主從延遲調優思路

GreatSQL發表於2024-04-15

主從延遲調優思路

1、什麼是主從延遲?

本質是從庫的回放跟不上主庫,回放階段的延遲

file

2、主從延遲常見的原因有哪些?

1、大事務,從庫回放時間較長,導致主從延遲

2、主庫寫入過於頻繁,從庫回放跟不上

3、引數配置不合理

4、主從硬體差異

5、網路延遲

6、表沒有主鍵或者索引大量頻繁的更新

7、一些讀寫分離的架構,從庫的壓力比較大

3、解決主從延遲有哪些方法

1、對於大事務,拆分成小事務

2、開啟並行複製

3、升級從庫硬體

4、儘量都有主鍵

4、什麼是並行複製,引數有哪些?

回顧MySQL並行複製的路程

MySQL5.6 是基於資料庫級別的並行複製

slave-parallel-type=DATABASE(不同庫的事務,沒有鎖衝突)

file

MySQL5.7 基於group commit的並行複製

slave-parallel-type=LOGICAL_CLOCK : Commit-Parent-Based模式(同一組的事務[last-commit相同]沒有鎖衝突. 同一組,肯定沒有衝突,否則沒辦法成為同一組)

上面是從庫的配置,並行複製依賴於主庫的組提交(注意區分組複製)

greatsql> show variables like '%group%delay%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
+-----------------------------------------+-------+
2 rows in set (0.01 sec)
  • binlog_group_commit_sync_delay:等待多少時間後才進行組提交

  • binlog_group_commit_sync_no_delay_count:等待多少個事務後才進行組提交

以上引數都依賴於主庫業務繁忙的情況下,如果業務不頻繁,就會很尷尬

  • binlog_group_commit_sync_no_delay_count:這個引數設定成2個

比如只有一個執行緒執行一個事務,第二個事務在24h之後執行,那麼這個事務需要等待24h才能提交,十分坑

  • binlog_group_commit_sync_delay

假如設定成200ms,只有一個執行緒執行一個事務,本來10ms可以提交,還必須等待200ms才可以

線上一般是兩個都設定,舉個例子,就像是小船運人過河

假設我們的引數這麼設定:

binlog_group_commit_sync_delay=200;
binlog_group_commit_sync_no_delay_count=2

要麼滿足200ms直接走,要麼滿足2個人直接走,這麼人性化了很多,但是在業務不繁忙的情況下依然尷尬

file

MySQL8.0 基於write-set的並行複製

基於主鍵的衝突檢測(binlog_transaction_depandency_tracking = COMMIT_ORDERE|WRITESET|WRITESET_SESSION, 修改的row的主鍵或非空唯一鍵沒有衝突,即可並行)

事務檢測演算法:transaction_write_set_extraction = XXHASH64

MySQL會有一個變數來儲存已經提交的事務HASH值,所有已經提交的事務所修改的主鍵(或唯一鍵)的值經過hash後都會與那個變數的集合進行對比,來判斷改行是否與其衝突,並以此來確定依賴關係

這裡說的變數,可以透過這個設定大小:binlog_transaction_dependency_history_size

這樣的粒度,就到了 row 級別了,就是此時並行的粒度更加精細,並行的速度會更快,某些情況下,說slave的並行度超越master也不為過(master是單執行緒的寫,slave也可以並行回放)

簡單來說就是基於行去並行回放,rc級別下不同的行不會有鎖衝突

組提交的表現:

看主庫binlog的last_committed值是否一致,一致就可以並行回放,不一致只能序列

file

5、實戰分析

5.1 檢視線上主從延遲

Seconds_Behind_Master: 48828

可見延遲很高,接近14個小時,此時主庫也在不斷的寫資料,大概是6分鐘一個binlog,一個為500M

5.2 檢視當前的複製配置

檢視從庫配置:

greatsql> show variables like '%slave%para%';
+------------------------+---------------+
| Variable_name      | Value     |
+------------------------+---------------+
| slave_parallel_type   | LOGICAL_CLOCK |
| slave_parallel_workers | 128      |
+------------------------+---------------+
2 rows in set (0.02 sec)

延遲現象:

