PolarDB支持参数polar_slave_work_on_nonblock_mdl_mode。开启该参数后,可以防止PolarDB只读节点上的长事务阻塞主节点上的DDL操作。本文介绍如何为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 Committed
或Read Uncommitted
时,polar_slave_work_on_nonblock_mdl_mode参数才有效。
polar_slave_work_on_nonblock_mdl_mode参数仅在PolarDB的只读节点生效。
背景信息
ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize
。replica_lock_wait_timeout
控制,该参数值默认为50s。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阻塞问题。
操作步骤
- 登录PolarDB控制台。
- 在控制台左上角,选择集群所在地域。
- 找到目标集群,单击集群ID。
- 在左侧导航栏中选择 。
- 找到目标参数loose_polar_slave_work_on_nonblock_mdl_mode,单击当前值列的
图标,在弹出的对话框中,输入新的参数值,单击确定。
- 单击左上角提交修改,在保存改动对话框中,单击确定。
使用示例
- 首先,在只读节点上查询
test.t
:mysql> begin; mysql> select * from test.t; +------+ | a | +------+ | 1 | +------+ 1 row in set (0.00 sec)
- 然后,在主节点上对
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
- 最后,再次在只读节点上查询
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
)。