MySQL定時備份(全量備份+增量備份)

增量備份的優(yōu)點是沒有重復數據,備份量不大,時間短衫嵌。但缺點也很明顯,需要建立在上次完全備份及完全備份之后所有的增量才能恢復彻秆。
MySQL沒有提供直接的增量備份方法,但是可以通過mysql二進制日志間接實現增量備份结闸。二進制日志對備份的意義如下:
二進制日志保存了所有更新或者可能更新數據的操作
二進制日志在啟動MySQL服務器后開始記錄唇兑,并在文件達到所設大小或者收到flush logs 命令后重新創(chuàng)建新的日志文件
只需定時執(zhí)行flush logs 方法重新創(chuàng)建新的日志,生成二進制文件序列桦锄,并及時把這些文件保存到一個安全的地方扎附,即完成了一個時間段的增量備份。

全量備份

mysqldump --lock-all-tables --flush-logs --master-data=2 -u root -p test > backup_sunday_1_PM.sql

參數 --lock-all-tables
對于InnoDB將替換為 --single-transaction结耀。
該選項在導出數據之前提交一個 BEGIN SQL語句留夜,BEGIN 不會阻塞任何應用程序且能保證導出時數據庫的一致性狀態(tài)。它只適用于事務表图甜,例如 InnoDB 和 BDB碍粥。本選項和 --lock-tables 選項是互斥的,因為 LOCK TABLES 會使任何掛起的事務隱含提交黑毅。要想導出大表的話嚼摩,應結合使用 --quick 選項。
參數 --flush-logs矿瘦,結束當前日志枕面,生成并使用新日志文件

參數 --master-data=2,該選項將會在輸出SQL中記錄下完全備份后新日志文件的名稱缚去,用于日后恢復時參考潮秘,例如輸出的備份SQL文件中含有:CHANGE MASTER TO MASTER_LOG_FILE='MySQL-bin.000002', MASTER_LOG_POS=106;

參數 test,該處的test表示數據庫test易结,如果想要將所有的數據庫備份枕荞,可以換成參數 --all-databases

參數 --databases 指定多個數據庫

參數 --quick或-q柜候,該選項在導出大表時很有用,它強制 MySQLdump 從服務器查詢取得記錄直接輸出而不是取得所有記錄后將它們緩存到內存中买猖。

參數 --ignore-table改橘,忽略某個數據表,如 --ignore-table test.user 忽略數據庫test里的user表
更多mysqldump 參數玉控,請參考網址

全量備份腳本shell

#!/bin/bash
# mysql 數據庫全量備份
 
# 用戶名飞主、密碼、數據庫名
username="root"
password="tencns152"
dbName="goodthing"
 
beginTime=`date +"%Y年%m月%d日 %H:%M:%S"`
# 備份目錄
bakDir=/home/mysql/backup
# 日志文件
logFile=/home/mysql/backup/bak.log
# 備份文件
nowDate=`date +%Y%m%d`
dumpFile="${dbName}_${nowDate}.sql"
gzDumpFile="${dbName}_${nowDate}.sql.tgz"
 
cd $bakDir
# 全量備份(對所有數據庫備份高诺,除了數據庫goodthing里的village表)
/usr/local/mysql/bin/mysqldump -u${username} -p${password} --quick --events --databases ${dbName} --ignore-table=goodthing.village --ignore-table=goodthing.area --flush-logs --delete-master-logs --single-transaction > $dumpFile
# 打包
/bin/tar -zvcf $gzDumpFile $dumpFile
/bin/rm $dumpFile
 
endTime=`date +"%Y年%m月%d日 %H:%M:%S"`
echo 開始:$beginTime 結束:$endTime $gzDumpFile succ >> $logFile
 
# 刪除所有增量備份
cd $bakDir/daily
/bin/rm -f *

這里全量備份只備份了一個數據庫碌识,因為如果所有數據庫都備份的話,文件太大了虱而。這里的取舍我也不是很清楚筏餐,畢竟自己還在學習階段,沒有實際的操作經驗牡拇。

增量備份

1. 檢查log_bin是否開啟

進入mysql命令行魁瞪,執(zhí)行 show variables like '%log_bin%'

mysql> show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | OFF   |
| log_bin_basename                |       |
| log_bin_index                   |       |
| log_bin_trust_function_creators | OFF   |
| log_bin_use_v1_row_events       | OFF   |
| sql_log_bin                     | ON    |
+---------------------------------+-------+
6 rows in set (0.01 sec)

如上所示,log_bin 未開啟惠呼;如果log_bin開啟导俘,則跳過第2步,直接進入第3步

