Mysql按需備份數據mysql
經過在my.cnf配置bin-log,實現操做日誌的記錄,並配合mysqldump的全備份來實現全備和按需恢復數據的數據備份方案。
再以實例來講明方案的實現。
本文章實現單機備份方案,主從備份,後續再補充。
實施環境說明:
--centos:6.5
--mysql5.7.12
注:本文以linux系統下的方案,windows系統可做爲參考。linux
##1. 建立備份文件夾sql
按需建立本身的備份文件夾,本方案建立兩個文件夾,一個放全備,一個放bin-log日誌 全備:/home/databackup/backups 日誌:/home/databackup/bin-log
GRANT SELECT,SHOW DATABASES,SHOW VIEW,LOCK TABLES,TRIGGER,RELOAD,REPLICATION CLIENT ON *.* TO 'dumper'@'127.0.0.1' IDENTIFIED BY 'password' WITH GRANT OPTION;FLUSH PRIVILEGES;
受權後續說明數據庫
按以下配置my.cnf以後,重啓service mysql restart, 在/home/databackup/bin-log文件夾下,會生成msyql-bin.index和mysql-bin.000001。windows
#database backup explicit_defaults_for_timestamp = 1 # server-id = 1 ## binlog存放路徑 log-bin=/home/databackup/bin-log/mysql-bin.log ## binlog記錄的格式,有row、statement、mixed三種選項 binlog-format = row ## binlog寫緩衝區設置大小,因爲是內存,寫速度很是快,能夠有效提升binlog的寫效率,若是數據庫>中常常出現大事務,能夠酌情提升該參數。 binlog_cache_size = 32m ## 最大緩存區大小 max_binlog_cache_size = 512m ## binlog文件最大的大小 max_binlog_size = 1000m ## 二進制日誌自動刪除的天數。默認值爲0,表示「沒有自動刪除」 expire_logs_days = 60 ## 須要備份的數據庫名,若是備份多個數據庫,重複設置這個選項便可 binlog-do-db = databaseName1 binlog-do-db = databaseName2 ...... ## 不須要備份的數據庫,若是備份多個數據庫,重複設置這個選項便可 binlog-ignore-db = databaseName1 binlog-ignore-db = databaseName2 ......
建立備份腳本,文件名爲mysql-databackup.sh,內容以下:centos
## !/bin/ash ## mysql-databackup.sh # Database info B_USER="dumper" DB_PASS="Dum#Per2017!" DB_HOST="127.0.0.1" # Database array DB_NAME=("power_organization") # Others vars BIN_DIR="/home/databackup/bin-log" #the mysql bin path BCK_DIR="/home/databackup/backups" #the backup file directory DATE=`date +%F` # create file mkdir $BCK_DIR/$DATE # TODO # /usr/bin/mysqldump --opt -ubatsing -pbatsingpw -hlocalhost timepusher > /mnt/mysqlBackup/db_`date +%F`.sql for var in ${DB_NAME[@]}; do mysqldump --opt -uuser -ppassword -h$DB_HOST --single-transaction --flush-logs --master-data=2 $var | gzip > $BCK_DIR/$DATE/$var.sql.gz done # 刪除10天以前的備份文件 find /home/databackup/backups -mtime +10 -name "*.*" -exec rm -Rf {} \;
crontab -e內容緩存
0 3 * * * /home/databackup/mysql-databackup.sh
建立實例數據庫test,並隨意插入幾條數據。並 登陸mysql執行flush logs,生成新日誌mysql-bin.000002編碼
msyql>flush log;
mysql> show variables like '%log_bin%';
首先對test數據庫作一個完整備份:rest
$ mysqldump -hlocalhost -uuser -ppassword --flush-logs -P3306 --master-data=2 --single-transaction --opt test > test_bak_full.sql
這時候就會獲得一個全備文件test.sql日誌
a. 在test庫的某個表插入一些數據,而後執行flush logs命令。這時將會產生一個新的二進制日誌文件mysql-bin.000004,mysql-bin.000004則保存了全備事後的全部更改,既增長記錄的操做也保存在了mysql-bin.00004中。
b. 再在test庫中的t_user表中增長兩條記錄,而後誤刪除t_user任意記錄。t_user中增長記錄的操做和刪除表的操做都記錄在mysql-bin.000005中。
$ mysqldump -hlocalhost -uuser -ppassword --flush-logs -P3306 --master-data=2 --single-transaction --opt test > test_bak_full2.sql
mysql > set sql_log_bin=0;
首先導入全備數據
$ mysql -hlocalhost -uuser -ppassword < test_bak_full2.sql
此時數據庫恢復到刪除前的數據,test數據庫恢復
查看當前所在二進制日誌中的位置:
mysql> show master status;
會顯示最新的日誌記錄mysql-bin.000007
mysql> show binlog events in 'mysql-bin.000007';
根據上面命令的記錄能夠查看固然日誌的位置position。
恢復數據
也能夠經過命令mysqlbinlog查看日誌明細,能大概肯定須要完整恢復哪幾個binlog文件。
若是知道誤操做的命令如DROP TABLE,則能夠經過下面的方法在binlog文件中找到誤操做以前的那個或那位置段/時間段。
position: (以下面的信息顯示,誤操做DROP TABLE以前的pos是775,在datetime 141204 15:08:04或pos 882時完成DROP TABLE操做) $ mysqlbinlog /var/lib/mysql/mysql-bin.000003 |grep -C 5 'DROP TABLE' #141204 15:07:05 server id 1 end_log_pos 775 Xid = 376 COMMIT/*!*/; # at 775 #141204 15:08:04 server id 1 end_log_pos 882 Query thread_id=10 exec_time=0 error_code=0 SET TIMESTAMP=1417676884/*!*/; DROP TABLE `t_user` /* generated by server */ /*!*/; # at 882
根據記錄,可選擇mysql-bin.000005進行恢復,使用mysqlbinlog來查看恢復到什麼位置。
這個日誌中包括了新增記錄和誤刪表兩個部分,咱們須要恢復到新增記錄以後、誤刪操做之前的位置。
如下是恢復命令:
msyqlbinlog mysql-bin.000005 --start-position --stop-position | msyql -hlocalhost -uuser -ppassword
或
mysqlbinlog mysql-bin.000005 --start-datetime=775 --stop-datetime | mysql -h localhost -uroot -p
或
mysqlbinlog mysql-bin.000005 --start-datetime=775 --stop-datetime | restore.sql
而後執行restore.sql來恢復數據
注:在待恢復的position或時間點之前、全備之後的binlog須要所有恢復,多個文件以空格隔開
mysql > set sql_log_bin=1;
unknown variable 'default-character-set=utf8'
在使用mysqlbinlog查看二進制日誌的時候,提示下面的錯誤:
/usr/local/mysql/bin/mysqlbinlog: unknown variable 'default-character-set=utf8'
緣由是在爲了統一mysql客戶端到服務端的的字符編碼,在/etc/my.cnf文件的[client]、[mysqld]等節加入了default-character-set = utf8,mysqlbinlog會從my.cnf中的[client]讀取配置,但奈何mysqlbinlog並不認識這個選項(聽說是個bug)致使的。
應對這個bug的方法有兩個:第一,天然是註釋到[client]中的這個字符集配置;第二,改用loose-default-character-set = utf8。在選項前加了loose-,表示當程序不認識此選項時會略過此選項,並給出一個警告。