全部产品
Search
文档中心

云原生数据库 PolarDB:抢占式DDL

更新时间:Aug 28, 2024

PolarDB MySQL版新增抢占式DDL(Preemptive DDL)功能。Preemptive DDL解决了在执行DDL的过程中,由于只读节点的表上存在大查询和长事务而导致的DDL执行失败的问题。

问题现象

PolarDB MySQL版数据库中执行DDL操作时提示获取不到MDL锁,报错信息如下:

ERROR HY000: Fail to get MDL on replica during DDL synchronize
ERROR HY000: Fail to get table lock on replica; you can 'set polar_support_mdl_sync_preemption = ON' and try restarting transaction

前提条件

PolarDB MySQL版集群版本需为:

  • 5.6版本且修订版本为5.6.1.0.43及以上。

  • 5.7版本且修订版本为5.7.1.0.34及以上。

  • 8.0.1版本且修订版本为8.0.1.1.39及以上。

  • 8.0.2版本且修订版本为8.0.2.2.14及以上。

如何查看集群版本,请参见查询版本号

使用限制

目前仅只读节点支持抢占式DDL功能,读写节点暂不支持。

注意事项

  • 开启抢占式DDL功能可能会导致只读节点上访问当前表的连接中断或者当前表上未执行完的SQL回滚,请您谨慎操作。

  • loose_replica_lock_wait_timeout参数的值 >(loose_polar_mdl_sync_preempt_after_wait_second参数的值+5)时,抢占式DDL功能才生效。

  • MySQL 8.0.1MySQL 8.0.2,rename路径下此功能不生效,推荐使用alter table rename语句代替。

背景信息

PolarDB MySQL版采用共享存储的架构,用户在执行DDL操作时,首先会在读写节点上获取MDL-X锁,然后再通知只读节点获取MDL-X锁。若此时只读节点的表上存在访问表的事务,MDL锁同步线程便会被阻塞。如果在超时时间内,只读节点始终无法获得MDL-X锁,客户端则会返回错误ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize。对于含有多个只读节点的PolarDB MySQL版集群,经常会出现MDL锁同步失败导致DDL执行失败的问题,为此新增抢占式DDL功能。

使用方法

您可以先通过loose_polar_support_mdl_sync_preemption参数开启抢占式DDL功能,并通过loose_polar_mdl_sync_preempt_after_wait_second参数设置抢占过程中等待超时的时间。具体操作请参见设置集群参数和节点参数。参数说明如下:

参数

级别

说明

loose_polar_support_mdl_sync_preemption

Session

抢占式DDL功能开关。取值范围如下:

  • ON:开启抢占式DDL功能。

  • OFF(默认):关闭抢占式DDL功能。

loose_polar_mdl_sync_preempt_after_wait_second

Global

设置同步MDL锁阻塞时,等待超时的时间。到达此时间还未成功同步MDL锁,则开始抢占线程。

取值范围:1~31536000。单位为秒。默认值为10。

使用示例

关闭抢占式DDL功能

  1. 首先在只读节点上查询test.t1

    mysql> use test;
    Database changed
    #大查询,执行100s
    mysql> select sleep(100) from t1;
  2. 然后在读写节点上进行加列操作。

    mysql > alter table t1 add column c int;
    ERROR 8007 (HY000): Fail to get MDL on replica during DDL synchronize

    通过上述示例,可以看出在关闭抢占式DDL功能的情况下,由于只读节点上存在长事务,同步MDL锁失败,读写节点上的DDL操作被阻塞,从而导致执行DDL操作失败。

    image..png

开启抢占式DDL功能

  1. 首先在只读节点上查询test.t1

    mysql> use test;
    Database changed
    #大查询,执行100s
    mysql> select sleep(100) from t1;
  2. 然后在读写节点上进行加列操作。

    mysql> alter table t1 add column c int;
    Query OK, 0 rows affected (11.13 sec)
    Records: 0  Duplicates: 0  Warnings: 0

    通过上述示例,可以看出在开启抢占式DDL功能的情况下,由于只读节点上存在长事务,同步MDL锁被阻塞。等待一段时间后,开始抢占线程,DDL操作成功。

    image..png

联系我们

若您对DDL操作有任何疑问,请联系我们