2. 開啟 log_bin剔蹋,并重啟mysql

編輯 mysql 的配置文件 vim /etc/my.cnf旅薄,在 mysqld 下面添加下面2條配置

[mysqld]
log-bin=/var/lib/mysql/mysql-bin
server_id=152

Tip1: 一定要加 server_id,否則會報錯泣崩。至于server_id的值少梁,隨便設就可以。
Tip2: log_bin 中間可以下劃線_相連矫付,也可以-減號相連凯沪。同理server_id也一樣。
重啟mysql

service mysqld restart

再次在mysql命令行中執(zhí)行 show variables like '%log_bin%'

mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.01 sec)

3. 備份

進入mysql命令行技即,執(zhí)行 show master status;

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      430 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

當前正在記錄日志的文件名是 mysql-bin.000003
比如當前數據庫test的bk_user只有2條記錄

mysql> select * from test.bk_user;
+----+------+------+------+
| id | name | sex  | age  |
+----+------+------+------+
|  1 | 小明 | 男   |   25 |
|  2 | 小紅 | 女   |   21 |
+----+------+------+------+
2 rows in set (0.00 sec)

插入一條新的記錄

mysql> insert into test.bk_user(name, sex, age) values('小強', '男', 24);
Query OK, 1 row affected (0.02 sec)
mysql> select * from test.bk_user;
+----+------+-----+-----+
| id | name | sex | age |
+----+------+-----+-----+
|  1 | 小明 | 男  |  25 |
|  2 | 小紅 | 女  |  21 |
|  5 | 小強 | 男  |  24 |
+----+------+-----+-----+
3 rows in set (0.03 sec)

執(zhí)行命令mysqladmin -uroot -p密碼 flush-logs著洼,生成并使用新的日志文件
再次查看當前使用的日志文件,已經變?yōu)?mysql-bin.000004 了而叼。
mysql-bin.000003 則記錄著剛才執(zhí)行的 insert 語句的日志身笤。

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

到這里,其實已經完成了增量備份了葵陵。

恢復增量備份

首先假裝誤刪數據庫記錄

mysql> delete from test.bk_user where id=4;
Query OK, 1 row affected (0.01 sec)
 
mysql> select * from test.bk_user;
+----+------+------+------+
| id | name | sex  | age  |
+----+------+------+------+
|  1 | 小明 | 男   |   25 |
|  2 | 小紅 | 女   |   21 |
+----+------+------+------+
2 rows in set (0.00 sec)

從備份的日志文件mysql-bin.000003中恢復數據

[root@centos56 ~]# mysqlbinlog --no-defaults /var/lib/mysql/mysql-bin.000003 | mysql -uroot -p test
Enter password: 
ERROR 1032 (HY000) at line 36: Can't find record in 'bk_user'

如果你也遇到這個問題的話液荸,不妨修改 /etc/my.cnf 配置試試。
我在server_id那一行下添加了 slave_skip_errors=1032 脱篙,然后就執(zhí)行成功了娇钱,不再報錯伤柄。

mysql> select * from test.bk_user;
+----+------+------+------+
| id | name | sex  | age  |
+----+------+------+------+
|  1 | 小明 | 男   |   25 |
|  2 | 小紅 | 女   |   21 |
|  5 | 小強 | 男   |   24 |
+----+------+------+------+
3 rows in set (0.00 sec)

增量備份的shell腳本

#!/bin/bash
 
# 增量備份時復制mysql-bin.00000*的目標目錄,提前手動創(chuàng)建這個目錄
BakDir=/home/mysql/backup/daily
# 日志文件
LogFile=/home/mysql/backup/bak.log
 
# mysql的數據目錄
BinDir=/var/lib/mysql-bin
# mysql的index文件路徑文搂,放在數據目錄下的
BinFile=/var/lib/mysql-bin/mysql-bin.index
 
# 這個是用于產生新的mysql-bin.00000*文件
/usr/local/mysql/bin/mysqladmin -uroot -ptencns152 flush-logs
 
Counter=`wc -l $BinFile | awk '{print $1}'`
NextNum=0
# 這個for循環(huán)用于比對$Counter,$NextNum這兩個值來確定文件是不是存在或最新的
for file in `cat $BinFile`
do
        base=`basename $file`
        NextNum=`expr $NextNum + 1`
        if [ $NextNum -eq $Counter ]
        then
                echo $base skip! >> $LogFile
        else
                dest=$BakDir/$base
                #test -e用于檢測目標文件是否存在适刀,存在就寫exist!到$LogFile去
                if(test -e $dest)
                then
                        echo $base exist! >> $LogFile
                else
                        cp $BinDir/$base $BakDir
                        echo $base copying >> $LogFile
                fi
        fi
