MySQL5.6復制新特性
一、名詞解釋:
1:
server_uuid:服務器身份ID。在第一次啟動Mysql時,會自動生成一個server_uuid并寫入到數據目錄下auto.cnf文件里,官方不建議修改。
[root@mysql5_6 data]# pwd
/usr/local/mysql/data
[root@mysql5_6 data]# cat auto.cnf
[auto]
server-uuid=b0869d03-d4a9-11e1-a2ee-000c290a6b8f
2:
GTID:全局事務標識符。當開始這個功能時,每次事務提交都會在binlog里生成一個唯一的標示符,它由server_uuid和事務ID組成。首次提交的事務ID為1,第二次為2,第三次為3,依次類推。
查看主機master
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB Executed_Gtid_Set
binlog.000001 184761 D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-515
在binlog日志已經存在的D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-515值,如果有新進來的binlog日志中的gtid有和原來有重復,新進來的語句不執行。
二、新特性
1:支持多線程復制.事實上是針對每個database開啟相應的獨立線程。即每個庫有一個單獨的(sql thread)如果線上業務中,只有一個database或者絕大多數壓力集中在個別database的話,多線程并發復制特性就沒有意義了
2:啟用GTID,無須再知道binlog和POS點,需要知道master的IP、端口,賬號密碼即可,因為同步復制是自動的,mysql通過內部機制GTID自動找點同步
在my.cnf使用
gtid_mode = ON
disable-gtid-unsafe-statements = 1
注意:這兩個參數無法在線修改,只能在my.cnf修改。
三、問題:
GTID的局限性:
1.GTID同步復制是基于事務。所以Myisam表不支持,這可能導致多個GTID分配給同一個事務。
(5.6.9版本已經修改,支持修改Myisam表)
2.gtid_mode和disable-gtid-unsafe-statements必須同時使用,不同時使用,啟動Mysql報錯。
3.無法修改myisam表的數據,會提示Updates to non-transactional tables are forbidden when disable-gtid-unsafe-statements"
4.不支持CREATE TEMPORARY TABLE、DROP TEMPORARY TABLE 臨時表操作
5.不支持CREATE TABLE ... SELECT語句。因為該語句會被拆分成create table 和insert兩個事務,并且這個兩個事務被分配了同一個GTID,這會導致insert被備庫忽略掉
6.GTID是自動同步,復制的時候沒辦法使用全備份+偏移量日志這種辦法還原,從機的第一次同步只能從主機的第一個事務點開始還原,所以主機的 binlog日志必須保持完整,binlog日志不能丟失。(mysql手冊說mysql5.6.9以后的版本可以使用全備份+偏移量日志這種辦法還原,繼續等待mysql5.6.9出來后再測試)。
以上的問題是RC版,相信到了正式版出來后,問題會有很大的改善。
(5.6.9的測試結果支持全備份+偏移量日志,執行mysqldump命令的時候,在dmp文件中會記錄SET @@GLOBAL.GTID_PURGED='E6916BE4-4E3F-11E2-BBC7-000C29EE3F03:1-157',但是設置GTID_PURGED ,必須保證gtid_executed沒有設置過,執行reset master即可。)
四、測試步驟:
1:在my.cnf設置相應的參數
在master設置
log-bin = binlog
binlog_format = mixed
gtid_mode = ON
disable-gtid-unsafe-statements = 1
binlog_cache_size = 4M
max_binlog_size = 1G
max_binlog_cache_size = 2G
sync_binlog = 1
expire_logs_days = 1
在slave設置
#binlog
log-bin = binlog
binlog_format = mixed
gtid_mode = ON
disable-gtid-unsafe-statements = 1
binlog_cache_size = 4M
max_binlog_size = 1G
max_binlog_cache_size = 2G
sync_binlog = 1
expire_logs_days = 1
slave_parallel_workers #開啟基于庫的多線程復制。默認是0,不開啟,最大并發數為1024個線程
#relay log
max_relay_log_size = 1G
relay_log_purge = 1
relay_log_recovery = 1 #當被設置成ENABLED,在CRASH后自動放棄所有未執行的relay-log,并且重新從MASTER獲取日志;這樣保證relay-log的完整
#master_verify_checksum = 1 #主從復制事件校驗,master
#slave_sql_verify_checksum = 1 #主從復制事件校驗
#slave_allow_batching = 1
log_slave_updates
2:在slave執行
CHANGE MASTER TO
MASTER_HOST = '127.0.0.1',
MASTER_PORT = 3306,
MASTER_USER = 'rel',
MASTER_PASSWORD = '123',
MASTER_AUTO_POSITION = 1,
MASTER_DELAY=30; #延時30秒執行
注意:此參數功能,relay日志會及時同步到slave機,只是日志的中的事件會根據事件的時間戳延時30秒執行。此功能在實際場景中運用也較多。
3:啟動slave
start slave;
五、觀察結果:
在slave執行 show slave status \G;
觀察Retrieved_Gtid_Set和Executed_Gtid_Set項。
Retrieved_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:2602
Executed_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-2602
Retrieved_Gtid_Set項:記錄了relay日志從Master獲取了binlog日志的位置
Executed_Gtid_Set項:記錄本機執行的binlog日志位置(如果是從機,包括Master的binlog日志位置和slave本身的binlog日志位置)
預測:
Executed_Gtid_Set:從本機的binlog中獲取,如果binlong日志中記錄了主機的Gtid,那么即使我們在從機重新同步,從機的IO進程依然不會從主機獲取這些數據,
測試如下:
第一步:在slave執行:show slave stauts \G;
Retrieved_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-2601
Executed_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-2601
顯示的Slave從Master同步,relay獲取了執行了D68DBC47-3AAE-11E2-BC2F- 842B2B699BDA:1-2601,然后執行,在binglog日志中記錄了D68DBC47-3AAE-11E2-BC2F- 842B2B699BDA:1-2601。
第二步:在slave執行
1:stop slave;
2:reset slave;
3:刪除所有relay文件;
4:CHANGE MASTER TO
MASTER_HOST = '127.0.0.1',
MASTER_PORT = 3306,
MASTER_USER = 'rel',
MASTER_PASSWORD = '123',
MASTER_AUTO_POSITION = 1,
MASTER_DELAY=30;
5:start slave;
執行show slave status \G;
Retrieved_Gtid_Set:
Executed_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-2601
Retrieved_Gtid_Set項沒有值,說明重新同步的時候,relay沒有從master取數據。
第三步:在master執行一條sql語句
在slave執行show slave status \G;
Retrieved_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:2602
Executed_Gtid_Set: D68DBC47-3AAE-11E2-BC2F-842B2B699BDA:1-2602
觀測結果符合預期。