在MySQL中使用GTIDs復(fù)制協(xié)議和中斷協(xié)議的教程_MySQL教程
推薦:MySQL獲取所有分類的前N條記錄比如有文章表 Article(Id,Category,InsertDate),現(xiàn)在要用SQL找出每種類型中時(shí)間最新的前N個(gè)數(shù)據(jù)組成的集合,一段不錯(cuò)的代碼,留存?zhèn)溆?SELECT A1.* FROM Article AS A1 INNER JOIN (SELECT A.Category,A.InsertDate FROM Article AS A LEFT JOIN Article AS B ON A.Ca
MySQL5.6有很多新的特性,其中很多人都感興趣的一條就是全局事務(wù)序號(hào)功能(GTIDs)。而大家都對(duì)這一特性很感興趣的原因也很好理解,即:本來重新連接從服務(wù)器和一個(gè)新的主服務(wù)器一直是件很麻煩的事,然而在啟用GTIDs功能之后就變得簡單易行�?墒牵珿TIDs的使用不單單是用單獨(dú)的標(biāo)識(shí)符替換舊的二進(jìn)制日志文件/位置,它也采用了新的復(fù)制協(xié)議。假如你還不太明白這些,那你可以在這篇文章里學(xué)點(diǎn)什么。
復(fù)制協(xié)議:新的 VS 舊的
舊的協(xié)議往往簡單直接即:首先從服務(wù)器上在一個(gè)特定的偏移量那里連接到一個(gè)給定的二進(jìn)制日志文件,然后主服務(wù)器在從那里發(fā)送所有的事務(wù)。
新協(xié)議稍有不同:slave首先會(huì)發(fā)送它已經(jīng)執(zhí)行過的GTID的范圍,然后master發(fā)送每一個(gè)丟失的事務(wù). 它也確保了一個(gè)給定的GTID只可以在一個(gè)特定的slave中執(zhí)行一次.
實(shí)踐中,這會(huì)改變?nèi)魏螙|西嗎? 使得,它會(huì)改變很多東西. 想象一下下面的場(chǎng)景: 你想要從trx 4開始復(fù)制,但是trx2在slave上因?yàn)槟撤N緣故丟失了.
使用老協(xié)議的話,trx 2再也不會(huì)被執(zhí)行一次,而使用新協(xié)議,它就會(huì)被自動(dòng)的再執(zhí)行一次.
下面是兩個(gè)你可以在實(shí)踐中看到新協(xié)議的通用場(chǎng)景.
跳過事務(wù)
眾所周知老的 SET GLOBAL sql_slave_skip_counter = N 在你想要跳過一個(gè)事務(wù)時(shí)不再提供支持,而GTID就可以被啟用了. 換用 GTID XXX:N 來跳過事務(wù), 你須得 注入一個(gè)空的事務(wù):
mysql> SET gtid_next = 'XXX:N';
mysql> BEGIN; COMMIT;
mysql> SET gtid_next = 'AUTOMATIC';
為什么我們不能使用 sql_slave_skip_counter? 就是因?yàn)樾碌膹?fù)制協(xié)議!
想象一下我們擁有如下圖所示的三臺(tái)服務(wù)器:
讓我們假設(shè) sql_slave_skip_counter 可以用并且已經(jīng)被用在S2上用于跳過trx2. 如果你吧S2設(shè)置成S1的一個(gè)slave將會(huì)發(fā)生什么呢?
兩個(gè)服務(wù)器會(huì)互相交換被執(zhí)行了GTID的范圍,并且S1將會(huì)意識(shí)到其必須將trx2發(fā)送給S2. 然后會(huì)發(fā)生的事情有兩種可能:
如果 trx 2 仍然在S1的二進(jìn)制日志中,它將會(huì)被發(fā)送給S2,而事務(wù)在也不會(huì)被跳過了.
如果 trx 2 不再存在于S1的二進(jìn)制日志中,你將會(huì)得到一個(gè)復(fù)制錯(cuò)誤.
很明顯這不安全,這就是為什么 sql_slave_skip_counter 在使用GTID時(shí)是不能用的. 要想跳過一個(gè)事務(wù),唯一安全的選擇就是去執(zhí)行一個(gè)虛擬的事務(wù),而不是一個(gè)真實(shí)的事務(wù).
錯(cuò)誤的事務(wù)
如果你在一個(gè)slave上本地執(zhí)行了一個(gè)事務(wù) (在MySQL文檔中被稱為錯(cuò)誤事務(wù)), 如果你被這個(gè)事務(wù)推送到新的master上時(shí)會(huì)發(fā)生什么呢?
使用老協(xié)議,基本上沒啥事(準(zhǔn)確點(diǎn)說,新的master和其slave之間的數(shù)據(jù)將會(huì)出現(xiàn)不一致,但那在稍后就可能會(huì)被修復(fù)).
使用新協(xié)議,錯(cuò)誤的事務(wù)將會(huì)被識(shí)別成為在每個(gè)地方都丟失了,并且將會(huì)自動(dòng)在容錯(cuò)備份上被執(zhí)行,這樣就將會(huì)導(dǎo)致打斷復(fù)制的隱患.
比方說,你擁有一個(gè)master(M)和兩個(gè)slave (S1 和 S2). 這里有兩種將slave重連到新的master將會(huì)發(fā)生(帶有不同復(fù)制錯(cuò)誤的)失敗的場(chǎng)景:
# 場(chǎng)景 1
# S1
mysql> CREATE DATABASE mydb;
# M
mysql> CREATE DATABASE IF NOT EXISTS mydb;
# Thanks to 'IF NOT EXITS', replication doesn't break on S1. Now move S2 to S1:
# S2
mysql> STOP SLAVE; CHANGE MASTER TO MASTER_HOST='S1'; START SLAVE;
# This creates a conflict with existing data!
mysql> SHOW SLAVE STATUS\G
[...]
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'mydb'; database exists' on query. Default database: 'mydb'. Query: 'CREATE DATABASE mydb'
[...]
# 場(chǎng)景 2
# S1
mysql> CREATE DATABASE mydb;
# Now, we'll remove this transaction from the binary logs
# S1
mysql> FLUSH LOGS;
mysql> PURGE BINARY LOGS TO 'mysql-bin.000008';
# M
mysql> CREATE DATABASE IF NOT EXISTS mydb;
# S2
mysql> STOP SLAVE; CHANGE MASTER TO MASTER_HOST='S1'; START SLAVE;
# The missing transaction is no longer available in the master's binary logs!
mysql> SHOW SLAVE STATUS\G
[...]
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'
[...]
你可以這樣理解,錯(cuò)誤的事務(wù)應(yīng)該借助基于GTID的服務(wù)得以避免. 如果你需要運(yùn)行一個(gè)本地事務(wù),最好的選擇是針對(duì)那條特定的語句禁用二進(jìn)制日志:
mysql> SET SQL_LOG_BIN = 0;
mysql> # Run local transaction
結(jié)論
GTIDs在讓我們方便重新和其他服務(wù)器連接副本方面是個(gè)不小的進(jìn)步。然而同樣的在運(yùn)維方面我們也因此面臨新的困難和挑戰(zhàn)。假如你打算開始使用GTIDs,那么你就得確實(shí)理解新的復(fù)制協(xié)議,否則你就會(huì)以一種想不到的方式結(jié)束復(fù)制過程。
分享:將MySQL的臨時(shí)目錄建立在內(nèi)存中的教程MySQL 系統(tǒng)會(huì)在內(nèi)存(MEMORY)和磁盤(MyISAM)中建立臨時(shí)表,如何能知道在磁盤中建立了多少臨時(shí)表以及在內(nèi)存中建立多少臨時(shí)表呢?你可以通過下面命令獲知: mysql SHOW GLOBAL STATUS LIKE 'Created_tmp%tables'; +-------------------------+----------+ | Variable_name
- MySQL獲取所有分類的前N條記錄
- 將MySQL的臨時(shí)目錄建立在內(nèi)存中的教程
- 介紹使用WordPress時(shí)10個(gè)常用的MySQL查詢
- 初步介紹MySQL中的集合操作
- 簡單介紹MySQL中的事務(wù)機(jī)制
- mysql查詢區(qū)分大小寫高性能
- WordPress如何修改Mysql數(shù)據(jù)庫的表前綴
- sqlitestudio怎么用
- MS SQL Server Management Studio Express怎么安裝?
- SQL Server 錯(cuò)誤:15023
- mysql數(shù)據(jù)庫執(zhí)行SQL導(dǎo)出數(shù)據(jù)方法
- MySQL最常見的操作語句小結(jié)
MySQL教程Rss訂閱編程教程搜索
MySQL教程推薦
猜你也喜歡看這些
- SQL2008 附加數(shù)據(jù)庫提示5120錯(cuò)誤解決方法
- 基于Sql Server通用分頁存儲(chǔ)過程的解決方法
- 讓你的MySQL數(shù)據(jù)庫徹底與中文聯(lián)姻
- SQL Server 2008 數(shù)據(jù)加載創(chuàng)世界記錄
- 揭秘SQL Server查詢優(yōu)化方法
- 解析配置SQL SERVER合并復(fù)制(一)概念介紹
- mssql2005字符串連接方法 避免無效的連接錯(cuò)誤
- 總結(jié)SQL的存儲(chǔ)過程
- 解讀SQL Server如何備份文件導(dǎo)入當(dāng)前數(shù)據(jù)庫
- Sql語句密碼驗(yàn)證的安全漏洞
- 相關(guān)鏈接:
- 教程說明:
MySQL教程-在MySQL中使用GTIDs復(fù)制協(xié)議和中斷協(xié)議的教程
。