mysql查詢庫,MySQL全備份如何只恢復一個庫或者一個表?
前言
MySQL 5.6引入了GTID,每個事務都會產生一個GTID,我們可以通過驗證主從GTID來驗證主從數據的一致性。
為了敘述簡便,定義一個量ALL_GTID: 表示某個數據庫實例上 所有存在過的 或 將要存在的事務 的GTID(包括已經被purge掉的事務)。
在討論數據庫可用性的場景中, 當發生主備切換時, 需要進行數據補償。通過比較主備的ALL_GTID,可以確定需要補償多少數據:
在實例存活的情況,可以在實例狀態中查詢ALL_GTID。在實例崩潰的情況,無法在實例狀態中查詢ALL_GTID。可以通過查詢BINLOG中的Previous-GTIDs計算來獲得ALL_GTID。下面列舉與ALL_GTID相關的變量。與ALL_GTID相關的變量Previous-GTIDsPrevious-GTIDs格式如下(環境為MySQL5.7,日志手動flush binary logs獲得):查看新輪轉出的BINLOG:下面為mysql-bin.00001中包含的GTID:請點擊輸入圖片描述然后再次flush binary logs:請點擊輸入圖片描述mysql-bin.00002中是沒有任何GTID的。請點擊輸入圖片描述綜上Previous-GTIDs是本身這個BINLOG文件前面的所有BINLOG的集合。請點擊輸入圖片描述全局變量中的GTID相關的變量請點擊輸入圖片描述變量解釋:gtid_executed 代表著server上所有事務執行產生的GTID(包含已經被purge的BINLOG中的GTID或者是手動set gtid_purged的GTID)。gtid_purged 代表著已經被purge到的GTID。gtid_purged是gtid_executed的子集。gtid_retrieved 是從機上relay_log中的GTID。ALL_GTID 的計算了解了GTID相關的變量之后,可以得到獲得實例的All_GTID的集合的方法:對象方法存活的Master實例 gtid_executed 存活的Slave實例 gtid_executed和gtid_retrieved的并集 非存活Master實例 最后一個BINLOG文件的Previous-GTIDs + 最后一個BINLOG文件中所有的GTID 非存活Slave實例 最后一個BINLOG文件的Previous-GTIDs + 最后一個BINLOG文件中所有的GTID 在獲得非存活實例中的ALL_GTID時,最后一個BINLOG文件中的GTID可能不連續(比如事務同時來自于本實例客戶端和復制回放),所以需要掃描最后一個BINLOG文件。生產中我們使用Xtrabackup來產生一個 從實例 的流程如下:拉取備份,進行還原change master toset @@global.gtid_purged='xxx';set @@global.gtid_purged='xxx'; 的影響:將 從實例 的ALL_GTID手工置為xxx, 在通過GTID方式建立復制時不會出錯.將更新Binlog中記錄的Previous-GTIDs (由于Binlog不可改變, 將產生新的Binlog, 記錄新的Previous-GTIDs).MySQL 5.7中set gtid_purged的行為變更問題描述回顧一下備份恢復的流程:拉取備份,進行還原change master toset @@global.gtid_purged='xxx';現象: 發現有一臺MySQL 5.7的Slave服務器恢復后沒有產生 正確的Previous-GTIDs。分析分析整個過程,解決問題應該分階段進行手動模擬發現問題。以下為詳細步驟:手工還原備份環境BINLOG數量,Previous-GTIDs狀態Xtrabackup 2.4.2 & MySQL 5.6 1,空 Xtrabackup 2.4.2 & MySQL 5.7 1,空 Xtrabackup 2.2.9 & MySQL 5.6 1,空 Xtrabackup 2.2.9 & MySQL 5.7 1,空 可見: 恢復過程不會輪轉BINLOG。驗證change master和set gtid_purged在不同的MySQL版本中執行的差異環境BINLOG數量,Previous-GTIDs狀態change master & MySQL 5.6 1,空 change master & MySQL 5.7 1,空 set gtid_purged & MySQL 5.6 2,正常 set gtid_purged & MySQL 5.7 1,空 可見: 執行set gtid_purged時不同版本的MySQL產生了差異驗證對不同版本MySQL單獨執行set @@global.gtid_purged='';語句。檢查結果環境進行的操作BINLOG數量,Previous-GTIDs狀態MySQL 5.7 reset master; set @@global.gtid_purged=”; 1,空 MySQL 5.6 reset master; set @@global.gtid_purged=”; 2,正常 結論參考: http://bugs.mysql.com/bug.php?id=75767官方解釋: 在5.7版本中,執行SET GTID_PURGED語句后binlog_simple_gtid_recovery會給GTID_PURGED計算出一個錯誤的值。由于5.7中新增了存儲GTID的表。所以5.7版本中set @@global.gtid_purged='';語句被改成只修改存放GTID的表。而5.6版本中會進行BINLOG輪轉和向Previous_gtids_log_event中添加GTID。如果5.7需要產生和5.6相同結果的話,可以在SET GTID_PURGED語句后手動執行flush binary logs語句。