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 Committed
或Read 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阻塞问题。
操作步骤
登录PolarDB控制台。
在左上角,选择集群所在地域。
找到目标集群,单击集群ID。
在左侧导航栏中选择 。
找到目标参数loose_polar_slave_work_on_nonblock_mdl_mode,单击修改参数。
参数修改完成后,单击提交修改,在保存改动对话框中,单击确定。
使用示例
开启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
)。
联系我们
若您对DDL操作有任何疑问,请联系我们。