1. 程式人生 > 其它 >mysqldump的一點使用總結(r12筆記第81天)

mysqldump的一點使用總結(r12筆記第81天)

MySQL裡的mysqldump無疑是大家使用最為廣泛的備份恢復工具了。這樣一個工具使用起來功能非常豐富,很多功能幾個引數組合起來就能夠輕鬆實現了,我就簡單列舉幾個不錯的點。

--master-data

這個選項在搭建主從的時候經常需要考慮,而有了GTID,這個工作一下子輕鬆了很多,如果需要使用我們總是會使用maser-data=2來匯出,1和2是什麼區別,簡單來看,區別不大,但是差別很明顯。

2的情況 -- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000033', MASTER_LOG_POS=943935226; 1的情況 CHANGE MASTER TO MASTER_LOG_FILE='binlog.000033', MASTER_LOG_POS=943935226;

--order-by-primary

這個選項屬於MySQL很有特色的一個功能,能夠根據主鍵值來進行排序,這樣得到的資料看起來就更加規整了。

----skip-extended-insert

如果要得到一行資料對應一條insert語句的形式,使用這個選項就可以搞定。預設是使用insert into xxx values(xx)(xx)的形式。

INSERT INTO `test` VALUES (1,'1'); INSERT INTO `test` VALUES (2,'2'); INSERT INTO `test` VALUES (3,'3'); INSERT INTO `test` VALUES (5,'5');

--add-drop-database 如果在資料恢復的時候,資料庫已經存在則刪除重建的情況,使用這個選項就很有用,而在表級預設就不需要了,因為預設是打開了--add-drop-table選項。

Variables (--variable-name=value) and boolean options {FALSE|TRUE} Value (after reading options) --------------------------------- ---- all-databases FALSE all-tablespaces FALSE

no-tablespaces FALSE add-drop-database FALSE add-drop-table TRUE

當然對於這個選項,我們得多說說,在最後來引申一個bug。

--replace

這個選項可以生成replace語句而非insert語句,在一些特定的場景中尤其有用。如果出現了資料衝突的情況,需要merge資料,使用replace選項就是一個很不錯的選擇,而我們也承上啟下,比如想一行資料生辰過一條replace語句,那麼就可以結合--skip-extended-insert來完成,這樣一來就會生成若干條replace語句。

REPLACE INTO `test` VALUES (1,'aa'); REPLACE INTO `test` VALUES (2,'bb');

--complete-insert

這個選項簡直臺酸爽了,可以生成一個完整的列值對映關係。

INSERT INTO `test` (`id`, `name`) VALUES (1,'aa'),(2,'bb');

或者結合--skip-extended-insert生成多條語句。

INSERT INTO `test` (`id`, `name`) VALUES (1,'aa'); INSERT INTO `test` (`id`, `name`) VALUES (2,'bb');

一個bug

其實mysqldump匯出資料的過程還是比較清晰的,只是多了一些更加豐富的功能來修飾。但是也在測試的過程彙總發現了--add-drop-database的一個bug,說起來關係就一下子很微妙了。

如果你需要把某個資料庫的資料恢復到指定的備份,如果是全部資料的恢復,包括資料字典資料等,那麼使用mysqldump的時候--add-drop-database選項就尤其關鍵了。

我在使用mysqldup --all-databases --add-drop-database的方式匯出資料,匯入恢復的時候,收到一個錯誤資訊。

ERROR 1580 (HY000): You cannot 'DROP' a log table if logging is enabled

這樣一個問題,看起來很詭異,如果是使用source的方式來執行,基本上會淹沒在大批量的日誌中。而使用管道的方式也好不到哪裡,因為這個錯誤是完全相同的。

為什麼會有這個問題呢,是在mysql這個資料庫中存在兩個表slow_log,general_log(它們的儲存引擎是csv的)。我們的資料庫基本都開啟了慢日誌選項slow_query_log,在啟用的時候,如果嘗試drop這個表就會丟擲錯誤,這一點上來看,這個處理確實有些彆扭,而查詢mysql的bug庫還真有一個匹配的bug。https://bugs.mysql.com/bug.php?id=69953

而目前的解決方案就有很多了,如果想盡可能平滑實現這個功能,那就是修改匯出的sql檔案,把drop database if exists mysql這句給去掉,聽起來比較笨重,或者修改mysqldump.c,相當於在程式碼層面加一層過濾。可以參考丁奇的一篇部落格。https://m.aliyun.com/yunqi/articles/8721

而如果你使用一點小技巧,比如匯入資料前,關掉slow_log,匯入後開啟,那麼匯入後就開啟不了了,會提示表不存在,無法開啟,這樣看來,你還得單獨再對此做一個備份,想想都頭疼。