后台进程(守护进程)自动备份PostgreSQL数据库

来源:互联网 发布:linux kvm命令 编辑:程序博客网 时间:2024/06/05 10:48

从当前目录中读取ini配置文件的登录数据库必要的参数,登录数据库后获取两次备份的间隔天数,然后启动一个线程隔1分钟检查一下是否需要备份。

之前查资料查了好久,才找到

"pg_dump \"host=%s port=%d user=%s password=%s dbname=%s\" > db_bak\\%s.bak"
这种可以避免输入密码,实现自动备份(不用配置环境变量或改动数据库的登录权限)

#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <process.h>#include "inc/libpq-fe.h"#include <time.h> #pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup")#pragma comment(lib, "lib/libpq.lib") #define DIRECTORY "db_bak"#define INIFILE "sysinfo.ini"#define CONNINFO "host=localhost port=5432 user=postgres password=123456 dbname=DB_SPS"#define QUERYSQL "select sys_val from tb_sysinfo where sys_key=\'backup_interval_time\'"#define SPACEUNIT (60*60*24)// BEGTIME:00 ~ ENDTIME:59#define BEGTIME 2#define ENDTIME 3typedef struct tagArgs{int t_space;char db_ip[16];char db_name[10];char db_user[10];char db_passwd[10];unsigned short db_port;}Args;unsigned int __stdcall ThreadCheckAndSave(void* arglist){struct tm tlasttime = {0}, tcurtime = {0};time_t lasttime = 0, curtime = 0;Args args = {0};char cmd[256] = {0}, strtime[256] = {0};if(arglist == NULL){printf("error for begin and space args !\n");_endthreadex(1);}memcpy(&args,arglist,sizeof(args));lasttime = time(NULL);do{curtime = time(NULL);if((difftime(curtime,lasttime)/SPACEUNIT) > args.t_space){localtime_s(&tcurtime,&curtime);if(tcurtime.tm_hour >= BEGTIME && tcurtime.tm_hour <= ENDTIME){//备份memset(cmd,0,sizeof(cmd));memset(strtime,0,sizeof(strtime));localtime_s(&tcurtime, &curtime);strftime(strtime,sizeof(strtime),"%Y-%m-%d(%H_%M_%S)",&tcurtime);CreateDirectoryA(DIRECTORY,NULL);sprintf(cmd,"pg_dump \"host=%s port=%d user=%s password=%s dbname=%s\" > db_bak\\%s.bak",args.db_ip,args.db_port,args.db_user,args.db_passwd,args.db_name,strtime);system(cmd);lasttime = curtime;}Sleep(60000);}}while(true);_endthreadex(0);return 0;}int main(int argc, const char* argv[]){PGconn* conn = NULL;PGresult* result = NULL;char* getstr = NULL;Args args = {0};HANDLE hthread = NULL;char inipath[MAX_PATH] = {0};char strsql[MAX_PATH] = {0};GetCurrentDirectoryA(sizeof(inipath),inipath);strcat(inipath,"\\");strcat(inipath,INIFILE);GetPrivateProfileStringA("db","#ip","127.0.0.1",args.db_ip,sizeof(args.db_ip),inipath);GetPrivateProfileStringA("db","#name","",args.db_name,sizeof(args.db_name),inipath);GetPrivateProfileStringA("db","#user","",args.db_user,sizeof(args.db_user),inipath);GetPrivateProfileStringA("db","#passwd","",args.db_passwd,sizeof(args.db_passwd),inipath);args.db_port = GetPrivateProfileIntA("db","#port",0,inipath);sprintf(strsql,"host=%s port=%d user=%s password=%s dbname=%s",args.db_ip,args.db_port,args.db_user,args.db_passwd,args.db_name);conn = PQconnectdb(strsql);if(PQstatus(conn) != CONNECTION_OK)goto END;result = PQexec(conn,QUERYSQL);if(PQresultStatus(result) != PGRES_TUPLES_OK)goto END;//获取配置参数getstr = PQgetvalue(result,0,0);if(getstr == NULL)goto END;args.t_space = atoi(getstr);//循环检查备份数据库hthread = (HANDLE)_beginthreadex(NULL,0,ThreadCheckAndSave,&args,CREATE_SUSPENDED,NULL);SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS);//SetThreadPriority(hthread,THREAD_PRIORITY_IDLE);ResumeThread(hthread);END:if(result != NULL){printf("PQexec : %s\n", PQerrorMessage(conn));PQclear(result);result = NULL;}if(conn != NULL){printf("PQconn : %s\n", PQerrorMessage(conn));PQfinish(conn);conn = NULL;}if(hthread != NULL)WaitForSingleObject(hthread,INFINITE);elsereturn -1;return 0;}


原创粉丝点击