linux下c实现的数据库备份(第四版)
时间:2021-07-01 10:21:17
帮助过:5人阅读
<sys/wait.h>
#include<ctype.h>
#include<unistd.h>
#include<
string.h>
#include<stdlib.h>
#include<signal.h>
#include<time.h>
#include<stdio.h>
//程序运行的pid信息
#define PID_FILE "./pid.db"
//记录待备份的数据库信息文件
#define DB_FILE "./db_list"
//配置文件信息
#define CONF_FILE "./conf"
//日志文件
#define LOG_FILE "./log"
//最大备份的数据库数量
#define NUM 20
//数据库名字长度的限制
#define LEN 128
//程序轮询时间间隔
#define ALARM_TIME 10
//从文件读取到的数据库信息保存至该数组中
char *
db_list[NUM];
//当前待备份的数据库数量
int read_num;
//是否用户终止备份
int isbreak =
0;
//数据库连接信息
typedef
struct db_conf {
char *
host;
char *
user;
char *
pass;
}CONF;
//数据库备份时间
typedef
struct bat_t {
int hour;
int min;
}BAT_T;
//malloc
void malloc_dblist();
//free
void free_dblist();
//读取待备份的数据库信息
int readDbFile();
//读取配置文件信息(数据库连接信息,备份时间等)
CONF readConfFile();
//读取备份的时间信息
BAT_T readBatTFile();
//记录日志信息
void recordLog(
char *
);
//信号处理函数
void signHandler(
int sig);
//记录程序运行的pid信息
int recordPid(
int pid);
//获取程序运行时的pid信息
int readPid(
void);
//移除程序运行时的pid信息
void delPid(
void);
int main(
int argc,
char *
argv[])
{
CONF conf;
BAT_T bt;
pid_t pid, old_pid;
int i, prs;
char buf[LEN];
time_t t;
struct tm *
tm_ptr;
struct sigaction act, oldact;
sigset_t newmask, suspmask, oldmask;
if (argc >=
2) {
old_pid =
(pid_t)readPid();
//停止掉备份程序
if (strcmp(argv[
1],
"stop") ==
0) {
kill(old_pid, SIGINT);
return 0;
}
else if (strcmp(argv[
1],
"restart") ==
0) {
kill(old_pid, SIGINT);
sleep(5);
}
}
old_pid =
(pid_t)readPid();
//检测程序是否已经在运行
if (old_pid >
0) {
fprintf(stderr, "Progress is running.\n");
return -
1;
}
//记录程序运行的pid信息
prs = recordPid((
int)getpid());
if (prs == -
1) {
fprintf(stderr, "Open pid.db file error.\n");
return -
1;
}
//读取待备份的数据库
int rs =
readDbFile();
if (rs) {
delPid();
return rs;
}
//读取数据配置信息
conf =
readConfFile();
//读取备份时间
bt =
readBatTFile();
//信号接管
act.sa_handler =
signHandler;
sigemptyset(&
act.sa_mask);
act.sa_flags =
0;
sigaction(SIGALRM, &act,
0);
sigaction(SIGINT, &act,
0);
while (
1) {
time(&
t);
tm_ptr = localtime(&
t);
//备份时间内进行备份
if (bt.hour == (
int)tm_ptr->tm_hour && bt.min == (
int)tm_ptr->
tm_min) {
for (i =
0; i < read_num; i++
) {
memset(buf, ‘\0‘, LEN);
//密码为空
if (!
strlen(conf.pass)) {
sprintf(buf, "mysqldump -h%s -u%s %s > %s_%02d%02d%02d.sql",
conf.host, conf.user, db_list[i], db_list[i],
tm_ptr->tm_year+
1900, tm_ptr->tm_mon+
1, tm_ptr->
tm_mday);
}
else {
sprintf(buf, "mysqldump -h%s -u%s -p%s %s > %s_%02d%02d%02d.sql",
conf.host, conf.user, conf.pass, db_list[i], db_list[i],
tm_ptr->tm_year+
1900, tm_ptr->tm_mon+
1, tm_ptr->
tm_mday);
}
system(buf);
}
}
alarm(ALARM_TIME);
pause();
if (isbreak) {
recordLog("User break progress.");
break;
}
}
free_dblist();
delPid();
exit(0);
}
void malloc_dblist()
{
int i =
0;
//malloc for db_list
for (i =
0; i < NUM; i++
) {
db_list[i] =
malloc(LEN);
memset(db_list[i], ‘\0‘, LEN);
}
}
void free_dblist()
{
int i;
//free db_list‘s memory
for (i =
0; i < NUM; i++
) {
free(db_list[i]);
}
}
int readDbFile()
{
FILE *
fp;
fp = fopen(DB_FILE,
"r");
if (!
fp) {
char buf[
128];
sprintf(buf, "%s not found\n", DB_FILE);
recordLog(buf);
fprintf(stderr, "%s not found\n", DB_FILE);
return 1;
}
else {
malloc_dblist();
read_num =
0;
while (fscanf(fp,
"%127[^\r\n]\n", db_list[read_num]) ==
1) {
read_num++
;
}
fclose(fp);
return 0;
}
}
CONF readConfFile()
{
FILE *
fp;
CONF conf;
if (!(fp = fopen(CONF_FILE,
"r"))) {
conf.host =
"localhost";
conf.user =
"root";
conf.pass =
"";
return conf;
}
char buf[
128];
while ((fscanf(fp,
"%127[^\r\n]\n", buf)) ==
1) {
char *tmp1 = strtok(buf,
"=");
char *tmp2 = strtok(NULL,
"=");
if (strstr(tmp1,
"HOST")) {
if (tmp2) {
conf.host =
strdup(tmp2);
}
else {
conf.host =
"localhost";
}
}
else if (strstr(tmp1,
"USER")) {
if (tmp2) {
conf.user =
strdup(tmp2);
}
else {
conf.host =
"root";
}
}
else if (strstr(tmp1,
"PASS")) {
if (tmp2) {
conf.pass =
strdup(tmp2);
}
else {
conf.pass =
"";
}
}
}
return conf;
}
BAT_T readBatTFile()
{
FILE *
fp;
BAT_T bat_time;
if (!(fp = fopen(CONF_FILE,
"r"))) {
bat_time.hour =
02;
bat_time.min =
00;
return bat_time;
}
char buf[
128];
while ((fscanf(fp,
"%127[^\r\n]\n", buf)) ==
1) {
if (!strstr(buf,
"BAT_TIME"))
continue;
//获取到备份数据数据
char *tmp1 = strtok(buf,
"=");
char *tmp2 = strtok(NULL,
"=");
//对备份时间数据进行分割
char *hour = strtok(tmp2,
" ");
char *min = strtok(NULL,
" ");
if (hour) {
bat_time.hour =
atoi(hour);
}
else {
bat_time.hour =
02;
}
if (min) {
bat_time.min =
atoi(min);
}
else {
bat_time.min =
02;
}
}
return bat_time;
}
void recordLog(
char *
msg)
{
FILE *
fp;
fp = fopen(LOG_FILE,
"a");
if (fp) {
time_t t;
struct tm *
tm_ptr;
time(&
t);
tm_ptr = localtime(&
t);
fprintf(fp, "%d-%d-%d %d:%d:%d: %s\n", (tm_ptr->tm_year+
1900), tm_ptr->tm_mon, tm_ptr->
tm_mday,
tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->
tm_sec, msg);
fclose(fp);
}
}
void signHandler(
int sig)
{
char buf[
128];
switch (sig) {
case SIGALRM:
//fprintf(stdout, "alarm signal comming:%d.\n", sig);
break;
case SIGINT:
//fprintf(stdout, "sigint signal comming:%d.\n", sig);
isbreak =
1;
break;
default:
//fprintf(stdout, "uncatched signal comming:%d.\n", sig);
sprintf(buf,
"uncatched signal comming:%d.\n", sig);
recordLog(buf);
}
}
int recordPid(
int pid)
{
FILE *fp =
NULL;
if (!(fp = fopen(PID_FILE,
"w")))
return -
1;
pid =
getpid();
fprintf(fp, "%d", (
int)pid);
fclose(fp);
return 0;
}
int readPid(
void)
{
FILE *fp =
NULL;
if (!(fp = fopen(PID_FILE,
"r")))
return -
1;
int pid;
if (fscanf(fp,
"%d", &pid) !=
1) {
fclose(fp);
return -
2;
}
fclose(fp);
return pid;
}
void delPid(
void)
{
unlink(PID_FILE);
}
mian.c
conf
#数据库服务器地址
HOST=localhost
#数据库账号
USER=root
#数据库密码
PASS=
#备份时间 :小时 分钟
BAT_TIME=17 25
db_list
mkbl
ck_book
linux下c实现的数据库备份(第四版)
标签: