linux c数据库备份第三版

这个版本相对第一版更新了很多,其实我本地定义为第五版的。相对第一版主要更新内容:
1.增加了定时器
2.用户可以停止调备份程序
3.如果备份程序正在运行,那么尝试运行提示已经在运行
4.记录程序运行时的pid信息
5.支持** start;** restart;** stop等命令
还有其他细节的更新。
不足:restart的支持还不是很完美,因为没有考虑到服务器繁忙等情况。

运行示例:
编译:
gcc -o main main.c
运行:
./main
重启
./main restart
关闭
./main stop

#include<sys/types.h>
#include<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 NUM 20
//数据库名字最长字符数
#define LEN 128
//闹钟时间间隔
#define ALARM_TIME 10

//数据库名数组信息
char *db_list[NUM];
//当前备份数据库的数量
int read_num;
//用户是否停止备份
int isbreak = 0;

//申请内容
void malloc_dblist();
//释放申请的内存
void free_dblist();
//读取数据库信息
void readDbFile();
//型号处理函数
void signHandler(int sig);
//记录程序运行的pid信息
int recordPid(int pid);
//获取程序运行时的pid信息
int readPid(void);
//移除程序运行时的pid信息
void delPid(void);

int main(int argc, char *argv[]) {
    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;
    }

    readDbFile();
    
    //注册信号处理
    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);
        
        for (i = 0; i < read_num; i++) {
            memset(buf, '\0', LEN);
            sprintf(buf, "mysqldump -uroot %s > %s_%02d%02d%02d.sql", 
                db_list[i], db_list[i], tm_ptr->tm_year+1900, tm_ptr->tm_mon+1, tm_ptr->tm_mday);
            system(buf);
            printf("%d,%s\n", i, buf);
        }
        
        alarm(ALARM_TIME);
        pause();
        
        if (isbreak) {
            fprintf(stderr, "User break progress.\n");
            break;
        }
    }
    
    free_dblist();
    
    delPid();
    
    exit(0);
    
}

void malloc_dblist()
{
    int i = 0;
    for (i = 0; i < NUM; i++) {
        db_list[i] = malloc(LEN);
        memset(db_list[i], '\0', LEN);
    }
}
void free_dblist()
{
    int i;
    for (i = 0; i < NUM; i++) {
        free(db_list[i]);
    }
}

void readDbFile()
{
    FILE *fp;
    
    fp = fopen(DB_FILE, "r");
    if (!fp) {
        fprintf(stderr, "%s not found\n", DB_FILE);
    }
    else {
        malloc_dblist();
        
        read_num = 0;
        while (fscanf(fp, "%127[^\r\n]\n", db_list[read_num]) == 1) {
            puts(db_list[read_num]);
            read_num++;
        }
        
        fclose(fp);    
    }
    
}

void signHandler(int sig)
{
    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);
    }
}

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);
}
main.c
mkbl
ck_book

 

posted @ 2015-07-23 20:51  齐泽西  阅读(366)  评论(0编辑  收藏  举报