MySQL5.6 新特性之GTID【转】
轉(zhuǎn)自
MySQL5.6 新特性之GTID - jyzhou - 博客園
http://www.cnblogs.com/zhoujinyi/p/4717951.html
背景:
? ? ??MySQL5.6在5.5的基礎(chǔ)上增加了一些改進,本文章先對其中一個一個比較大的改進"GTID"進行說明。
概念:
? ????GTID即全局事務(wù)ID(global transaction identifier),GTID實際上是由UUID+TID組成的。其中UUID是一個MySQL實例的唯一標(biāo)識。TID代表了該實例上已經(jīng)提交的事務(wù)數(shù)量,并且隨著事務(wù)提交單調(diào)遞增,所以GTID能夠保證每個MySQL實例事務(wù)的執(zhí)行(不會重復(fù)執(zhí)行同一個事務(wù),并且會補全沒有執(zhí)行的事務(wù))。下面是一個GTID的具體形式:
4e659069-3cd8-11e5-9a49-001c4270714e:1-77更具體的說明見官方說明。
GTID意義:
? ? ??引入GTID的意義是什么?
? ? ? 1)因為清楚了GTID的格式,所以通過UUID可以知道這個事務(wù)在哪個實例上提交的。
? ? ? 2)通過GTID可以極方便的進行復(fù)制結(jié)構(gòu)上的故障轉(zhuǎn)移,新主設(shè)置。很好的解決了下面這個圖(圖來自高性能MySQL第10章)的問題。
上面圖的意思是:Server1(Master)崩潰,根據(jù)從上show slave status獲得Master_log_File/Read_Master_Log_Pos的值,Server2(Slave)已經(jīng)跟上了主,Server3(Slave)沒有跟上主。這時要是把Server2提升為主,Server3變成Server2的從。這時在Server3上執(zhí)行change的時候需要做一些計算,這里就不做說明了,具體的說明見高性能MySQL第10章,相對來說是比較麻煩的。
這個問題在5.6的GTID出現(xiàn)后,就顯得非常的簡單。由于同一事務(wù)的GTID在所有節(jié)點上的值一致,那么根據(jù)Server3當(dāng)前停止點的GTID就能定位到Server2上的GTID。甚至由于MASTER_AUTO_POSITION功能的出現(xiàn),我們都不需要知道GTID的具體值,直接使用CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION命令就可以直接完成failover的工作。
原理:
? ? ??從服務(wù)器連接到主服務(wù)器之后,把自己執(zhí)行過的GTID(Executed_Gtid_Set)<SQL線程> 、獲取到的GTID(Retrieved_Gtid_Set)<IO線程>發(fā)給主服務(wù)器,主服務(wù)器把從服務(wù)器缺少的GTID及對應(yīng)的transactions發(fā)過去補全即可。當(dāng)主服務(wù)器掛掉的時候,找出同步最成功的那臺從服務(wù)器,直接把它提升為主即可。如果硬要指定某一臺不是最新的從服務(wù)器提升為主, 先change到同步最成功的那臺從服務(wù)器, 等把GTID全部補全了,就可以把它提升為主了。
測試:
1)復(fù)制環(huán)境的搭建:具體的復(fù)制搭建的步驟可以在網(wǎng)上搜索
因為支持GTID,所以5.6多了幾個參數(shù):
mysql> show variables like '%gtid%'; +---------------------------------+-----------+ | Variable_name | Value | +---------------------------------+-----------+ | binlog_gtid_simple_recovery | OFF | | enforce_gtid_consistency | OFF | | gtid_deployment_step | OFF | | gtid_executed | | | gtid_mode | OFF | | gtid_next | AUTOMATIC | | gtid_owned | | | gtid_purged | | | simplified_binlog_gtid_recovery | OFF | +---------------------------------+-----------+主從環(huán)境的搭建和5.5沒有什么區(qū)別,唯一需要注意的是:開啟GTID需要啟用這三個參數(shù):
#GTID gtid_mode = on enforce_gtid_consistency = 1 log_slave_updates = 1任意一個參數(shù)不開啟則都會報錯:
2015-08-09 02:33:57 6512 [ERROR] --gtid-mode=ON or UPGRADE_STEP_1 or UPGRADE_STEP_2 requires --log-bin and --log-slave-updates 2015-08-09 02:33:57 6512 [ERROR] Aborting2015-08-09 02:39:58 9860 [ERROR] --gtid-mode=ON or UPGRADE_STEP_1 requires --enforce-gtid-consistency 2015-08-09 02:39:58 9860 [ERROR] Aborting具體的方法可以參考官方文檔。
三個實例開啟之后(3306、3307、3308),執(zhí)行change的時候也要注意:
各個實例的uuid:
3306: mysql> select @@server_uuid; +--------------------------------------+ | @@server_uuid | +--------------------------------------+ | 4e659069-3cd8-11e5-9a49-001c4270714e | +--------------------------------------+3307: mysql> select @@server_uuid; +--------------------------------------+ | @@server_uuid | +--------------------------------------+ | 041d0e65-3cde-11e5-9a6e-001c4270714e | +--------------------------------------+3308: mysql> select @@server_uuid; +--------------------------------------+ | @@server_uuid | +--------------------------------------+ | 081ccacf-3ce4-11e5-9a95-001c4270714e | +--------------------------------------+使用5.6之前的主從change:
mysql> change master to master_host='127.0.0.1',master_user='rep',master_password='rep',master_log_file='mysql-bin3306.000001',master_log_pos=151,/*master_auto_position=1*/;報錯:
ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.當(dāng)使用?MASTER_AUTO_POSITION 參數(shù)的時候,MASTER_LOG_FILE,MASTER_LOG_POS參數(shù)不能使用。
使用5.6之后的主從change:
mysql> change master to master_host='127.0.0.1',master_user='rep',master_password='rep',master_port=3306,master_auto_position=1;在執(zhí)行上面的命令的時候會報錯2個warnings,主要的原因是復(fù)制賬號安全的問題,相關(guān)的信息可以看這里。
從總體上看來,由于要支持GTID,所以不需要手工確定主服務(wù)器的MASTER_LOG_FILE及MASTER_LOG_POS。要是不需要GTID則需要指定FILE和POS。在2個從上執(zhí)行上面命令,到此主從環(huán)境搭建完成。GTID的主從完成之后可以通過show processlist查看:
mysql> show processlist\G; *************************** 1. row ***************************Id: 38User: repHost: localhost:52321db: NULLCommand: Binlog Dump GTID #通過GTID復(fù)制Time: 48State: Master has sent all binlog to slave; waiting for binlog to be updatedInfo: NULLRows_sent: 0 Rows_examined: 02)測試復(fù)制的故障轉(zhuǎn)移
server1(3306)掛了,服務(wù)器起不來了。需要把其中的一個從設(shè)置為主,另一個設(shè)置為其的從庫:
server2(3307):
Master_Log_File: mysql-bin3306.000002Read_Master_Log_Pos: 4156773Exec_Master_Log_Pos: 4156773server3(3308):
Master_Log_File: mysql-bin3306.000001Read_Master_Log_Pos: 83795320Exec_Master_Log_Pos: 83795320相比之下server2完成的事務(wù)要比server3更接近或則等于server1,現(xiàn)在需要把server3設(shè)置為server2的從庫。
在MySQL5.6之前,這里的計算會很麻煩,要計算之前主庫的log_pos和當(dāng)前要設(shè)置成主庫的log_pos,很有可能出錯。所以出現(xiàn)了一些高可用性的工具如MHA,MMM等解決問題。
在MySQL5.6之后,很簡單的解決了這個難題。因為同一事務(wù)的GTID在所有節(jié)點上的值一致,那么根據(jù)server3當(dāng)前停止點的GTID就能定位到server2上的GTID,所以直接在server3上執(zhí)行change即可:
mysql> stop slave; Query OK, 0 rows affected (0.02 sec)#千萬不要執(zhí)行 reset master,否則會從最先的GTID上開始執(zhí)行。mysql> change master to master_host='127.0.0.1',master_user='rep',master_password='rep',master_port=3307,master_auto_position=1; #指定到另一個比較接近主的從上。 Query OK, 0 rows affected, 2 warnings (0.02 sec)mysql> start slave; #成功的切換到新主 Query OK, 0 rows affected (0.03 sec)
主從結(jié)構(gòu)已經(jīng)變更,server2是Master,server3是Slave。因為不需要計算pos的值,所以通過GTID很簡單的解決了這個問題。
3)跳過復(fù)制錯誤:gtid_next、gtid_purged
①?從服務(wù)器跳過一個錯誤的事務(wù):
在MySQL5.6之前,只需要執(zhí)行:
mysql> set global sql_slave_skip_counter=1;?跳過一個錯誤的事務(wù),就可以繼續(xù)進行復(fù)制了。但在MySQL5.6之后則不行:
mysql> set global sql_slave_skip_counter=1; ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction分析:因為是通過GTID來進行復(fù)制的,也需要跳過這個事務(wù)從而繼續(xù)復(fù)制,這個事務(wù)可以到主上的binlog里面查看:因為不知道找哪個GTID上出錯,所以也不知道如何跳過哪個GTID。但在show slave status里的信息里可以找到在執(zhí)行Master里的POS:151
Exec_Master_Log_Pos: 151的時候報錯,所以通過mysqlbinlog找到了GTID:
# at 151 #150810 22:57:45 server id 1 end_log_pos 199 CRC32 0x5e14d88f GTID [commit=yes] SET @@SESSION.GTID_NEXT= '4e659069-3cd8-11e5-9a49-001c4270714e:1'/*!*/;找到這個GTID之后執(zhí)行:必須按照下面順序執(zhí)行
mysql> stop slave; Query OK, 0 rows affected (0.01 sec)mysql> set session gtid_next='4e659069-3cd8-11e5-9a49-001c4270714e:1'; #在session里設(shè)置gtid_next,即跳過這個GTID Query OK, 0 rows affected (0.01 sec)mysql> begin; #開啟一個事務(wù) Query OK, 0 rows affected (0.00 sec)mysql> commit; Query OK, 0 rows affected (0.01 sec)mysql> SET SESSION GTID_NEXT = AUTOMATIC; #把gtid_next設(shè)置回來 Query OK, 0 rows affected (0.00 sec)mysql> start slave; #開啟復(fù)制 Query OK, 0 rows affected (0.01 sec)查看復(fù)制狀態(tài):
mysql> show slave status\G; *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 127.0.0.1Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin3306.000001Read_Master_Log_Pos: 38260944Relay_Log_File: mysqld-relay-bin3307.000003Relay_Log_Pos: 716Relay_Master_Log_File: mysql-bin3306.000001Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 38260944Relay_Log_Space: 38261936Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4e659069-3cd8-11e5-9a49-001c4270714eMaster_Info_File: mysql.slave_master_infoSQL_Delay: 0 #延遲同步SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 4e659069-3cd8-11e5-9a49-001c4270714e:1-48Executed_Gtid_Set: 4e659069-3cd8-11e5-9a49-001c4270714e:1-48Auto_Position: 1在此成功跳過了錯誤,同步繼續(xù)。可以通過這個辦法來處理復(fù)制失敗的問題,這里還有個例子,有興趣的可以看一下(從服務(wù)器中跳過一條語句/事務(wù)):
mysql > stop slave; Query OK, 0 ROWS affected (0.05 sec) mysql > CHANGE master TO MASTER_DELAY=600; Query OK, 0 ROWS affected (0.27 sec) mysql > START slave; Query OK, 0 ROWS affected, 1 warning (0.06 sec)master 原本是正常的, 然后意外地執(zhí)行了 truncate table:mysql > INSERT INTO t SET title='c'; Query OK, 1 ROW affected (0.03 sec) mysql > INSERT INTO t SET title='d'; Query OK, 1 ROW affected (0.05 sec)mysql > SHOW master STATUS \G *************************** 1. ROW ***************************File: black-bin.000001POSITION: 2817Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:1-10 1 ROW IN SET (0.00 sec)mysql > TRUNCATE TABLE t; Query OK, 0 ROWS affected (0.15 sec)mysql > SHOW master STATUS \G *************************** 1. ROW ***************************File: black-bin.000001POSITION: 2948Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:1-11 1 ROW IN SET (0.00 sec)slave有延遲, 雖然已經(jīng)獲取到了gtid及對應(yīng)的events, 但是并未執(zhí)行:mysql > SHOW slave STATUS \G *************************** 1. ROW ***************************Slave_IO_State: Waiting FOR master TO send event ....... .......SQL_Delay: 600SQL_Remaining_Delay: 565Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed eventMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:9-11Executed_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:1-8Auto_Position: 1 1 ROW IN SET (0.00 sec)要想辦法在slave中跳過 GTID:0c005b76-d3c7-11e2-a27d-274c063b18c4:11, 也就是那條truncate table語句 。 辦法就是設(shè)置GTID_NEXT,然后提交一個空的事務(wù)。mysql > stop slave; Query OK, 0 ROWS affected (0.03 sec) mysql > SET session gtid_next='0c005b76-d3c7-11e2-a27d-274c063b18c4:11'; Query OK, 0 ROWS affected (0.00 sec) mysql > BEGIN; commit; Query OK, 0 ROWS affected (0.00 sec) Query OK, 0 ROWS affected (0.01 sec)mysql >SET SESSION GTID_NEXT = AUTOMATIC; Query OK, 0 ROWS affected (0.00 sec) mysql > START slave; Query OK, 0 ROWS affected, 1 warning (0.07 sec)查看復(fù)制狀態(tài) mysql > SHOW slave STATUS \G *************************** 1. ROW ***************************Slave_IO_State: Waiting FOR master TO send event ....... .......Retrieved_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:9-11Executed_Gtid_Set: 0c005b76-d3c7-11e2-a27d-274c063b18c4:1-11Auto_Position: 1 1 ROW IN SET (0.00 sec)mysql > SELECT * FROM t; +----+-------+ | id | title | +----+-------+ | 1 | a | | 2 | b | | 3 | c | | 4 | d | +----+-------+ 4 ROWS IN SET (0.00 sec)成功跳過 truncate table, 當(dāng)然此時主從的數(shù)據(jù)已經(jīng)不一致了。注意:通過GTID的復(fù)制都是沒有指定MASTER_LOG_FILE和MASTER_LOG_POS的,所以通過GTID復(fù)制都是從最先開始的事務(wù)開始,除非在自己的binlog里面有執(zhí)行過之前的記錄,才會繼續(xù)后面的執(zhí)行。
②?要是事務(wù)日志被purge,再進行change:
mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql-bin3306.000001 | 38260944 | +----------------------+-----------+ 1 row in set (0.00 sec)mysql> flush logs; Query OK, 0 rows affected (0.03 sec)mysql> show tables; +---------------+ | Tables_in_mmm | +---------------+ | patent_family | | t1 | | t2 | +---------------+ 3 rows in set (0.01 sec)mysql> create table t3(id int)engine = tokudb; Query OK, 0 rows affected (0.02 sec)mysql> insert into t3 values(3),(4); Query OK, 2 rows affected (0.05 sec) Records: 2 Duplicates: 0 Warnings: 0mysql> flush logs; Query OK, 0 rows affected (0.02 sec)mysql> create table ttt(id int)engine = tokudb; Query OK, 0 rows affected (0.02 sec)mysql> insert into ttt values(1),(2),(3),(4),(5); Query OK, 5 rows affected (0.03 sec) Records: 5 Duplicates: 0 Warnings: 0mysql> show master logs; +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql-bin3306.000001 | 38260995 | | mysql-bin3306.000002 | 656 | | mysql-bin3306.000003 | 619 | +----------------------+-----------+ 3 rows in set (0.00 sec)mysql> purge binary logs to 'mysql-bin3306.000003'; #日志被purge Query OK, 0 rows affected (0.02 sec)mysql> show master logs; #日志被purge之后等下的binlog +----------------------+-----------+ | Log_name | File_size | +----------------------+-----------+ | mysql-bin3306.000003 | 619 | +----------------------+--------3308登陸之后執(zhí)行:mysql> change master to master_host='127.0.0.1',master_user='rep',master_password='rep',master_port=3306,master_auto_position=1; Query OK, 0 rows affected, 2 warnings (0.04 sec)mysql> start slave; Query OK, 0 rows affected (0.02 sec)mysql> show slave status\G; *************************** 1. row ***************************Slave_IO_State: Master_Host: 127.0.0.1Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: Read_Master_Log_Pos: 4Relay_Log_File: mysqld-relay-bin3308.000001Relay_Log_Pos: 4Relay_Master_Log_File: Slave_IO_Running: NoSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 0Relay_Log_Space: 151Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 1236Last_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.'Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4e659069-3cd8-11e5-9a49-001c4270714eMaster_Info_File: /var/lib/mysql3/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: 150811 00:02:50Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 1報錯:
Last_IO_Errno: 1236Last_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.'這里需要解決的是:Slave如何跳過purge的部分,而不是在最先開始的事務(wù)執(zhí)行。
在主上執(zhí)行,查看被purge的GTID: mysql> show global variables like 'gtid_purged'; +---------------+-------------------------------------------+ | Variable_name | Value | +---------------+-------------------------------------------+ | gtid_purged | 4e659069-3cd8-11e5-9a49-001c4270714e:1-50 | +---------------+-------------------------------------------+ 1 row in set (0.00 sec)在從上執(zhí)行,跳過這個GTID: mysql> stop slave; Query OK, 0 rows affected (0.00 sec)mysql> set global gtid_purged = '4e659069-3cd8-11e5-9a49-001c4270714e:1-50'; Query OK, 0 rows affected (0.02 sec)mysql> reset master; Query OK, 0 rows affected (0.04 sec)mysql> start slave; Query OK, 0 rows affected (0.01 sec)要是出現(xiàn): ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty. 則需要執(zhí)行: reset master;到這從的同步就正常了。?
mysql> show slave status\G; *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 127.0.0.1Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin3306.000003Read_Master_Log_Pos: 619Relay_Log_File: mysqld-relay-bin3308.000002Relay_Log_Pos: 797Relay_Master_Log_File: mysql-bin3306.000003Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 619Relay_Log_Space: 1006Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4e659069-3cd8-11e5-9a49-001c4270714eMaster_Info_File: /var/lib/mysql3/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 4e659069-3cd8-11e5-9a49-001c4270714e:51-52Executed_Gtid_Set: 4e659069-3cd8-11e5-9a49-001c4270714e:1-52Auto_Position: 1 1 row in set (0.00 sec)mysql> use mmm Database changed mysql> show tables; +---------------+ | Tables_in_mmm | +---------------+ | ttt | +---------------+ 1 row in set (0.00 sec)③ 通過另一個從庫恢復(fù)從庫數(shù)據(jù)
比如一臺從庫誤操作,數(shù)據(jù)丟失了,可以通過另一個從庫來進行恢復(fù):
slave2(3308): mysql> use mmm Database changed mysql> show tables; +---------------+ | Tables_in_mmm | +---------------+ | patent_family | | t | | tt | +---------------+ 3 rows in set (0.00 sec)mysql> truncate table tt; #誤操作,把記錄刪除了 Query OK, 0 rows affected (0.02 sec)mysql> show slave status\G; *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 127.0.0.1Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin3306.000001Read_Master_Log_Pos: 38260553Relay_Log_File: mysqld-relay-bin3308.000002Relay_Log_Pos: 38260771Relay_Master_Log_File: mysql-bin3306.000001Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 38260553Relay_Log_Space: 38260980Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1Master_UUID: 4e659069-3cd8-11e5-9a49-001c4270714eMaster_Info_File: /var/lib/mysql3/master.infoSQL_Delay: 0 #延遲同步SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 4e659069-3cd8-11e5-9a49-001c4270714e:1-46Executed_Gtid_Set: 081ccacf-3ce4-11e5-9a95-001c4270714e:1, #多出了一個GTID(本身實例執(zhí)行的事務(wù)) 4e659069-3cd8-11e5-9a49-001c4270714e:1-46Auto_Position: 1數(shù)據(jù)被誤刪除之后,最好停止復(fù)制:stop slave;恢復(fù)數(shù)據(jù)從slave1(3307)上備份數(shù)據(jù),并還原到slave2(3308)中。 備份: mysqldump -uzjy -p123456 -h127.0.0.1 -P3307 --default-character-set=utf8 --set-gtid-purged=ON -B mmm > mmm1.sql在還原到slave2的時候需要在slave2上執(zhí)行:reset master; 不然會報錯: ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.還原: root@zjy:~# mysql -uzjy -p123456 -h127.0.0.1 -P3308 --default-character-set=utf8 < mmm.sql 開啟同步: mysql> start slave; Query OK, 0 rows affected, 1 warning (0.03 sec)這時候你會發(fā)現(xiàn)誤刪除的數(shù)據(jù)已經(jīng)被還原,并且復(fù)制也正常。因為根據(jù)GTID的原理,通過slave1的備份直接可以和Master進行同步。這里備份注意的一點是:在備份開啟GTID的實例里,需要指定?--set-gtid-purged參數(shù),否則會報warning:
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events備份文件里面會出現(xiàn):
SET @@GLOBAL.GTID_PURGED='4e659069-3cd8-11e5-9a49-001c4270714e:1-483';還原的時候會要求先在實例上reset master,不然會報錯:
Warning: Using a password on the command line interface can be insecure. ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.指定--set-gtid-purged=ON參數(shù),出現(xiàn)GTID_PURGED,直接還原的時候執(zhí)行,從庫不需要其他操作就可以直接change到主。關(guān)于GTID更多的信息可以到官方文檔里查看。?
總結(jié):
? ? ??GTID就是全局事務(wù)ID(global transaction identifier ),最初由google實現(xiàn),官方MySQL在5.6才加入該功能。要是主從結(jié)構(gòu)只有一臺Master和一臺Slave對于GTID來說就沒有優(yōu)勢了,而對于2臺主以上的結(jié)構(gòu)優(yōu)勢異常明顯,可以在數(shù)據(jù)不丟失的情況下切換新主。
? ? ? 使用GTID需要注意的是:在構(gòu)建主從復(fù)制之前,在一臺將成為主的實例上進行一些操作(如數(shù)據(jù)清理等),通過GTID復(fù)制,這些在主從成立之前的操作也會被復(fù)制到從服務(wù)器上,引起復(fù)制失敗。即:通過GTID復(fù)制都是從最先開始的事務(wù)日志開始,即使這些操作在復(fù)制之前執(zhí)行。比如在server1上執(zhí)行一些drop、delete的清理操作,接著在server2上執(zhí)行change的操作,會使得server2也進行server1的清理操作。
?
參考文章:
http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html
http://www.cnblogs.com/cenalulu/p/4309009.html
http://mysqllover.com/?p=594
http://forum.z27315.com/topic/22781-mysql56%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/
www.zhaokunyao.com/archives/4131
?
總結(jié)
以上是生活随笔為你收集整理的MySQL5.6 新特性之GTID【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 71文件类型
- 下一篇: linux cmake编译源码,linu