PolarDB 不能光是介绍,咱们也的有点实际的,证明你用过。我写了3年的PolarDB 最近发现同盟者越来越多,开始使用这个数据库的人和同学都在问我问题,本着知无不言,分享点也掉不了一块肉的宗旨,越写越明白,大不了我不还有POLARDB 的后花园们。

这次是一个生产上的问题,使用POALRDB的用户会遇到,问题先描述一下:

早上开发找我,问添加字段的时候卡主了,通过集成的平台对一堆的表添加字段,然后有的过去了,有的等了有10多分钟还没有过去,过来问我怎么回事。

我其实对于一些不好学,或者说过一次还不长记性的人通常是没有好脾气的,要不叫我刺头刘。我数落了他一顿,但问题还是要分析的,这里也给开始使用POLARDB的同学提一个醒。

这是一张简易的POLARDB-M的结构图,其中可以看到存储就只有一个,那么这说明一个问题,主库和从库的数据同步的部分那根本就不可能和BINLOG有半毛钱的关系。



POLARDB  添加字段 “卡” 住---这锅Polar不背_数据库

且数据同步是通过REDO LOG 进行的同步,因为数据只在一个存储上,那么这就出现了一个问题,关于数据多版本和数据读取时的数据MVCC的问题。下面这张图可以清晰的看到,数据通过REDO LOG 复制到了从库,一些数据也会从存储直接提取到从库的内存中,完整主从复制的数据一致性。



POLARDB  添加字段 “卡” 住---这锅Polar不背_MySQL_02

这里就有一个问题,关于从库,从库要对内存中的数据进行刷新,但此时你的读写节点是分离的,那么从库的节点读取什么数据是自己的事情,比如他有一个大事务,读取时的数据snapshot,而你要刷新当前的从库的内存中的数据,这矛盾就出来了。

从库到底是刷新还是不刷新,刷新内存了,当前读取的数据没有了,但如果不刷新,REDO的日志同步的部分就需要等待进行刷新。这是一个问题,这部分的DML数据的解决方案我之前在白皮书上有写,还有POLARDB的优化过程(POALRDB 数据库程序的优化)。

今天就说DDL的问题,在给出了一个解决的方案: PolarDB MySQL版8.0.1版本且Revision version为8.0.1.1.29及以上,以及8.0.2.2.12版本

首先先确认你的数据库版本是不是以上的版本,8.01.1.29 或者8.02.2.12 版本

然后咱们有4个参数 loose_polar_nonblock_ddl_mode

第一个参数,默认是关闭的状态,咱们需要打开这个参数,这个参数开启了 非阻塞 DDL(Non-blocking DDL)模式。当该模式启用时,POLARDB 会尝试以一种更智能的方式执行 DDL 操作,从而减少对数据库其他操作(尤其是 DML 操作)的阻塞影响。

loose_polar_nonblock_ddl_lock_wait_timeout

第二个参数,默认是1 单位秒,这里参数是进行DDL 时发现有MDL-X锁时多长时间算做超时,这个参数可以适当调整大一些,比如你的数据库服务器经常从库在进行OLAP的工作。

loose_polar_nonblock_ddl_retry_times 第三个参数,这个参数指定了在 获取 MDL-X 锁(元数据锁排它锁)时的 最大重试次数。这个部分不能设置的太大,太大会导致长时间的重试。

loose_polar_nonblock_ddl_retry_interval

第四个参数,此参数设置了 获取 MDL 锁超时重试的时间间隔。如果获取 MDL 排它锁失败,POLARDB 会在此时间间隔后再次尝试,单位秒。

最后这里给使用POLARDB-MySQL的同学一个调节的案例

innodb_bulk_load_page_grained_redo_enable = on (玩PolarDB的都知道)

这个参数会极大的优化polardb-M 下的DDL的性能,开与不开性能相差,官方显示。3-10倍的差距。

loose_polar_nonblock_ddl_mode  = on

这个没有说的必须打开,后续的参数才能生效

loose_polar_slave_work_on_nonblock_mdl = on

这个参数也需要打开,让从库也在nonblock_mdl的模式

loose_polar_nonblock_ddl_lock_wait_timeout

这个参数是获取MDL锁时最大的等待时间,这个数值是秒,这里我设置的是1秒

loose_polar_nonblock_ddl_retry_times = 4194304

这个参数是在无法获得MDL锁时可以重试的次数,以上数值为官方建议的

loose_polar_nonblock_ddl_retry_interval = 3

这个参数是或许MDL锁超时重试的间隔,失败等待3秒重试 默认值6

通过调整参数后,可以解决或缓解在一些POALRDB FOR MYSQL 上把POLARDB 当OLAP 数据库使用的方式式还要在业务时间里面对字段进行操作的行为。

官方文档: https://help.aliyun.com/zh/polardb/polardb-for-mysql/user-guide/nonblocking-ddl-statements?spm=a2c4g.11186623.0.i2

POLARDB  添加字段 “卡” 住---这锅Polar不背_MySQL_03


POLARDB  添加字段 “卡” 住---这锅Polar不背_数据库_04

POLARDB  添加字段 “卡” 住---这锅Polar不背_数据库_05