后台进程(守护进程)自动备份PostgreSQL数据库
时间:2022-05-03
本文章向大家介绍后台进程(守护进程)自动备份PostgreSQL数据库,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
从当前目录中读取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 3
typedef 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 : %sn", PQerrorMessage(conn));
PQclear(result);
result = NULL;
}
if(conn != NULL)
{
printf("PQconn : %sn", PQerrorMessage(conn));
PQfinish(conn);
conn = NULL;
}
if(hthread != NULL)
WaitForSingleObject(hthread,INFINITE);
else
return -1;
return 0;
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 蓝桥杯 试题 基础练习 FJ的字符串
- 蓝桥杯 试题 基础练习 龟兔赛跑预测
- 问题 1432: [蓝桥杯][2013年第四届真题]剪格子
- 问题 1426: [蓝桥杯][历届试题]九宫重排
- mock测试及jacoco覆盖率
- HDU 1495 非常可乐 最简单的的解决方案
- Performing Push Install adb: error: failed to get feature set: more than one 解决方案
- Shell Style Guide
- 10分钟搞定OAuth2.0授权服务
- IP 地址大解密
- 曾经,我以为我很懂MySQL索引
- AES加解密工具类AESUtil记录
- iOS逆向之使用unc0ver越狱 iOS13.5
- Spring @Autowired npe example:Why your Spring @Autowired component is null
- Spring JPA 查询创建