本文介绍全球数据库网络(Global Database Network,简称GDN)的DDL复制操作。
通过高效的DML复制,可以实现GDN上下游集群之间数据表内容的一致性,而DDL复制,则是保证GDN主从集群之间Schema一致性的核心能力。GDN主从集群之间Schema的一致性不仅仅局限于表结构的一致,而且体现在所有数据库对象之间的一致,这样才能保证在发生主从切换时从集群有能力承载应用的流量。否则,即使丢失一个索引,也可能引发严重的性能问题。
DDL类型
PolarDB-X支持多种类型的数据库对象,包括常见的兼容MySQL的表、列、索引、视图、函数等,以及TableGroup、Sequence、全局二级索引(GSI)、列存索引(CCI)、自定义函数等各种自定义的对象类型。此外,还提供了许多自定义的扩展语法,如TTL、Locality、无锁变更列类型(OMC)、本地索引(Local index)等。无论是在兼容性还是分布式场景的复杂性方面,DDL复制都是一个相当具有挑战性的能力。因此,PolarDB-X提供了内置的DDL复制能力,简单、可靠且易于使用。
DDL类型支持情况说明:
类别 | 类型 | 是否支持 | 说明 |
DATABASE | CREATE_DATABASE | 是 | 请参见:数据库。 说明 ALTER DATABASE目前不支持修改字符集,因此在复制场景下无法实现支持。 |
DROP_DATABASE | 是 | ||
ALTER_DATABASE | 否 | ||
MOVE_DATABASE | 否 | ||
TABLE | CREATE_TABLE | 是 | 请参见:数据表。 |
ALTER_TABLE | 是 | ||
DROP_TABLE | 是 | ||
TRUNCATE_TABLE | 是 | ||
RENAME_TABLE | 是 | ||
ANALYZE_TABLE | 是 | ||
PARTITION | 分区分裂 | 是 | 请参见:分区变更语法。 说明 暂不支持分区迁移,请参见限制一。 |
热点分区分裂 | 是 | ||
分区合并 | 是 | ||
分区迁移 | 否 | ||
重命名分区 | 是 | ||
增加分区 | 是 | ||
删除分区 | 是 | ||
修改分区 | 是 | ||
重组分区 | 是 | ||
清空分区 | 是 | ||
TABLEGROUP | CREATE_TABLEGROUP | 是 | 请参见:表组。 |
DROP_TABLEGROUP | 是 | ||
ALTER_TABLEGROUP | 是 | ||
MERGE_TABLEGROUP | 是 | ||
ALTER_TABLEGROUP_ADD_TABLE | 是 | ||
ALTER_TABLE_SET_TABLEGROUP | 是 | ||
JOINGROUP | CREATE_JOINGROUP | 是 | |
ALTER_JOINGROUP | 是 | ||
DROP_JOINGROUP | 是 | ||
INDEX | CREATE_INDEX | 是 | 请参见:索引。 |
DROP_INDEX | 是 | ||
ALTER_INDEX | 是 | ||
ALTER_INDEX_VISIBILITY | 是 | ||
SEQUENCE | CREATE_SEQUENCE | 是 | 请参见:Sequence。 |
DROP_SEQUENCE | 是 | ||
ALTER_SEQUENCE | 是 | ||
RENAME_SEQUENCE | 是 | ||
CONVERT_ALL_SEQUENCES | 是 | ||
FUNCTION | CREATE_FUNCTION | 是 | 请参见:自定义函数。 |
DROP_FUNCTION | 是 | ||
ALTER_FUNCTION | 是 | ||
CREATE_JAVA_FUNCTION | 是 | ||
ALTER_JAVA_FUNCTION | 是 | ||
DROP_JAVA_FUNCTION | 是 | ||
PROCEDURE | CREATE_PROCEDURE | 是 | 请参见:存储过程。 |
ALTER_PROCEDURE | 是 | ||
DROP_PROCEDURE | 是 | ||
VIEW | CREATE_VIEW | 是 | 请参见:视图。 |
DROP_VIEW | 是 | ||
ALTER_VIEW | 是 | ||
CREATE_MATERIALIZED_VIEW | 是 | ||
DROP_MATERIALIZED_VIEW | 是 | ||
USER | CREATE_USER | 是 | 请参见:账号权限管理。 |
DROP_USER | 是 | ||
SET_PASSWORD | 是 | ||
GRANT_PRIVILEGE_TO_USER | 是 | ||
REVOKE_PRIVILEGE_FROM_USER | 是 | ||
ROLE | CREATE_ROLE | 是 | 请参见:角色权限管理。 |
DROP_ROLE | 是 | ||
GRANT_PRIVILEGE_TO_ROLE | 是 | ||
GRANT_ROLE_TO_USER | 是 | ||
SQL_SET_DEFAULT_ROLE | 是 | ||
REVOKE_PRIVILEGE_FROM_ROLE | 是 | ||
REVOKE_ROLE_FROM_USER | 是 | ||
SET | SET GLOBAL ... | 否 | PolarDB-X采取了和MySQL相同的策略,在主从复制链路中并未进行同步,这并非Schema变更。如需进行调整,请在主集群和从集群分别进行操作。 |
SQL限流 | * | 否 | SQL限流通常是一种临时性操作,GDN不支持将限流规则复制到从集群,如果需要,请在主集群和从集群分别进行操作。 |
目前不支持与列存索引相关的DDL复制(CREATE/DROP/ALTER COLUMNAR INDEX)。
表组类型
PolarDB-X支持两种类型的表组:显式表组和隐式表组。
显式表组允许用户自定义,可以通过
CREATE TABLEGROUP
进行创建,通过DROP TABLEGROUP
进行删除,通过ALTER TABLEGROUP
进行变更,具体操作可参考表组。隐式表组由PolarDB-X隐式创建,当创建分区表、删除分区表、变更表的分区类型时,可能会涉及隐式表组的创建、变更或删除。隐式表组不支持通过
CREATE TABLEGROUP
和DROP TABLEGROUP
进行管理,但支持通过ALTER TABLEGROUP
进行变更。隐式表组的名称通过维护一个序列号生成,如tg1、tg2、tg3...,以此类推。该序列号的生成具有不确定性,例如并行创建两张不同的分区表T1和T2,这两张表对应的隐式表组的序号大小是随机的;此外,序号还可能被跳过,例如对序号加1后生成了表组名称,但DDL任务流出现了回滚,则该序号被作废。
隐式表组对PolarDB-X的主从复制带来了挑战。如果让主集群和从集群按照默认的规则各自生成自己的隐式表组,可能会导致主从集群中相同表的隐式表组名称不一致,甚至可能出现所有隐式表组名称完全混乱的情况。在GDN数据复制场景下,隐式表组的复制是通过扩展DDL SQL语法来实现的。当DDL操作涉及隐式表组的变更时,主集群记录到Binlog中的DDL都是经过扩展的DDL SQL。
示例一
提交的建表SQL:
create table if not exists tb1 (
a int PRIMARY KEY,
b int,
c int,
d varchar(10) UNIQUE,
INDEX b(b),
INDEX b_2(b),
KEY b_3 (b),
KEY b_4 (b),
UNIQUE KEY b_5 (b),
UNIQUE KEY b_6 (b),
UNIQUE INDEX b_7 (b),
UNIQUE INDEX b_8 (b),
INDEX g1(b),
KEY g2 (b),
UNIQUE KEY g3 (b),
UNIQUE INDEX g4 (b)
) DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_general_ci;
示例二
提交的变更分区的SQL:
ALTER TABLE tb1 MERGE PARTITIONS p1, p2 TO p12;
记录到Binlog中经过扩展后的SQL:
ALTER TABLE tb1 MERGE PARTITIONS p1, p2 TO p12 WITH TABLEGROUP=tg29 IMPLICIT;
多流复制
在单流复制场景下,只需按照Binlog中的顺序逐条执行复制主集群的DDL SQL到从集群。然而,在多流复制场景下,在进行DDL复制时,则需要考虑不同复制链路之间的协调一致。每条复制链路在收到某条DDL SQL后必须等待其它复制链路,只有当所有链路都收到该DDL SQL之后,才可以将DDL操作复制给从集群,否则将导致DML流量和Schema之间的不一致,引发异常或数据错误。
针对多流复制,GDN提供了分布式DDL复制引擎(Distributed DDL Replication Engine),通过高效的多路协调算法,实现分布式场景下DDL复制的一致性。
使用限制
限制一
PolarDB-X提供了支持通过LOCALITY指定存储位置。该特性允许在DDL SQL中包含DN节点的实例id。然而,由于GDN目前暂不支持主从集群间DN节点之间的关联映射,因此在将包含此类SQL的DDL复制到下游时,系统将会剔除SQL中涉及DN的相关内容。针对这一情况,您可登录从集群并手动进行分区分布的调整。
示例一
// 主集群执行SQL: CREATE TABLE test_pg3 ( id int ) DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_general_ci PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (1000) LOCALITY 'dn=xdevelop-240524092100-31ef-bngl-dn-1', PARTITION p1 VALUES LESS THAN (2000) LOCALITY 'dn=xdevelop-240524092100-31ef-bngl-dn-1' ) // 复制到从集群的SQL: create table test_pg3 ( id int ) DEFAULT CHARACTER SET = utf8mb4 DEFAULT COLLATE = utf8mb4_general_ci PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (1000), PARTITION p1 VALUES LESS THAN (2000) ) WITH TABLEGROUP = tg3778 IMPLICIT
示例二
// 主集群执行SQL: ALTER TABLE special_dml_test1 MOVE PARTITIONS (p2, p4, p6, p8) TO 'xdevelop-240524092100-31ef-bngl-dn-0'; // 复制到从集群的SQL: ALTER TABLE special_dml_test1;
限制二
PolarDB-X提供了SET PARTITION_HINT命令,可以指定SQL语句在特定分区上执行。在GDN主从集群复制场景下,目前不支持将该命令透传到从集群,也就是说,在主集群通过该命令显式将数据写入指定分区后,GDN无法保证这些数据也会被写入到从集群的相同分区。