在线DDL
功能描述
在线DDL是指在执行特定DDL等锁的过程中,DML和查询语句可正常执行,不会被DDL阻塞。可有效避免因DDL等锁造成DML和查询语句阻塞的情况。该功能通过GUC参数enable_nonblocking_ddl控制,默认值为off,设置为on表示开启在线DDL。
原有的DDL加锁逻辑为直接加高级别的锁,如果与当前正在执行的业务互斥,则进入等待队列,后续其他事务如果需要操作该对象,如果新的业务与正在排队的DDL之间互斥,则需要等待正在排队的DDL执行完,新的业务才能执行。
在线DDL功能则是在DDL等锁过程中,DML和查询语句不被DDL阻塞,而是在与已持有的锁不互斥的情况下直接加锁执行。
支持的场景如下:
表增加字段(ADD COLUMN),仅支持追加到最后,不支持指定位置增加。
表删除字段(DROP COLUMN)。
表修改字段(MODIFY COLUMN)。
注意事项
在线DDL功能需谨慎使用,建议在无业务时段操作。
满足以下条件的DDL语句执行时间与数据量无关,对业务影响更小。
表增加字段时,追加到最后,不在指定位置增加。
表修改字段时,仅做同数据类型长度增加。
默认场景为字段不含默认值,即without any default value。
字段含有默认值的场景,默认值支持的数据类型如下:boolean、bytea、char、bigint、smallint、integer、text、real、double precision、abstime、reltime、tinterval、character、varchar、numeric、number、date、time without time zone、oradate、timestamp without time zone、timestamp、with time zone、interval、time with time zone、tinyint、smalldatetime、datetime2、datetime、oid、name、aclitem[]。
default value 默认表达式不能包含易失性函数(指没有相关数据变化的情况下回自动更新结果的函数,例如rand()、now()等)。
default value 默认值不超过128字节。
在线DDL能力仅限于DDL加锁过程对业务的阻塞减轻,对于DDL执行过程中对业务的阻塞无变化。
非阻塞式DDL不支持在事务块中执行。
需设置GUC参数enable_nonblocking_ddl为on。
示例
1、设置GUC参数enable_nonblocking_ddl为on。
ALTER SYSTEM SET enable_nonblocking_ddl TO ON;
2、创建测试表。
CREATE TABLE mytable (existingfield VARCHAR(500));
3、在线DDL测试。
会话一,开启事务并插入数据。
BEGIN; INSERT INTO mytable VALUES(' \\BRRNAKCL12\Audiofiles22\1Year\Diogarfngal_ZZZZZZZZZ\2020\Aug\03\5249013\5249013-07-25-18-96572.cca');
会话二,执行DDL语句,模拟DDL阻塞场景。
ALTER TABLE mytable ADD NewField VARCHAR(500);
会话三,执行DML语句和查询语句。
INSERT INTO mytable VALUES('123'); SELECT * FROM mytable;
返回结果为:
existingfield --------------- 123 (1 row)
上述结果可以看出DDL阻塞场景下不影响DML及查询语句执行。
4、会话一执行清理测试数据。
COMMIT;
ALTER SYSTEM SET enable_nonblocking_ddl TO OFF;
DROP TABLE mytable;