MySQL5.6 新特性之GTID【转】
轉自
MySQL5.6 新特性之GTID - jyzhou - 博客園
http://www.cnblogs.com/zhoujinyi/p/4717951.html
背景:
? ? ??MySQL5.6在5.5的基礎上增加了一些改進,本文章先對其中一個一個比較大的改進"GTID"進行說明。
概念:
? ????GTID即全局事務ID(global transaction identifier),GTID實際上是由UUID+TID組成的。其中UUID是一個MySQL實例的唯一標識。TID代表了該實例上已經提交的事務數量,并且隨著事務提交單調遞增,所以GTID能夠保證每個MySQL實例事務的執行(不會重復執行同一個事務,并且會補全沒有執行的事務)。下面是一個GTID的具體形式:
4e659069-3cd8-11e5-9a49-001c4270714e:1-77更具體的說明見官方說明。
GTID意義:
? ? ??引入GTID的意義是什么?
? ? ? 1)因為清楚了GTID的格式,所以通過UUID可以知道這個事務在哪個實例上提交的。
? ? ? 2)通過GTID可以極方便的進行復制結構上的故障轉移,新主設置。很好的解決了下面這個圖(圖來自高性能MySQL第10章)的問題。
上面圖的意思是:Server1(Master)崩潰,根據從上show slave status獲得Master_log_File/Read_Master_Log_Pos的值,Server2(Slave)已經跟上了主,Server3(Slave)沒有跟上主。這時要是把Server2提升為主,Server3變成Server2的從。這時在Server3上執行change的時候需要做一些計算,這里就不做說明了,具體的說明見高性能MySQL第10章,相對來說是比較麻煩的。
這個問題在5.6的GTID出現后,就顯得非常的簡單。由于同一事務的GTID在所有節點上的值一致,那么根據Server3當前停止點的GTID就能定位到Server2上的GTID。甚至由于MASTER_AUTO_POSITION功能的出現,我們都不需要知道GTID的具體值,直接使用CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION命令就可以直接完成failover的工作。
原理:
? ? ??從服務器連接到主服務器之后,把自己執行過的GTID(Executed_Gtid_Set)<SQL線程> 、獲取到的GTID(Retrieved_Gtid_Set)<IO線程>發給主服務器,主服務器把從服務器缺少的GTID及對應的transactions發過去補全即可。當主服務器掛掉的時候,找出同步最成功的那臺從服務器,直接把它提升為主即可。如果硬要指定某一臺不是最新的從服務器提升為主, 先change到同步最成功的那臺從服務器, 等把GTID全部補全了,就可以把它提升為主了。
測試:
1)復制環境的搭建:具體的復制搭建的步驟可以在網上搜索
因為支持GTID,所以5.6多了幾個參數:
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 | +---------------------------------+-----------+主從環境的搭建和5.5沒有什么區別,唯一需要注意的是:開啟GTID需要啟用這三個參數:
#GTID gtid_mode = on enforce_gtid_consistency = 1 log_slave_updates = 1任意一個參數不開啟則都會報錯:
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),執行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.當使用?MASTER_AUTO_POSITION 參數的時候,MASTER_LOG_FILE,MASTER_LOG_POS參數不能使用。
使用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;在執行上面的命令的時候會報錯2個warnings,主要的原因是復制賬號安全的問題,相關的信息可以看這里。
從總體上看來,由于要支持GTID,所以不需要手工確定主服務器的MASTER_LOG_FILE及MASTER_LOG_POS。要是不需要GTID則需要指定FILE和POS。在2個從上執行上面命令,到此主從環境搭建完成。GTID的主從完成之后可以通過show processlist查看:
mysql> show processlist\G; *************************** 1. row ***************************Id: 38User: repHost: localhost:52321db: NULLCommand: Binlog Dump GTID #通過GTID復制Time: 48State: Master has sent all binlog to slave; waiting for binlog to be updatedInfo: NULLRows_sent: 0 Rows_examined: 02)測試復制的故障轉移
server1(3306)掛了,服務器起不來了。需要把其中的一個從設置為主,另一個設置為其的從庫:
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完成的事務要比server3更接近或則等于server1,現在需要把server3設置為server2的從庫。
在MySQL5.6之前,這里的計算會很麻煩,要計算之前主庫的log_pos和當前要設置成主庫的log_pos,很有可能出錯。所以出現了一些高可用性的工具如MHA,MMM等解決問題。
在MySQL5.6之后,很簡單的解決了這個難題。因為同一事務的GTID在所有節點上的值一致,那么根據server3當前停止點的GTID就能定位到server2上的GTID,所以直接在server3上執行change即可:
mysql> stop slave; Query OK, 0 rows affected (0.02 sec)#千萬不要執行 reset master,否則會從最先的GTID上開始執行。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)
主從結構已經變更,server2是Master,server3是Slave。因為不需要計算pos的值,所以通過GTID很簡單的解決了這個問題。
3)跳過復制錯誤:gtid_next、gtid_purged
①?從服務器跳過一個錯誤的事務:
在MySQL5.6之前,只需要執行:
mysql> set global sql_slave_skip_counter=1;?跳過一個錯誤的事務,就可以繼續進行復制了。但在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來進行復制的,也需要跳過這個事務從而繼續復制,這個事務可以到主上的binlog里面查看:因為不知道找哪個GTID上出錯,所以也不知道如何跳過哪個GTID。但在show slave status里的信息里可以找到在執行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之后執行:必須按照下面順序執行
mysql> stop slave; Query OK, 0 rows affected (0.01 sec)mysql> set session gtid_next='4e659069-3cd8-11e5-9a49-001c4270714e:1'; #在session里設置gtid_next,即跳過這個GTID Query OK, 0 rows affected (0.01 sec)mysql> begin; #開啟一個事務 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設置回來 Query OK, 0 rows affected (0.00 sec)mysql> start slave; #開啟復制 Query OK, 0 rows affected (0.01 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: 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在此成功跳過了錯誤,同步繼續。可以通過這個辦法來處理復制失敗的問題,這里還有個例子,有興趣的可以看一下(從服務器中跳過一條語句/事務):
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 原本是正常的, 然后意外地執行了 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有延遲, 雖然已經獲取到了gtid及對應的events, 但是并未執行: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語句 。 辦法就是設置GTID_NEXT,然后提交一個空的事務。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)查看復制狀態 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, 當然此時主從的數據已經不一致了。注意:通過GTID的復制都是沒有指定MASTER_LOG_FILE和MASTER_LOG_POS的,所以通過GTID復制都是從最先開始的事務開始,除非在自己的binlog里面有執行過之前的記錄,才會繼續后面的執行。
②?要是事務日志被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登陸之后執行: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的部分,而不是在最先開始的事務執行。
在主上執行,查看被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)在從上執行,跳過這個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)要是出現: ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty. 則需要執行: 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)③ 通過另一個從庫恢復從庫數據
比如一臺從庫誤操作,數據丟失了,可以通過另一個從庫來進行恢復:
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(本身實例執行的事務) 4e659069-3cd8-11e5-9a49-001c4270714e:1-46Auto_Position: 1數據被誤刪除之后,最好停止復制:stop slave;恢復數據從slave1(3307)上備份數據,并還原到slave2(3308)中。 備份: mysqldump -uzjy -p123456 -h127.0.0.1 -P3307 --default-character-set=utf8 --set-gtid-purged=ON -B mmm > mmm1.sql在還原到slave2的時候需要在slave2上執行: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)這時候你會發現誤刪除的數據已經被還原,并且復制也正常。因為根據GTID的原理,通過slave1的備份直接可以和Master進行同步。這里備份注意的一點是:在備份開啟GTID的實例里,需要指定?--set-gtid-purged參數,否則會報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備份文件里面會出現:
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參數,出現GTID_PURGED,直接還原的時候執行,從庫不需要其他操作就可以直接change到主。關于GTID更多的信息可以到官方文檔里查看。?
總結:
? ? ??GTID就是全局事務ID(global transaction identifier ),最初由google實現,官方MySQL在5.6才加入該功能。要是主從結構只有一臺Master和一臺Slave對于GTID來說就沒有優勢了,而對于2臺主以上的結構優勢異常明顯,可以在數據不丟失的情況下切換新主。
? ? ? 使用GTID需要注意的是:在構建主從復制之前,在一臺將成為主的實例上進行一些操作(如數據清理等),通過GTID復制,這些在主從成立之前的操作也會被復制到從服務器上,引起復制失敗。即:通過GTID復制都是從最先開始的事務日志開始,即使這些操作在復制之前執行。比如在server1上執行一些drop、delete的清理操作,接著在server2上執行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
?
總結
以上是生活随笔為你收集整理的MySQL5.6 新特性之GTID【转】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 71文件类型
- 下一篇: 阿特斯携手EDF启动建设巴西191.5M