mysqldump詳解


Ⅰ、mysqldump的簡單使用與注意點

1.1 基本參數

只備份innodb,用不了幾個參數,記住下面幾個即可,其他的沒什么卵用

-A 備份所有的database
-B 備份哪幾個數據庫
-R 備份存儲過程(-- routines)
-E 備份定時任務(-- events)
-d 只備份表結構
-w 備份過濾數據
-t 只備份數據
-q 直接讀數據,繞過緩沖池,默認已加
--triggers 備份觸發器
--master-data=2 在備份文件中以注釋的形式記錄備份開始時binlog的position,默認值是1,不注釋

tips:
①--set-gtid-purged=OFF 如果實例開了gtid最好加上這個參數,不然備份時候會報warning,且備份出來的數據恢復到其他版本的實例上會報錯:A partial dump from a server that has GTIDs is not allowed.
②--dump-slave,該參數可以用作在從庫做備份獲取主庫的位置點,來做一個新從庫,避免在主庫做備份影響業務,帶該參數備份時,從上sql線程會被kill,備份完再拉起

常見用法:

mysqldump --single-transaction -B test a > backup.sql    備份test庫和a庫
mysqldump --single-transaction test a > backup.sql       備份test庫下的a表
mysqldump --single-transaction test a -w "c=12"> backup.sql

1.2 其他參數

--lock-tables(-l)
在備份中依次鎖住所有表,一般用於myisam備份,備份時數據庫只能提供讀操作,以此來保證數據一致性,該參數和--single-transaction是互斥的,所以實例中既存在myisam又存在innodb則,只能使用該參數

--lock-all-tables(-x)
比上面的參數力度更大,備份時將整個實例鎖住

1.3 重點

--single-transaction
必須加(一個事務中導出數據,確保產生一致性的備份數據)

my.cnf中配上下面配置

[mysqldump]
single-transaction
master-data=2

Ⅱ、mysqldump實現原理剖析

2.1 開glog嗖哈一把看看嘛(__)

session 1:
(root@localhost) [(none)]> truncate mysql.general_log;
Query OK, 0 rows affected (0.02 sec)

(root@localhost) [(none)]> set global general_log = 1;
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [(none)]> set global log_output = 'table';
Query OK, 0 rows affected (0.00 sec)

session 2:
[root@VM_0_5_centos src]# mysqldump --single-transaction --master-data=2 -B dump_test > /tmp/back.sql

session 1:
(root@localhost) [(none)]> set global general_log = 0;
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [(none)]> set global log_output = 'file';
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [(none)]> select thread_id,left(argument,64) from mysql.general_log;

(root@localhost) [(none)]> select argument from mysql.general_log where thread_id=239 order by event_time;

FLUSH /*!40101 LOCAL */ TABLES
# 先把表刷一把,減少ftwrl鎖的等待時間
FLUSH TABLES WITH READ LOCK
# 把當前整個實例鎖成只讀
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
# 設置備份線程事務隔離級別為rr
START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
# 開啟事務
SHOW VARIABLES LIKE 'gtid\_mode'                                                                    
SHOW MASTER STATUS
# 獲得當前二進制日志位置
UNLOCK TABLES
# 釋放實例級別的只讀鎖
SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IN (SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('dump_test'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE, TOTAL_EXTENTS, INITIAL_SIZE ORDER BY LOGFILE_GROUP_NAME
SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('dump_test')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
SHOW VARIABLES LIKE 'ndbinfo\_version'
dump_test
SHOW CREATE DATABASE IF NOT EXISTS `dump_test`
SAVEPOINT sp
# 使用savepoint sp,便於回滾,用於快速釋放metadata數據共享鎖
show tables                                                                                        
show table status like 'dump\_inno'
SET SQL_QUOTE_SHOW_CREATE=1
SET SESSION character_set_results = 'binary'
show create table `dump_inno`
SET SESSION character_set_results = 'utf8'
show fields from `dump_inno`
show fields from `dump_inno`
SELECT /*!40001 SQL_NO_CACHE */ * FROM `dump_inno`
SET SESSION character_set_results = 'binary'
use `dump_test`
select @@collation_database
SHOW TRIGGERS LIKE 'dump\_inno'
SET SESSION character_set_results = 'utf8'
# 以上部分備份數據
ROLLBACK TO SAVEPOINT sp                                                                            
RELEASE SAVEPOINT sp
# 回到savepoint sp,釋放metadata的鎖
# 每取一張表的數據,就rollback to savepoint sp(一個savepoint就夠了)

root@localhost on  using Socket
/*!40100 SET @@SQL_MODE='' */
/*!40103 SET TIME_ZONE='+00:00' */

2.2 mysqldump流程小結

- 操作 解析
step1 flush tables/flush tables with read lock 將實例鎖成只讀
step2 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ/START TRANSACTION 開啟rr隔離級別的事務
step3 SHOW MASTER STATUS/UNLOCK TABLES 獲取二進制日志位置並釋放全局讀鎖
step4 SAVEPOINT sp 設置回滾點
step5 select xxx 備份數據
step6 ROLLBACK TO SAVEPOINT sp/RELEASE SAVEPOINT sp 結束一張表備份,回到sp

2.3 關鍵點細說

  • start transaction with consistent snapshot

位置點問題:事務隔離級別是rr,開始事務,並且馬上創建一個read_view,所以mysqldump備份的數據是備份開始時候的數據而不是備份結束時的數據(備份了30min,整個過程實例一直可讀可寫,備份的是30min之前的數據而不是30min之后的數據)

執行start transaction同時(而不是等到執行第一條sql)建立與本事務一致性讀的snapshot

  • --single-transaction

所有的數據都是在一個事務里面讀出來,而且事務隔離級別是如rr的,所以讀到的數據是一致的

一致性備份:整個備份從start transaction開始,備份所有的表,所有的表的數據都是在一個事務里面,通過select導出來

  • savepoint保存點(4.1還是5.0加進來的)

savepoint很少用,真正用的最多就是備份的時候,一張表備份完,會回滾到對應保存點,此時對應備份的表上面的元數據鎖都釋放,這時候可以這個表可以做ddl操作。

否則在一個事務里,持有元數據鎖,要做ddl(比如其他線程想對這里一個表創建索引),即使備份完了也做不了,要等所有備份結束才能動

沒有savepoint時,只讀鎖要持有整個事務時間,而不是表備份的時間

Ⅲ、常規操作

①備份並且壓縮

mysqldump --single-transaction --master-data=1 --triggers -R -E -B sbtest | pv | gzip -c > sbtest.backup.tgz

壓縮過的備份恢復

gunzip < sbtest.backup.tgz | mysql

②備份並且壓縮到遠程服務器

mysqldump --single-transaction --master-data=1 --triggers -R -E -B sbtest | gzip -c | ssh root@test-3 'cat > /tmp/sbtest.sql.gz'

備份校驗,另行考慮

③備份文件使用

mysql < xxx.sql;

tips:

備份占用帶寬很大,需要調度算法確保同一個集群中同時只有一個機器做備份,或者不每天做備份從而錯開備份時間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM