全部產品
Search
文件中心

PolarDB:防止唯讀節點上長事務阻塞DDL操作

更新時間:Dec 27, 2024

PolarDB支援參數polar_slave_work_on_nonblock_mdl_mode。開啟該參數後,可以防止PolarDB唯讀節點上的長事務阻塞主節點上的DDL操作。本文介紹如何為PolarDB開啟該參數。

使用限制

PolarDB叢集版本需滿足如下條件之一:

  • PolarDB MySQL版8.0版本且修訂版本為8.0.1.1.23或以上

  • PolarDB MySQL版5.7版本且修訂版本為5.7.1.0.19或以上

  • PolarDB MySQL版5.6版本且修訂版本為5.6.1.0.32或以上

說明

您可以通過查詢版本號碼確認叢集的核心版本。

僅當PolarDB唯讀節點交易隔離等級為Read CommittedRead Uncommitted時,polar_slave_work_on_nonblock_mdl_mode參數才有效。

polar_slave_work_on_nonblock_mdl_mode參數僅在PolarDB的唯讀節點生效。

背景資訊

PolarDB唯讀節點上的長事務會一直持有訪問過的資料表的中繼資料鎖(MDL),它將導致PolarDB主節點上的DDL操作無法完成MDL同步,並最終逾時,返回錯誤ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize

說明

MDL同步過程的逾時時間由參數replica_lock_wait_timeout控制,該參數值預設為50s。

當發生該問題時,在PolarDB主節點上執行命令show processlist,查詢結果中State欄位若提示Wait for syncing with replicas,您可以在PolarDB唯讀節點上執行命令select * from information_schema.innodb_log_mdl_slot where slot_state = "SLOT_ACQUIRING"查詢處於等待狀態的MDL資訊。若該命令返回如下結果,則表明PolarDB唯讀節點上存在MDL等待問題。

+---------+----------------+-----------+----------+-----------+
| slot_id | slot_state     | slot_name | slot_lsn | thread_id |
+---------+----------------+-----------+----------+-----------+
|       0 | SLOT_ACQUIRING | test/t    | 35025648 | thread-0  |
+---------+----------------+-----------+----------+-----------+

注意事項

polar_slave_work_on_nonblock_mdl_mode只能解決長事務導致的DDL阻塞問題。開啟polar_slave_work_on_nonblock_mdl_mode後,您仍將可能遇到大查詢(即耗時超過MDL同步過程逾時時間的查詢)導致的MDL同步失敗。

由於lock table和flush table擷取的MDL需要顯式通過unlock tables來釋放,因此polar_slave_work_on_nonblock_mdl_mode無法解決lock table和flush table導致的MDL阻塞問題。

操作步驟

  1. 登入PolarDB控制台

  2. 在左上方,選擇叢集所在地區。

  3. 找到目的地組群,單擊叢集ID。

  4. 在左側導覽列中選擇配置与管理 > 参数配置

  5. 找到目標參數loose_polar_slave_work_on_nonblock_mdl_mode,單擊修改參數

    參數配置

  6. 參數修改完成後,單擊提交修改,在儲存改動對話方塊中,單擊確定

    儲存改動

使用樣本

開啟polar_slave_work_on_nonblock_mdl_mode後,在唯讀節點上,同一事務將可能會看到不一樣的表結構,如下:

  1. 首先,在唯讀節點上查詢test.t

    mysql> begin;
    mysql> select * from test.t;
    +------+
    | a    |
    +------+
    |    1 |
    +------+
    1 row in set (0.00 sec)
  2. 然後,在主節點上對test.t進行DDL操作:

    mysql> alter table test.t add column b int;
    Query OK, 0 rows affected (0.32 sec)
    Records: 0  Duplicates: 0  Warnings: 0
  3. 最後,再次在唯讀節點上查詢test.t

    mysql> select * from test.t;
    +------+------+
    | a    | b    |
    +------+------+
    |    1 | NULL |
    +------+------+
    1 row in set (0.00 sec)

通過上述樣本,可以看出在開啟polar_slave_work_on_nonblock_mdl_mode的情況下,由於在主節點上進行了DDL操作,從而在唯讀節點上的同一個事務看到了不同的列數目。如果關閉polar_slave_work_on_nonblock_mdl_mode,在主節點上的DDL操作將持續等待唯讀節點上的事務,直至該事務被提交或等待逾時(報錯:ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize)。

聯絡我們

若您對DDL操作有任何疑問,請聯絡我們