暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PolarDB MySQL之DDL易用性优化--抢占式DDL

xiaozhuo 2023-07-25
409

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

前提条件

集群版本需为PolarDB MySQL版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功能才生效。

背景信息

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

Global

抢占式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功能

  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
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论