從庫一直在追,說明不是大事務,但是Seconds_Behind_Master延遲一直在增長

Retrieved_Gtid_Set: 00000000-0000-0024-0046-41a8003b4b99:242966351-253068975,
00000000-0000-0040-0095-5fff003b4b99:91056629-110569633,
00000000-0000-005c-0ced-7bae003b4b99:150292055-160253193,
31f4399f-ade5-11ed-a544-00163ebdeb51:1-12,
​      Executed_Gtid_Set: 00000000-0000-0024-0046-41a8003b4b99:1-252250235,
00000000-0000-0040-0095-5fff003b4b99:1-109120315,
00000000-0000-005c-0ced-7bae003b4b99:1-159504296,
31f4399f-ade5-11ed-a544-00163ebdeb51:1-12,
​        Auto_Position: 1

此時懷疑並沒有並行複製,主庫可能沒設定組提交(只是一個猜想)

5.3 進一步驗證,檢視主庫的binlog

檢視主庫的引數配置:還是為組提交的規則

greatsql> show variables like '%binlog_transac%';
+--------------------------------------------+----------+
| Variable_name                              | Value    |
+--------------------------------------------+----------+
| binlog_transaction_compression             | OFF      |
| binlog_transaction_compression_level_zstd  | 3        |
| binlog_transaction_dependency_history_size | 25000    |
| binlog_transaction_dependency_tracking     | WRITESET |
+--------------------------------------------+----------+
4 rows in set (0.02 sec)

再看其組提交的配置:表示沒有開組提交

greatsql> show variables like '%group%delay%';
+-----------------------------------------+-------+
| Variable_name                           | Value |
+-----------------------------------------+-------+
| binlog_group_commit_sync_delay          | 0     |
| binlog_group_commit_sync_no_delay_count | 0     |
+-----------------------------------------+-------+
2 rows in set (0.01 sec)

進一步驗證,看其binlog,發現果然last_committed都不一樣,表示不能並行

file

5.4 主庫設定引數,再次解析其binlog

binlog_transaction_dependency_tracking改為WRITESET模式

greatsql> show variables like '%transaction%';
+----------------------------------------------------------+-----------------+
| Variable_name                                            | Value           |
+----------------------------------------------------------+-----------------+
| binlog_direct_non_transactional_updates                  | OFF             |
| binlog_transaction_compression                           | OFF             |
| binlog_transaction_compression_level_zstd                | 3               |
| binlog_transaction_dependency_history_size               | 25000           |
| binlog_transaction_dependency_tracking                   | WRITESET        |
| kill_idle_transaction                                    | 300             |
| performance_schema_events_transactions_history_long_size | 10000           |
| performance_schema_events_transactions_history_size      | 10              |
| replica_transaction_retries                              | 10              |
| session_track_transaction_info                           | OFF             |
| slave_transaction_retries                                | 10              |
| transaction_alloc_block_size                             | 8192            |
| transaction_allow_batching                               | OFF             |
| transaction_isolation                                    | REPEATABLE-READ |
| transaction_prealloc_size                                | 4096            |
| transaction_read_only                                    | OFF             |
| transaction_write_set_extraction                         | XXHASH64        |
+----------------------------------------------------------+-----------------+
17 rows in set (0.00 sec)

再次檢視其binlog,看到有很多都可以並行回放

file

5.5 最佳化完成

即使主庫在大批次的寫入,但延遲正在慢慢縮減,追上只是時間問題,今天就是0了

file


Enjoy GreatSQL 😃

關於 GreatSQL

GreatSQL是適用於金融級應用的國內自主開源資料庫,具備高效能、高可靠、高易用性、高安全等多個核心特性,可以作為MySQL或Percona Server的可選替換,用於線上生產環境,且完全免費併相容MySQL或Percona Server。

相關連結: GreatSQL社群 Gitee GitHub Bilibili

GreatSQL社群:

社群部落格有獎徵稿詳情:https://greatsql.cn/thread-100-1-1.html

image-20230105161905827

技術交流群:

微信:掃碼新增GreatSQL社群助手微信好友,傳送驗證資訊加群

image-20221030163217640

相關文章