本文使用的數據庫軟件版本爲:
mariadb-10.0.13.tar.gz
mysqldump備份軟件版本爲:
# mysqldump --version mysqldump Ver 10.15 Distrib 10.0.13-MariaDB, for Linux (x86_64)
一.mysqldump簡介
mysqldump客戶端可用來轉儲數據庫或蒐集數據庫進行備份或將數據轉移到另一個SQL服務器(不一定是一個MySQL服務器)。轉儲包含創建表和/或裝載表的SQL語句。
如果你在服務器上進行備份,並且表均爲MyISAM表,應考慮使用mysqlhotcopy,因爲可以更快地進行備份和恢復。
支持完整/全備份:備份指定數據集中的所有數據
二.mysqldump命令語法格式:
備份單個庫或單個庫中的指定表或多個表:
mysqldump [OPTIONS] database [tables]
備份一個或多個庫:
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
備份所有庫:
mysqldump [OPTIONS] --all-databases [OPTIONS]
如果沒有指定任何表或使用了---database或--all--database選項,則轉儲整個數據庫。
要想獲得你的版本的mysqldump支持的選項,執行mysqldump --help。
如果運行mysqldump沒有--quick或--opt選項,mysqldump在轉儲結果前將整個結果集裝入內存。
如果轉儲大數據庫可能會出現問題。該選項默認啓用,但可以用--skip-opt禁用。
如果使用最新版本的mysqldump程序生成一個轉儲重裝到很舊版本的MySQL服務器中,不應使用--opt或-e選項。
三.mysqldump常用命令選項:
注意:生產環境中二進制日誌文件和數據文件不應該放置在同一磁盤或存儲;
四.實際案例演示
1.完全備份的實現
# mysqldump -A -uroot -hlocalhost -p /tmp/all1.sql
到備份目錄查看:
[root@node1 tmp]# du -sh all1.sql 524K all1.sql
備份完成後可以將備份文件壓縮;
[root@node1 tmp]# xz all1.sql [root@node1 tmp]# ls all1.sql.xz ks-script-t3nzeD ks-script-t3nzeD.log mysql.sock yum.log [root@node1 tmp]# du -sh all1.sql.xz 108K all1.sql.xz
我們將用戶名和密碼寫入my.cnf配置文件,實現mysqldump命令輸入時不用輸入用戶名和密碼及主機名:
[root@node1 ~]# vim .my.cnf [client] user=root host=localhost password=oracle [mysqldump] user=root host=localhost password=oracle
2.MyISAM引擎的溫備的實現
我們備份時需要鎖定所有表,
-x, --lock-all-tables
也可以備份那張表就鎖定那張表:
-l, --lock-tables
可能造成時間點不一致,如備份一張表的時候鎖定了表,備份後跟其他表的時間點就不一致了,那麼數據就會不一致;
我們生產環境中就使用鎖定所有表的選項;除非是隻備份單張表;
實例:溫備實現對指定數據庫的備份;
[root@node1 ~]# mysqldump -B mysql--lock-all-tables > /tmp/warmbackup.sql [root@node1 ~]# ls -lh /tmp total 128K -rw-r--r-- 1 root root 105K Jan 22 15:52 all1.sql.xz srwxrwxrwx 1 mysql mysql 0 Jan 22 00:22 mysql.sock -rw-r--r-- 1 root root 10K Jan 22 16:20 warmbackup.sql
備份單個數據庫時參數-B的有無是有區別的:
#mysqldump -B mysql --lock-all-tables 會自動添加create database語句進行,備份的數據庫我們將來恢復時會自動創建空庫; #mysqldump mysql --lock-all-tables 不會自動添加create database語句,備份的數據庫我們將來進行恢復時需要手動創建空庫;
3.InnoDB引擎的熱備的實現:
先啓動一個大的單一事物來備份,InnoDB支持MVCC多版本併發控制,在備份之前申請啓動一個事物,那麼其它用戶無論怎麼更改數據,此事物中的數據都不會更改的,通過此事物看見的數據是一致的。
而對於非InnoDB存儲引擎,指定如下選項無更多意義,
--single-transaction
對於混合存儲引擎可能不會實現熱備;
所有數據庫的存儲引擎都是InnoDB就能實現熱備;
如果我們只需要備份單個數據庫,且數據庫的存儲引擎是InnoDB,那麼熱備就能實現;
如果備份指定數據庫就使用如下指令:
-B, --databases
實例:熱備實現對InnoDB存儲引擎的數據庫備份;
[root@node1 ~]# mysqldump -B hellodb --single-transaction > /tmp/hotbackup.sql
4.mysqldump全量備份+mysqlbinlog二進制日誌增量備份的實現
創建備份文件夾:
[root@node1 ~]# mkdir /backup
實現對指定數據庫hellodb的完全備份:
[root@node1 ~]# mysqldump -B hellodb --lock-all-tables --master-data=2 > /backup/hellodb-`date +%F`.sql [root@node1 ~]# ls /backup/ hellodb-2015-01-22.sql
爲了實現增量備份,我們連入mysql,做一些更改操作;
[root@node1 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 16 Server version: 10.0.13-MariaDB-log Source distribution Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> show tables; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | myisam_table | | scores | | students | | teachers | | toc | | v1 | +-------------------+ 9 rows in set (0.00 sec) MariaDB [hellodb]> create table tb1 (id int); Query OK, 0 rows affected (0.14 sec) MariaDB [hellodb]> insert into tb1 values (1),(2),(22); Query OK, 3 rows affected (0.12 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [hellodb]> \q Bye
增量備份備份的開始位置如下:
[root@node1 ~]# vim /backup/hellodb-2015-01-22.sql -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=518;
如圖中:位置是518,
那麼增量備份就是備份從518開始到結束的位置中間的內容;
我們需要連接數據庫執行FLUSH TABLES READ LOCK; 或者我們在這裏執行FLUSH LOGS;即可;
[root@node1 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 17 Server version: 10.0.13-MariaDB-log Source distribution Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> flush logs; Query OK, 0 rows affected (0.06 sec) MariaDB [(none)]> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 20181 | | mysql-bin.000002 | 2185 | | mysql-bin.000003 | 1098 | | mysql-bin.000004 | 1311 | | mysql-bin.000005 | 345 | | mysql-bin.000006 | 856 | | mysql-bin.000007 | 365 | +------------------+-----------+ 7 rows in set (0.00 sec) MariaDB [(none)]> \q Bye
或者我們增量備份根據時間範圍來備份:
[root@node1 ~]# mysqlbinlog --start-datetim '2015-01-22 16:20:00' --stop-datetime '2015-01-22 16:43:00' /mydata/data/mysql-bin.* > /backup/increment-`date +%F`.sql
第一次增量備份就實現了。
假如我們再次更改了數據庫,並且不小心刪除了hellodb數據庫,我們如何恢復數據庫?
此時,二進制日誌就至關重要了,我們之前備份的二進制日誌是剛纔插入的那條數據未備份,是增量備份到刪除數據庫之間的那段時間的內容未備份;我們可以導出這個階段的二進制日誌,但是需要過濾掉刪除數據庫這條指令;不然你恢復所有數據庫後它還會將數據庫hellodb刪除;
我們將二進制日誌文件備份到臨時目錄中:
我們先查看二進制日誌文件中drop語句執行的時間點:
[root@node1 ~]# mysqlbinlog /mydata/data/mysql-bin.000007 略… # at 564 #150122 16:58:26 server id 1 end_log_pos 651 Query thread_id=18 exec_time=0 error_code=0 SET TIMESTAMP=1421917106/*!*/; drop database hellodb /*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
我們知道了drop刪除數據庫指令的語句在564這個時間點,我們可以使用--stop-position=564只備份到時間點564之前的二進制日誌:
[root@node1 ~]# mysqlbinlog --stop-position=564 /mydata/data/mysql-bin.000007 > /tmp/a.sql
備份至此就完成了,下面就是還原恢復數據庫至刪除數據庫前狀態的過程了。
還原完全備份:
[root@node1 ~]# mysql < /backup/hellodb-2015-01-22.sql
現在登錄數據庫查看,我們創建的表tb1是不存在的;
[root@node1 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 20 Server version: 10.0.13-MariaDB-log Source distribution Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> show tables; +-------------------+ | Tables_in_hellodb | +-------------------+ | classes | | coc | | courses | | myisam_table | | scores | | students | | teachers | | toc | | v1 | +-------------------+ 9 rows in set (0.00 sec) MariaDB [hellodb]> \q Bye
恢復增量備份內容:
[root@node1 ~]# mysql < /backup/increment-2015-01-22.sql
現在我們創建的表tb1存在了,但是數據還是不全,丟失了我們插入的那條數據;
[root@node1 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 22 Server version: 10.0.13-MariaDB-log Source distribution Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> select * from tb1; +------+ | id | +------+ | 1 | | 2 | | 22 | +------+ 3 rows in set (0.00 sec) MariaDB [hellodb]> \q Bye
進行時間點還原,恢復從增量備份至刪除數據庫之前這段時間內的數據:
[root@node1 ~]# mysql < /tmp/a.sql
恢復完成後我們查看數據庫,我們插入的數據恢復了:
[root@node1 ~]# mysql Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 24 Server version: 10.0.13-MariaDB-log Source distribution Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use hellodb; Database changed MariaDB [hellodb]> select * from tb1; +------+ | id | +------+ | 1 | | 2 | | 22 | | 9 | | 20 | +------+ 5 rows in set (0.00 sec) MariaDB [hellodb]> \q Bye
五.如何使用shell腳本實現mysql全量,增量備份。
增量備份在週一-週六凌晨3點,會複製mysql-bin.00000*到指定目錄;
而全量備份則使用mysqldump將所有的數據庫導出,每週日凌晨3點執,並會刪除上週留下的mysq-bin.00000*。然後對mysql的備份操作會保留在bak.log文件中。
實現腳本創建:
1.編寫全量備份腳本
[root@node1 ~]# vim DBfullybak.sh #!/bin/bash # Program # use mysqldump to Fully backup mysql data per week! # History # 2015-01-22 guo # Path BakDir=/backup LogFile=/backup/bak.log Date=`date +%Y%m%d` Begin=`date +"%Y年%m月%d日 %H:%M:%S"` cd $BakDir DumpFile=$Date.sql GZDumpFile=$Date.sql.tgz /usr/local/mysql/bin/mysqldump -uroot -poracle --quick --all-databases --flush-logs --delete-master-logs --single-transaction > $DumpFile /bin/tar czvf $GZDumpFile $DumpFile /bin/rm $DumpFile Last=`date +"%Y年%m月%d日 %H:%M:%S"` echo 開始:$Begin 結束:$Last $GZDumpFile succ >> $LogFile cd $BakDir/daily rm -rf *
2.編寫增量備份腳本
[root@node1 ~]# vim DBdailybak.sh #!/bin/bash # Program # use cp to backup mysql data everyday! # History #2015-01-22 guo # Path BakDir=/backup/daily BinDir=/mydata/data LogFile=/backup/bak.log BinFile=/mydata/data/mysql-bin.index /usr/local/mysql/bin/mysqladmin -uroot -poracle flush-logs #這個是用於產生新的mysql-bin.00000*文件 Counter=`wc -l $BinFile |awk '{print $1}'` NextNum=0 #這個for循環用於比對$Counter,$NextNum這兩個值來確定文件是不是存在或最新的。 for file in `cat $BinFile` do base=`basename $file` #basename用於截取mysql-bin.00000*文件名,如去掉./mysql-bin.000005前面的./ NextNum=`expr $NextNum + 1` if [ $NextNum -eq $Counter ] then echo $base skip! >> $LogFile else dest=$BakDir/$base if (test -e $dest) #test -e用於檢測目標文件是否存在,存在就寫exist!到$LogFile去。 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
3.設置計劃任務每天執行
# crontab -l //內容爲下 #每個星期日凌晨3:00執行完全備份腳本 0 3 * * 0 /root/DBfullybak.sh >/dev/null 2>&1 #週一到週六凌晨3:00做增量備份 0 3 * * 1-6 /root/DBdailybak.sh >/dev/null 2>&1
總結:邏輯備份不適用於數據量特別大的生產環境,耗時長,我們在執行較大數據集的備份是可以執行物理備份,基於數據庫創建快照,使用rsync拷貝數據庫數據到遠程服務器。