MySQL主從複製之基於GTID及多執行緒
一、Mysql 5.6 複製管理工具
官方下載:http://dev.mysql.com/downloads/tools/utilities/#downloads
mysqlreplicate 快速啟動複製
mysqlrplcheck 快速檢查複製環境
mysqlrplshow 顯示覆制拓撲
mysqlfailover 故障轉移
mysqlrpladmim 管理工具
二、GTID詳解
MySQL 5.6 的新特性之一,是加入了全域性事務 ID (GTID) 來強化資料庫的主備一致性,故障恢復,以及容錯能力。
官方文件:http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html
GTID(Global Transaction Identifier)稱為全域性事務標示符,是由mysql伺服器自動管理的在原始master上提交事務時被建立。GTID需要在全域性的主-備拓撲結構中保持唯一性,每一個 GTID 代表一個數據庫事務。GTID由兩部分組成: GTID = source_id:transaction_id
source_id: 用於標示源伺服器,用server_uuid來表示,在首次啟動時 MySQL 會呼叫 generate_server_uuid() 自動生成一個 server_uuid,並且儲存到MySQL資料目錄下auto.cnf中,MySQL 5.6 用 128 位的 server_uuid 代替了原本的 32 位 server_id 的大部分功能,全域性唯一的 server_uuid 的一個好處是:可以解決由 server_id 配置衝突帶來的 MySQL 主備複製的異常終止(BUG #33815?)在MySQL 5.6,Slave 向 Master 申請 binlog 時,會首先發送自己的 server_uuid,Master用Slave傳送的server_uuid代替server_id 作為 kill_zombie_dump_threads 的引數,終止衝突或者僵死的 BINLOG_DUMP 執行緒。
transaction_id: 則是根據在源伺服器上第幾個提交的事務來確定。transaction_id 是一個從 1 開始的自增計數,表示在這個主庫上執行的第 n 個事務。MySQL 會保證事務與 GTID 之間的 1 : 1 對映。
GTID的生命週期:
- 事務在主庫上執行並提交給事務分配一個GTID(由主庫的uuid和該伺服器上未使用的最小事務序列號),該GTID被寫入到binlog中。
- 備庫讀取relaylog中的GTID,並設定session級別的GTID_NEXT的值,以告訴備庫下一個事務必須使用這個值
- 備庫檢查該GTID是否已經被其使用並記錄到他自己的binlog中。slave需要擔保之前的事務沒有使用這個gtid,也要擔保此時已讀取GTID,但未提交的事務也不能使用這個GTID.
- 由於GTID_NEXT非空,slave不會去生成一個新的GTID,而是使用從主庫獲得的GTID。這可以保證在一個複製拓撲中的同一個事務GTID不變。
由於GTID在全域性的唯一性,通過GTID,可以在自動切換時對一些複雜的複製拓撲很方便的提升新主庫及新備庫,例如通過指向特定的GTID來確定新備庫複製座標。當然,使用GTID也有一些限制:
- 事務中的更新包含非事務性儲存引擎,這可能導致多個GTID分配給同一個事務。
- create table…select語句不被支援,因為該語句會被拆分成create table 和insert兩個事務,並且這個兩個事務被分配了同一個GTID,這會導致insert被備庫忽略掉。
- 不支援CREATE/DROP臨時表操作
可以看到,支援GTID的複製對一些語句都有一些限制,MySQL也提供了一個選項disable-gtid-unsafe-statements以禁止這些語句的執行。
多執行緒複製基於庫
MySQL 5.6之前的版本,同步複製是單執行緒的,佇列的,只能一個一個執行,在5.6裡,可以做到多個庫之間的多執行緒複製,例如資料庫裡,存放著使用者表,商品表,價格表,訂單表,那麼將每個業務表單獨放在一個庫裡,這時就可以做到多執行緒複製,但一個庫裡的表,多執行緒複製是無效的。
說明:事實上多執行緒是針對每個database開啟相應的獨立執行緒。即每個庫有一個單獨的(sql thread),如果線上業務中,只有一個database或者絕大多數壓力集中在個別database的話,多執行緒併發複製特性就沒有意義了(slave-parallel-workers=0 表示禁用多執行緒功能)。
舉例:
A為主BC為從時,BC複製速度會不同,則在A故障的那一刻,BC上的資料也會有不同,此時通過GTID的方式實現讓B成為一個新的Master,那麼在C上有的但B上沒有的資料都先要複製到B上,然後把B提升為Master,然後再讓C成為B的Slave,GTID追蹤會把記錄在二進位制中每個事務中首部都標示一個GTID號;此時B可向C發出通告,告知C自己已經完成了哪些事務,從而實現伺服器兩端自動的發現各自在對方上缺少的資料,而不需要再進行手動指定的binglog以及master_log_pos。
因此GTID能夠保證讓一個從伺服器到其他的從伺服器那裡實現資料複製而且能夠實現資料整合。GTID在分散式架構中可以保證資料的一致性。從而也實現了MySQL 的高可用性。預設情況下GTID將一個事務記錄進二進位制檔案時將首先記錄它的GTID,而且GTID和事務相關的資訊一併要傳送給從伺服器,由從伺服器在本地應用認證但是絕對不會改變原來的事務ID號。因此在GTID的架構上就算有了N層架構,複製是N級架構、事務ID依然不會改變;有效的保證了資料的完整和安全性。
GTID配置選項
要在MySQL 5.6中使用複製功能,其服務配置段[mysqld]中於少應該定義如下選項:
log-slave-updates(slave更新是否記入日誌)、gtid-mode(gtid型別)、enforce-gtid-consistency(強制gtid一致性)、report-port和report-host:用於啟動GTID及滿足附屬的其它需求;
binlog-format:二進位制日誌的格式,有row、statement和mixed3種類型;
注意:當設定隔離級別為讀提交READ-COMMITED必須設定二進位制日誌格式為ROW,現在MySQL官方認為STATEMENT這個已經不再適合繼續使用;但mixed型別在預設的事務隔離級別下,可能會導致主從資料不一致;
report-port: The TCP/IP port number for connecting to the slave, to be reported to the master during slave registration.
report-host: The host name or IP address of the slave to be reported to the master during slave registration. This value appears in the output of SHOW SLAVE HOSTS on the master server.
log_slave_updates: Whether updates received by a slave server from a master server should be logged to the slave’s own binary log. Binary logging must be enabled on the slave for this variable to have any effect.
log-bin:啟用二進位制日誌,這是保證複製功能的基本前提;
server-id:同一個複製拓撲中的所有伺服器的id號必須惟一;
sync-master-info:確保伺服器崩潰時無資訊丟失;
binlog-rows-query-log-events:用於在二進位制日誌詳細記錄事件相關的資訊,可降低故障排除的複雜度;
binlog-checksum 、master-verify-checksum、slave-sql-verify-checksum:啟用複製有關的所有校驗功能;
slave-paralles-workers:設定從伺服器的SQL執行緒數;0表示關閉多執行緒複製功能;值與要複製的資料庫數目相同即可;
master-info-repository(資源庫)和relay-log-info-repository:啟用此兩項,可用於實現在崩潰時保證二進位制及從伺服器安全的功能;
relay-log-info-repository: This option causes the server to log its relay log info to a file or a table.
master-info-repository: The setting of this variable determines whether the slave logs master status and connection information to a FILE (master.info), or to a TABLE (mysql.slave_master_info)
三、配置 MySQL Master&&Slave兩臺伺服器基於GTID實現主從複製
MySQL Master伺服器:10.33.100.88
MySQL Slave伺服器:10.33.100.99
實驗系統:CentOS6.4_x86_64+5.6.12 MySQL Community Server (GPL)
修改主伺服器配置檔案
[[email protected] ~]# vim /etc/my.cnf
[mysqld]
user=mysql
port=3306
datadir=/mnt/SQLdata
socket=/tmp/mysql.sock
server-id=1
report-port=3306 ##提供複製報告埠
report-host=10.33.100.88 ##提供複製報告主機
log-bin=Master-bin ##二進位制日誌檔案
binlog-format=ROW
log-slave-updates=true ##將slave更新是記入日誌
gtid-mode=on ##啟用gtid型別,否則就是普通的複製架構
enforce-gtid-consistency=true ##強制GTID的一致性
master-info-repository=TABLE ##主服器資訊記錄庫=表/檔案
relay-log-info-repository=TABLE ##中繼日誌資訊記錄庫
sync-master-info=1 ##同步主庫資訊
slave-parallel-workers=4 ##從伺服器的SQL執行緒數,每個資料庫僅能使用一個執行緒
binlog-checksum=CRC32 ##校驗碼
master-verify-checksum=1 ##主服校驗
slave-sql-verify-checksum=1 ##從服校驗
binlog-rows-query-log_events=1 ##二進位制日誌詳細記錄事件
重啟主伺服器mysqld服務,並檢視GTID相關資訊
檢視master status
檢視UUID
賦予從庫許可權賬號,允許使用者在主庫上讀取日誌
修改從伺服器配置檔案
[[email protected] ~]# vim /etc/my.cnf
[mysqld]
user=mysql
port=3306
datadir=/mnt/SQLdata
socket=/tmp/mysql.sock
server-id=11
report-port=3306
report-host=10.33.100.77
binlog-format=ROW
log-bin=Slave-bin
##可以不啟用二進位制日誌,但在架設HA的MySQL場景中必須啟用從服上二進位制日誌,在主服出現問題時,從服可以升級為主伺服器
relay_log=slave_relay
##如不定義中繼日誌在start slave時會報錯Slave failed to initialize relay log info structure from the repository
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
Slave連線Master
配置主從複製,5.6以前的版本,需要找到binlog和pos點,然後change master to指向,在mysql5.6裡啟用GTID後,只需要知道Master的IP、埠,賬號密碼即可,mysql會自動找點同步。
主從測試:剛才在配置檔案中定義了4個複製執行緒,Master上建立4個數據庫,每個資料庫事務啟動一個複製執行緒,這些複製執行緒可同時啟動;
[root@Master ~]# cd /mnt/SQLdata/
[root@Master SQLdata]# mysqlbinlog Master-bin.000001
在以上的GTID表示為唯一標識的 MySQL 上執行的第 6 個數據庫事務。很容易理解,MySQL 只要保證每臺數據庫的 server_uuid 全域性唯一,以及每臺數據庫生成的transaction_id 自身唯一,就能保證 GTID 的全域性唯一性。
MySQL預設開啟了自動提交事務,會導致大量的日誌,可關閉自動commit的功能(mysql>set autocommit=1)只有輸入commit,事務才提交.
再對資料庫做一些增刪查改的操作
Master上檢視Master狀態資訊和Slave狀態資訊
Slave上檢視狀態資訊
mysql> show slave status\G