• linux c数据库备份第四版


    该版本算是比较成熟的啦,欢迎大伙拿来试用!!!
    1.新增数据库连接和备份时间配置文件conf
    2.新增日志文件,程序运行的一些异常会记录在log文件下

    后续的工作:
    1.将代码切割为多个文件,分类存放代码
    2.加入自动后台运行的支持
    3.加入开机自动运行的支持
    完成上面3个之后,我的linux c数据库备份程序就暂时靠一段落了。

    使用提醒:
    编译:gcc -o main main.c
    后台启动:./main &
    停止程序:./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 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.
    ");
            return -1;
        }
        
        //记录程序运行的pid信息
        prs = recordPid((int)getpid());
        if (prs == -1) {
            fprintf(stderr, "Open pid.db file error.
    ");
            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, '', 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], '', 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
    ", DB_FILE);
            recordLog(buf);
            fprintf(stderr, "%s not found
    ", DB_FILE);
            return 1;
        }
        else {
            malloc_dblist();
            
            read_num = 0;
            while (fscanf(fp, "%127[^
    ]
    ", 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[^
    ]
    ", 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[^
    ]
    ", 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
    ", (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.
    ", sig);
                break;
            case SIGINT:
                //fprintf(stdout, "sigint signal comming:%d.
    ", sig);
                isbreak = 1;
                break;
            default:
                //fprintf(stdout, "uncatched signal comming:%d.
    ", sig);
                sprintf(buf, "uncatched signal comming:%d.
    ", 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
  • 相关阅读:
    epoll源码实现分析[整理]
    linux几种时间函数总结
    linux几种定时函数的使用
    linux下redis数据库的简单使用
    网络编程之非阻塞connect编写
    网络编程之select
    数码相框(LCD、I2C)
    centos tftp和samba的安装与配置
    libevent库简单使用
    c语言随机数
  • 原文地址:https://www.cnblogs.com/qizexi/p/4676290.html
Copyright © 2020-2023  润新知