使用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