使用linuxC實現的mysql數據庫備份
目標:通過alarm信號定時備份數據庫
備注:目前是第一個版,本身不能定時備份可以結合linux自動化實現定時備份。
運行平台:Linux或類unix
測試平台:ubuntu server 14.04 x64
文件信息:
main.c:數據庫備份程序
db_list:待備份的數據庫信息,一行一個文件。
不足:
文件的讀取方式感覺還不到位,使用的是fgetc一個個字符讀取然後過濾和組合來讀取相關的數據庫信息;開始使用的是fgets函數處理的時候,遇到了很多的麻煩,比如讀取到回車字符\r,讀取到換行字符\n,讀取到不可見字符等,後面信心大受傷所以改用了fgetc實現了。目前測試還是挺良好的,也歡迎大家提出更好的解決方案。(注:昨晚已經使用fscanf函數解決了這個問題,晚點會更新上來)
編譯和運行:
首先把要備份的數據庫名寫進db_list文件裡面一行一個數據庫,如
admin
book
然後編譯和運行
$gcc -o mian main.c
$./main
下面是main.c文件內容:
#include<sys/types.h> #include<sys/wait.h> #include<ctype.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<stdio.h> //待備份的數據表文件(一個數據庫一行) #define DB_FILE "./db_list" //最多可以備份的數據庫數量 #define NUM 20 //一個數據庫名字的最長字符數 #define LEN 128 //保存從DB_FILE中讀取到的數據庫 char *db_list[NUM]; //從DB_FILE文件中讀取到的數據庫數量 int read_num; //請求內存函數 void malloc_dblist(); //釋放內存函數 void free_dblist(); //讀取數據庫文件 void readDbFile(); int main(int argc, char *argv[]) { pid_t pid; int i; char buf[LEN]; //從文件讀取數據庫信息 readDbFile(); pid = fork(); if (pid < 0) { fprintf(stderr, "fork error\n"); exit(1); } switch (pid) { case -1: fprintf(stderr, "fork failed\n"); exit(1); case 0: //子進程進行數據庫的備份 for (i = 0; i < read_num; i++) { memset(buf, '\0', LEN); sprintf(buf, "%s%s%s%s%s", "mysqldump -uroot ", db_list[i], " > ", db_list[i], ".sql"); system(buf); printf("%d,%s\n", i, buf); } break; } //等待子進程的結束 if (pid > 0) { int stat_val; pid_t child_pid; child_pid = wait(&stat_val); if (!WIFEXITED(stat_val)) { fprintf(stdout, "Child terminated abnormaly\n"); } exit(1); } free_dblist(); 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]); } } void readDbFile() { FILE *fp; int i, j, c, isnewline; char *rs; char tmpbuf[LEN]; fp = fopen(DB_FILE, "r"); if (!fp) { fprintf(stderr, "%s not found\n", DB_FILE); } else { malloc_dblist(); read_num = 1; j = 0; isnewline = 0; while (!feof(fp)) { c = fgetc(fp); //空字符或者字符串結束字符 if (c == ' ' || c == '\0') { continue; } //回車字符 if (c == '\r') { continue; } //換行字符 if (c == '\n') { j = 0; isnewline = 1; continue; } //不可打印字符 if (!isprint(c)) { continue; } if (isnewline) { read_num++; isnewline = 0; } db_list[read_num-1][j] = c; j++; } fclose(fp); } }
下面是數據庫信息文件db_list:
admin book