【MySQL】5.7新特性之七
寫在前面
本系列文章基於 5.7.12 版本講述MySQL的新特性。從安裝,檔案結構,SQL ,優化 ,運維層面 複製,GITD等幾個方面展開介紹 5.7 的新特性和功能。同時也建議大家跟蹤官方blog和官方文件,以儘快知悉其新的變化。本文主要研究5.7 複製方面的改進和優化。
7.1 Lock_log 鎖優化
主從複製過程中,拉取主庫的binlog 的時候有一把大鎖 , 在 5.7.12 之前,dump thread讀取binlog event事件的時候會持有鎖,最嚴重的是client 的寫入和dump thread讀取binlog 是互斥的,帶來兩個嚴重的問題
a 在MySQL中,寫入與讀取binlog使用的是同一把鎖(Lock_log),頻繁的讀取binlog,會加劇Lock_log衝突,影響主庫執行,進而造成TPS降低或抖動;
b 當備庫數量較多時,備庫拉取binlog會佔用過多的頻寬,影響應用的響應時間。
5.7.12 以及之後的版本MySQL對該鎖機制進行優化,只有在最後一次寫入log event成功之讀取位點的時候才持有該鎖。這項優化意味著併發讀取binlog 成為可能,並且dump thread 讀取binlog的時候,client可以同時寫入binlog。
7.2 半同步增強
5.6 的semi sync 在一定程度上保障了主從資料的一致性和可靠性。在Semisynchronous Replication模式下,在主庫上提交一個事務/event,它會等待至少一個slave通知主庫,slave 已經接收到傳遞過來的events並寫入relay log,才返回給回話層寫入成功,或者直到傳送日誌發生超時,
而且這期間主庫的會話只能等帶,所以在上線semi sync複製的時候 很多人都會考慮效能的下降問題。5.7版本中MySQL對此做了極大的改善,增加了ack thread 和AFTER_COMMIT 模式。
5.6版本的半同步邏輯
5.7版本的半同步邏輯
在增加ACK thread 之後,主庫提交事務之後,當前會話可以進行處理其他請求,由ack thread 來負責slave傳送回來的確認,極大的提高主庫的寫入效能。
b 無資料丟失
5.6 版本的預設是AFTER_COMMIT 模式
AFTER_COMMIT:某個會話在主庫提交事務,主庫將提交的事務持久化到儲存引擎和binlog並且同步給slave,主庫等待slave將接收的持久化到relay-log,並返回確認資訊給主庫,一旦主庫收到從庫的資訊就返回OK給客戶端。在此期間會話是不能進行下一步操作的。
AFTER_SYNC (the default): 5.7 開發了新的模式,會話提在主庫上提交事務,主庫會記錄binlog 並且同步給slave ,等待事務在slave落盤記錄到relay-log中並返回ack資訊。
特別強調此時事務還未commit,故其他會話是看不到修改的記錄,這點和after_commited 不一樣。一旦主庫收到從庫的資訊,主庫就提交該事務並且返回OK給客戶端。
#這裡分析的不嚴謹,待討論 ##
7.3 GTID功能增強
大家比較熟悉 5.6 版本的GTID功能和作用,簡化複製和降低主從複製維護的難度,提高複製的可運維性,不再依賴Master的binlog檔名和檔案中的位置。
但是它有很多限制,5.7版本MySQL支援對GTID做了如下改進
a 不需要重啟MySQL伺服器.
b 配置過程線上,整個複製叢集仍然對外提供讀和寫的服務.
c 不需要改變複製拓撲結構.
d 可以在任何結構的複製叢集中線上啟用GTID功能.
線上修改GTID時,必須按照如下順序 OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON,不能跳過其中環節,比如 gtid_mode 從off 不能直接變為on,否則MySQL會進行提示。
這裡需要對5.7版本的GTID_MODE 進行說明
舉個例子演示開啟gtid
整個過程slave 的例項不用重啟,可以持續對外提供服務。是不是可以提升DBA的幸福感了呢?
7.4 多源複製
5.7 版本之前的主從複製結構一般有一主一從,一主多從,雙主(雙向複製)等,不支援多主一從。5.7 版本提供多主複製:新引入 channel 的概念,每個channel
就是一個slave,有各自獨立的io_thread 和sql_thread ,除此之外複製的原理和 5.6 版本的主從複製原理一致。使用多源複製可以提高從庫的利用率,在一定程度上解決分片資料查詢統計困難的情況。
需要特別指出的是,
a 多源複製不支援檔案記錄binlog位點,必須啟用
master_info_repository = 'TABLE';relay_log_info_repository = 'TABLE';
b 使用多源複製要避免不同的主庫出現同名的庫,否則在複製時會發生錯誤。
7.5 並行複製
在MySQL 複製機制大致原理是:slave 通過io_thread 將主庫的binlog拉到從庫並寫入relay log,由SQL THREAD 讀出來relay log並進行重放。當主庫寫入併發寫入壓力很大,也即N:1的情形,slave 會出現延遲。
MySQL 5.6 版本提供並行複製功能,slave複製相關的執行緒由 io_thread,coordinator_thread,worker構成,其中 coordinator_thread 負責讀取 relay log,將讀取的binlog event以事務為單位分發到各個 worker thread 進行執行,並在必要時執行binlog event,比如是DDL 或者跨庫事務的時候。
worker_thread:執行分配到的binlog event,各個執行緒之間互不影響,具體worker_thread 的個數由slave_parallel_workers決定。
需要注意的是 dbname 與 worker 執行緒的繫結資訊在一個hash表中進行維護,hash表以entry為單位,entry中記錄當前entry所代表的資料庫名,有多少個事務相關的已被分發,執行這些事務的worker thread等資訊;
分配執行緒是以資料庫名進行分發的,當一個例項中只有一個資料庫的時候,不會對效能有提高,相反,由於增加額外的操作,效能還會有一點回退;
MySQL 5.7 版本提供基於組提交的並行複製,通過設定引數slave_parallel_workers>0 並且 global.slave_parallel_type='LOGICAL_CLOCK'啟用基於並行複製。
即主庫在ordered_commit中的第二階段的時候,將同一批commit的 binlog 打上一個相同的seqno標籤,同一時間戳的事務在備庫是可以同時執行的,因此大大簡化了並行複製的邏輯,並打破了相同 DB 不能並行執行的限制。備庫在執行時,具有同一seqno的事務在備庫可以並行的執行,互不干擾,也不需要繫結資訊,後一批seqno的事務需要等待前一批相同seqno的事務執行完後才可以執行。這樣的實現方式大大提高了slave 應用relaylog的速度。
推薦文章
《官方文件介紹》
MySQL 5.7並行複製實現原理與調優
MySQL核心月報 2015.01
7.6 支援線上維護replication filer
5.6 以及之前的版本在需要修改複製過濾相關配置的時候必須在配置檔案中修改,然後重啟資料庫才能生效。5.7採用了更加靈活的方式支援線上配置過濾規則。在配置過濾規則之前必須關閉 sql_thread 或者stop slave;
這裡以 REPLICATE_IGNORE_DB 為例,演示線上修改和取消REPLICATE_IGNORE_DB的具體操作。
取消過濾規則,只需將引數設定為空即可
這裡注意的是與Oracle spfile 不一樣,雖然MySQL支援線上修改但是它不支援同時寫入到my.cnf檔案,如果讀者朋友線上修改了,請務必配置在my.cnf檔案中,避免重啟失效。
參考資料
[1]《非同步複製官方文件》
[2]《MySQL核心月報》
[3]《MySQL 5.7 深度解析: 半同步複製技術》
[4]《MySQL 5.7 Replication 相關》
本系列文章基於 5.7.12 版本講述MySQL的新特性。從安裝,檔案結構,SQL ,優化 ,運維層面 複製,GITD等幾個方面展開介紹 5.7 的新特性和功能。同時也建議大家跟蹤官方blog和官方文件,以儘快知悉其新的變化。本文主要研究5.7 複製方面的改進和優化。
7.1 Lock_log 鎖優化
主從複製過程中,拉取主庫的binlog 的時候有一把大鎖 , 在 5.7.12 之前,dump thread讀取binlog event事件的時候會持有鎖,最嚴重的是client 的寫入和dump thread讀取binlog 是互斥的,帶來兩個嚴重的問題
a 在MySQL中,寫入與讀取binlog使用的是同一把鎖(Lock_log),頻繁的讀取binlog,會加劇Lock_log衝突,影響主庫執行,進而造成TPS降低或抖動;
b 當備庫數量較多時,備庫拉取binlog會佔用過多的頻寬,影響應用的響應時間。
5.7.12 以及之後的版本MySQL對該鎖機制進行優化,只有在最後一次寫入log event成功之讀取位點的時候才持有該鎖。這項優化意味著併發讀取binlog 成為可能,並且dump thread 讀取binlog的時候,client可以同時寫入binlog。
7.2 半同步增強
5.6 的semi sync 在一定程度上保障了主從資料的一致性和可靠性。在Semisynchronous Replication模式下,在主庫上提交一個事務/event,它會等待至少一個slave通知主庫,slave 已經接收到傳遞過來的events並寫入relay log,才返回給回話層寫入成功,或者直到傳送日誌發生超時,
而且這期間主庫的會話只能等帶,所以在上線semi sync複製的時候 很多人都會考慮效能的下降問題。5.7版本中MySQL對此做了極大的改善,增加了ack thread 和AFTER_COMMIT 模式。
5.6版本的半同步邏輯
5.7版本的半同步邏輯
在增加ACK thread 之後,主庫提交事務之後,當前會話可以進行處理其他請求,由ack thread 來負責slave傳送回來的確認,極大的提高主庫的寫入效能。
b 無資料丟失
5.6 版本的預設是AFTER_COMMIT 模式
AFTER_COMMIT:某個會話在主庫提交事務,主庫將提交的事務持久化到儲存引擎和binlog並且同步給slave,主庫等待slave將接收的持久化到relay-log,並返回確認資訊給主庫,一旦主庫收到從庫的資訊就返回OK給客戶端。在此期間會話是不能進行下一步操作的。
-
比如主庫操作update t1 set val=1 where id=10 將val 從5修改為1 。
-
1 會話session1 在主庫提交
-
update t1 set val=1 where id=10 ;commit;
-
2 主庫根據二階段提交將資料持久化到innodb和提交日誌binlog
-
3 同步日誌到 slave ,並等待slave 返回ack資訊,等待的實際時間以 rpl_semi_sync_master_timeout 為準,超過該設定時間則超時,主庫返回給客戶端成功寫入資訊。
-
4 接收到來自slave 的ack 資訊,返回成功給OK 客戶端。
-
分析:
-
第四步之前,master還未收到slave 的ack 資訊,此時由於事務已經提交,除了當前會話,其他會話是可以看到val=1 。此時發生HA切換,主庫伺服器down或者主庫例項crash
-
主庫未接收到slave的ack資訊, slave接收到日誌並落盤,應用binlog 把t1.val 更新為1 ,此時業務切換到slave上能獲取到一致的資料。
- 如果在 slave 還未接收到binlog 並且主庫掛了,因為主庫已經提交,此時主庫t1.val 是1而從庫t1.val 是5 ,主備不一致。
特別強調此時事務還未commit,故其他會話是看不到修改的記錄,這點和after_commited 不一樣。一旦主庫收到從庫的資訊,主庫就提交該事務並且返回OK給客戶端。
-
比如主庫操作update t1 set val=1 where id=10 將val 從5修改為1 。
-
1 會話session1 在主庫提交
-
update t1 set val=1 where id=10 ;commit;
-
2 主庫將事務寫入binlog,將binlog同步給slave,不提交。
-
3 等待slave 返回ack資訊,等待的實際時間以 rpl_semi_sync_master_timeout 為準,如果超時 則回滾該事務。
-
4 接收到來自slave 的ack 資訊,主庫進行提交併且返回成功給OK 客戶端。
-
分析
- 如果在第3步等待slave ack的過程中,主庫發生crash(此時t1.val=5),HA 切換到slave,應用查詢slave 。如果slave 接收到binlog併傳送ack給master,則t1.val=1。如果slave未接收到事務和響應主庫,此時t1.val=5,無論哪種狀態,對於所有客戶端資料庫都是一致,事務都沒有丟失。
7.3 GTID功能增強
大家比較熟悉 5.6 版本的GTID功能和作用,簡化複製和降低主從複製維護的難度,提高複製的可運維性,不再依賴Master的binlog檔名和檔案中的位置。
但是它有很多限制,5.7版本MySQL支援對GTID做了如下改進
a 不需要重啟MySQL伺服器.
b 配置過程線上,整個複製叢集仍然對外提供讀和寫的服務.
c 不需要改變複製拓撲結構.
d 可以在任何結構的複製叢集中線上啟用GTID功能.
線上修改GTID時,必須按照如下順序 OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON,不能跳過其中環節,比如 gtid_mode 從off 不能直接變為on,否則MySQL會進行提示。
- ERROR 1788 (HY000): The value of @@GLOBAL.GTID_MODE can only be changed one step at a time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that this value must be stepped up or down simultaneously on all servers. See the Manual for instructions.
-
OFF :不產生GTID,Slave只接受不帶GTID的事務
-
OFF_PERMISSIVE :不產生GTID,Slave即接受不帶GTID的事務,也接受帶GTID的事務
-
ON_PERMISSIVE :產生GTID,Slave即接受不帶GTID的事務,也接受帶GTID的事務
- ON :產生GTID,Slave只能接受帶GTID的事務。
-
mysql> set global gtid_mode=on;
-
ERROR 1788 (HY000): The value of @@GLOBAL.GTID_MODE can only be changed one step at a time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that this value must be stepped up or down simultaneously on all servers. See the Manual for instructions.
-
mysql> set global gtid_mode=OFF_PERMISSIVE;
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> set global gtid_mode=ON_PERMISSIVE;
-
Query OK, 0 rows affected (0.02 sec)
-
mysql> set global gtid_mode=ON; 開啟gtid之前 ,必須設定enforce_gtid_consistency=on
-
ERROR 3111 (HY000): SET @@GLOBAL.GTID_MODE = ON is not allowed because ENFORCE_GTID_CONSISTENCY is not ON.
-
mysql> set global enforce_gtid_consistency=on;
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> set global gtid_mode=ON;
- Query OK, 0 rows affected (0.01 sec)
7.4 多源複製
5.7 版本之前的主從複製結構一般有一主一從,一主多從,雙主(雙向複製)等,不支援多主一從。5.7 版本提供多主複製:新引入 channel 的概念,每個channel
就是一個slave,有各自獨立的io_thread 和sql_thread ,除此之外複製的原理和 5.6 版本的主從複製原理一致。使用多源複製可以提高從庫的利用率,在一定程度上解決分片資料查詢統計困難的情況。
需要特別指出的是,
a 多源複製不支援檔案記錄binlog位點,必須啟用
master_info_repository = 'TABLE';relay_log_info_repository = 'TABLE';
b 使用多源複製要避免不同的主庫出現同名的庫,否則在複製時會發生錯誤。
7.5 並行複製
在MySQL 複製機制大致原理是:slave 通過io_thread 將主庫的binlog拉到從庫並寫入relay log,由SQL THREAD 讀出來relay log並進行重放。當主庫寫入併發寫入壓力很大,也即N:1的情形,slave 會出現延遲。
MySQL 5.6 版本提供並行複製功能,slave複製相關的執行緒由 io_thread,coordinator_thread,worker構成,其中 coordinator_thread 負責讀取 relay log,將讀取的binlog event以事務為單位分發到各個 worker thread 進行執行,並在必要時執行binlog event,比如是DDL 或者跨庫事務的時候。
worker_thread:執行分配到的binlog event,各個執行緒之間互不影響,具體worker_thread 的個數由slave_parallel_workers決定。
需要注意的是 dbname 與 worker 執行緒的繫結資訊在一個hash表中進行維護,hash表以entry為單位,entry中記錄當前entry所代表的資料庫名,有多少個事務相關的已被分發,執行這些事務的worker thread等資訊;
分配執行緒是以資料庫名進行分發的,當一個例項中只有一個資料庫的時候,不會對效能有提高,相反,由於增加額外的操作,效能還會有一點回退;
MySQL 5.7 版本提供基於組提交的並行複製,通過設定引數slave_parallel_workers>0 並且 global.slave_parallel_type='LOGICAL_CLOCK'啟用基於並行複製。
即主庫在ordered_commit中的第二階段的時候,將同一批commit的 binlog 打上一個相同的seqno標籤,同一時間戳的事務在備庫是可以同時執行的,因此大大簡化了並行複製的邏輯,並打破了相同 DB 不能並行執行的限制。備庫在執行時,具有同一seqno的事務在備庫可以並行的執行,互不干擾,也不需要繫結資訊,後一批seqno的事務需要等待前一批相同seqno的事務執行完後才可以執行。這樣的實現方式大大提高了slave 應用relaylog的速度。
-
mysql> show variables like 'slave_parallel%';
-
+------------------------+----------+
-
| Variable_name | Value |
-
+------------------------+----------+
-
| slave_parallel_type | DATABASE |#預設是DATABASE 模式的,需要調整或者在my.cnf中配置
-
| slave_parallel_workers | 4 |
-
+------------------------+----------+
-
2 rows in set (0.00 sec)
-
mysql> STOP SLAVE SQL_THREAD;
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> set global slave_parallel_type='LOGICAL_CLOCK';
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> START SLAVE SQL_THREAD;
-
Query OK, 0 rows affected (0.01 sec)
-
啟用並行複製之後檢視processlist,系統多了四個執行緒 Waiting for an event from Coordinator .
-
mysql> show processlist;
-
+----+-------------+-----------------+------+---------+------+--------------------------------------------------------+------------------+
-
| Id | User | Host | db | Command | Time | State | Info |
-
+----+-------------+-----------------+------+---------+------+--------------------------------------------------------+------------------+
-
| 9 | root | localhost:40270 | NULL | Query | 0 | starting | show processlist |
-
| 10 | system user | | NULL | Connect | 1697 | Waiting for master to send event | NULL |
-
| 31 | system user | | NULL | Connect | 5 | Slave has read all relay log; waiting for more updates | NULL |
-
| 32 | system user | | NULL | Connect | 5 | Waiting for an event from Coordinator | NULL |
-
| 33 | system user | | NULL | Connect | 5 | Waiting for an event from Coordinator | NULL |
-
| 34 | system user | | NULL | Connect | 5 | Waiting for an event from Coordinator | NULL |
-
| 35 | system user | | NULL | Connect | 5 | Waiting for an event from Coordinator | NULL |
-
+----+-------------+-----------------+------+---------+------+--------------------------------------------------------+------------------+
- 7 rows in set (0.00 sec)
《官方文件介紹》
MySQL 5.7並行複製實現原理與調優
MySQL核心月報 2015.01
7.6 支援線上維護replication filer
5.6 以及之前的版本在需要修改複製過濾相關配置的時候必須在配置檔案中修改,然後重啟資料庫才能生效。5.7採用了更加靈活的方式支援線上配置過濾規則。在配置過濾規則之前必須關閉 sql_thread 或者stop slave;
這裡以 REPLICATE_IGNORE_DB 為例,演示線上修改和取消REPLICATE_IGNORE_DB的具體操作。
-
mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=(yang);
-
ERROR 3017 (HY000): This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL_THREAD first
-
mysql> STOP SLAVE SQL_THREAD;
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=(yang,youzan);
- Query OK, 0 rows affected (0.00 sec)
取消過濾規則,只需將引數設定為空即可
-
mysql> STOP SLAVE SQL_THREAD;
-
Query OK, 0 rows affected (0.01 sec)
-
mysql> CHANGE REPLICATION FILTER REPLICATE_IGNORE_DB=();
-
Query OK, 0 rows affected (0.00 sec)
-
mysql> start SLAVE SQL_THREAD;
- Query OK, 0 rows affected (0.01 sec)
參考資料
[1]《非同步複製官方文件》
[2]《MySQL核心月報》
[3]《MySQL 5.7 深度解析: 半同步複製技術》
[4]《MySQL 5.7 Replication 相關》
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-2133818/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- #MySQL# mysql5.7新特性之半同步複製MySql
- MySQL5.7新特性之備份工具mysqlpump的使用MySql
- MySQL 5.7新特性之線上收縮undo表空間MySql
- MySQL 5.7 新特性大全和未來展望MySql
- MySQL 5.7 學習心得之安全相關特性MySql
- MySQL 5.6, 5.7, 8.0版本的新特性彙總大全MySql
- MySQL 8 新特性之Clone PluginMySqlPlugin
- MySQL 8 新特性之Invisible IndexesMySqlIndex
- MySQL5.7 group by新特性報錯1055的解決辦法MySql
- MySQL 5.7 新特性 共享臨時表空間及臨時表改進MySql
- MySQL 8.0 新特性MySql
- MySQL5.6新特性之Multi-Range ReadMySql
- MySQL基礎之MySQL 5.7 新增配置MySql
- MySQL 5.7主從新增新從庫MySql
- MySQL5.7之auto_increment回溯MySqlREM
- MySQL 8 新特性之自增主鍵的持久化MySql持久化
- mysql5.1的新特性MySql
- MySQL8.0-新特性-DescendingIndexMySqlIndex
- MySQL 8 新特性之持久化全域性變數的修改MySql持久化變數
- MySQL-18 MySQL8其他新特性MySql
- MySQL 5.7新支援--通用表空間實戰MySql
- mysql8.0.11新特性測試MySql
- MySQL8.0-新特性彙總MySql
- MySQL 8.0 新特性梳理彙總MySql
- 【MySQL】死鎖案例之七MySql
- Java 10 新特性之 AppCDSJavaAPP
- Mysql8.0部分新特性MySql
- MySQL8.0 新特性 top10MySql
- MySQL 8部分新特性(8.0.17)MySql
- mysql8.0新特性--隱藏索引MySql索引
- MySQL9的3個新特性MySql
- 一文看完MySQL 9.0新特性!MySql
- Install MySQL 5.7 in the DockerMySqlDocker
- Docker 部署 mysql 5.7DockerMySql
- Java 8 新特性之方法引用Java
- IOS11新特性之maskedCornersiOS
- iOS 8 之後UINavigationController新特性iOSUINavigationController
- ES6 新特性之SymbolSymbol
- JDK8新特性之stream()JDK