done
 
echo `date +"%Y年%m月%d日 %H:%M:%S"` $Next Bakup succ! >> $LogFile

定時備份

執(zhí)行命令 crontab -e,添加如下配置

# 每個星期日凌晨3:00執(zhí)行完全備份腳本
0 3 * * 0 /bin/bash -x /root/bash/Mysql-FullyBak.sh >/dev/null 2>&1
 
# 周一到周六凌晨3:00做增量備份
0 3 * * 1-6 /bin/bash -x /root/bash/Mysql-DailyBak.sh >/dev/null 2>&1

遇到的問題

Can't connect to local MySQL server through socket '/tmp/mysql.sock'

mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)'
Check that mysqld is running and that the socket: '/tmp/mysql.sock' exists

去修改mysql的配置文件煤蹭,添加

[mysqladmin]
# 修改為相應的sock
socket=/var/lib/mysql/mysql.sock

執(zhí)行mysqldump時遇到 Unknown table 'column_statistics' in information_schema (1109)

[root@centos56 bash]# /usr/local/mysql/bin/mysqldump -uroot -ptencns152 --quick --events --all-databases --flush-logs --delete-master-logs --single-transaction > /home/mysql/backup/1.sql  
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: Couldn't execute 'SELECT COLUMN_NAME,                       JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"')                FROM information_schema.COLUMN_STATISTICS                WHERE SCHEMA_NAME = 'atd' AND TABLE_NAME = 'box_info';': Unknown table 'column_statistics' in information_schema (1109)

如果使用MySQL 8.0+版本提供的命令行工具mysqldump來導出低于8.0版本的MySQL數據庫到SQL文件笔喉,會出現Unknown table 'column_statistics' in information_schema的錯誤,因為早期版本的MySQL數據庫的information_schema數據庫中沒有名為COLUMN_STATISTICS的數據表硝皂。
解決問題的方法是常挚,使用8.0以前版本MySQL附帶的mysqldump工具,最好使用待備份的MySQL服務器版本對應版本號的mysqldump工具稽物,mysqldump可以獨立運行奄毡,并不依賴完整的MySQL安裝包,比如在Windows中贝或,可以直接從MySQL安裝目錄的bin目錄中將mysqldump.exe復制到其他文件夾吼过,甚至從一臺電腦復制到另一臺電腦,然后在CMD窗口中運行咪奖。
當前使用是的MySQL 5.7.22那先。把5.7.20的 MYSQL_HOME/bin/mysqldump 替換掉 5.7.22的,接著就能順利執(zhí)行mysqldump了赡艰,也真是奇了怪了。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末斤葱,一起剝皮案震驚了整個濱河市慷垮,隨后出現的幾起案子,更是在濱河造成了極大的恐慌揍堕,老刑警劉巖料身,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異衩茸,居然都是意外死亡芹血,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門楞慈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幔烛,“玉大人,你說我怎么就攤上這事囊蓝《鲂” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵聚霜,是天一觀的道長狡恬。 經常有香客問我珠叔,道長,這世上最難降的妖魔是什么弟劲? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任祷安,我火速辦了婚禮,結果婚禮上兔乞,老公的妹妹穿的比我還像新娘汇鞭。我一直安慰自己,他們只是感情好报嵌,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布虱咧。 她就那樣靜靜地躺著,像睡著了一般锚国。 火紅的嫁衣襯著肌膚如雪腕巡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天血筑,我揣著相機與錄音绘沉,去河邊找鬼。 笑死豺总,一個胖子當著我的面吹牛车伞,可吹牛的內容都是我干的。 我是一名探鬼主播喻喳,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼另玖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了表伦?” 一聲冷哼從身側響起谦去,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蹦哼,沒想到半個月后鳄哭,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡纲熏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年妆丘,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片局劲。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡勺拣,死狀恐怖,靈堂內的尸體忽然破棺而出鱼填,到底是詐尸還是另有隱情宣脉,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布剔氏,位于F島的核電站塑猖,受9級特大地震影響竹祷,放射性物質發(fā)生泄漏。R本人自食惡果不足惜羊苟,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一塑陵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蜡励,春花似錦令花、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稽寒,卻和暖如春扮碧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杏糙。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工慎王, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宏侍。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓赖淤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谅河。 傳聞我的和親對象是個殘疾皇子咱旱,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內容