目前业界兼容 MySQL 协议的分布式数据库,出于架构限制和实现难度等方面的原因,基本都是以性能优先为策略,放弃了连续和递增等特性,仅实现了对 AUTO_INCREMENT 的部分兼容。
PolarDB-X 2.0 从 5.4.14 版本开始,推出了新类型的 New Sequence,并将其与 AUTO 模式库中的表 AUTO_INCREMENT 属性相关联,达成了与 MySQL AUTO_INCREMENT 一致的功能和性能体验。
本文将以 INSERT 插入数据时,通过 AUTO_INCREMENT 自动填充 ID 的场景,演示某热门分布式数据和 PolarDB-X 2.0 对 AUTO_INCREMENT 兼容的差异性。
某热门分布式数据库
建表:
CREATE TABLE test_somedb (
id INT NOT NULL AUTO_INCREMENT,
number INT NOT NULL,
PRIMARY KEY (id)
);分别从3个不同计算节点的连接上插入数据:
-- 在节点1连接上执行
INSERT INTO test_somedb(number) VALUES (1);
-- 在节点2连接上执行
INSERT INTO test_somedb VALUES (null, 2);
-- 在节点3连接上执行
INSERT INTO test_somedb VALUES (0, 3);
-- 在节点2连接上执行
INSERT INTO test_somedb VALUES (null, 4);
-- 在节点1连接上执行
INSERT INTO test_somedb VALUES (0, 5);查询插入数据,能看到无法保证连续和自增,且有很大空洞,与 MySQL 不兼容:
SELECT * FROM test_somedb ORDER BY number;
+-------+--------+
| id | number |
+-------+--------+
| 1 | 1 |
| 54211 | 2 |
| 84211 | 3 |
| 54212 | 4 |
| 2 | 5 |
+-------+--------+向 AUTO_INCREMENT 列插入显式值:
-- 在节点1连接上执行
INSERT INTO test_somedb VALUES (1000000, 6);
-- 在节点2连接上执行
INSERT INTO test_somedb VALUES (null, 7);
-- 在节点3连接上执行
INSERT INTO test_somedb VALUES (0, 8);
-- 在节点1连接上执行
INSERT INTO test_somedb VALUES (null, 9);查询插入数据,能看到仅刷新了执行插入的节点上的缓存,其它节点继续按原有缓存分配,与 MySQL 不兼容:
SELECT * FROM test_somedb ORDER BY number;
+---------+--------+
| id | number |
+---------+--------+
| 1 | 1 |
| 54211 | 2 |
| 84211 | 3 |
| 54212 | 4 |
| 2 | 5 |
| 1000000 | 6 |
| 54213 | 7 |
| 84212 | 8 |
| 1000001 | 9 |
+---------+--------+执行 ALTER TABLE 变更 AUTO_INCREMENT 的起始值,然后从不同节点插入数据:
-- 在节点2连接上执行
ALTER TABLE test_somedb AUTO_INCREMENT = 10000000;
-- 在节点2连接上执行
INSERT INTO test_somedb VALUES (null, 10);
-- 在节点3连接上执行
INSERT INTO test_somedb VALUES (0, 11);
-- 在节点1连接上执行
INSERT INTO test_somedb VALUES (null, 12);
-- 在节点2连接上执行
INSERT INTO test_somedb VALUES (null, 13);查询插入数据,能看到跟插入显式值时类似的现象,且自动分配的 ID 看起来已比较混乱,与 MySQL 不兼容:
SELECT * FROM test_somedb ORDER BY number;
+----------+--------+
| id | number |
+----------+--------+
| 1 | 1 |
| 54211 | 2 |
| 84211 | 3 |
| 54212 | 4 |
| 2 | 5 |
| 1000000 | 6 |
| 54213 | 7 |
| 84212 | 8 |
| 1000001 | 9 |
| 10000000 | 10 |
| 10076830 | 11 |
| 10115925 | 12 |
| 10000001 | 13 |
+----------+--------+PolarDB-X 2.0
AUTO 模式库中建表:
CREATE TABLE test_pxc (
id INT NOT NULL AUTO_INCREMENT,
number INT NOT NULL,
PRIMARY KEY (id)
);分别从3个不同计算节点的连接上插入数据:
-- 在 CN1 连接上执行
INSERT INTO test_pxc(number) VALUES (1);
-- 在 CN2 连接上执行
INSERT INTO test_pxc VALUES (null, 2);
-- 在 CN3 连接上执行
INSERT INTO test_pxc VALUES (0, 3);
-- 在 CN2 连接上执行
INSERT INTO test_pxc VALUES (null, 4);
-- 在 CN1 连接上执行
INSERT INTO test_pxc VALUES (0, 5);查询插入数据,自动分配的 ID 是单调递增和连续的,没有空洞,与 MySQL 完全兼容:
SELECT * FROM test_pxc ORDER BY number;
+----+--------+
| id | number |
+----+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+--------+向 AUTO_INCREMENT 列插入显式值:
-- 在 CN1 连接上执行
INSERT INTO test_pxc VALUES (1000000, 6);
-- 在 CN2 连接上执行
INSERT INTO test_pxc VALUES (null, 7);
-- 在 CN3 连接上执行
INSERT INTO test_pxc VALUES (0, 8);
-- 在 CN1 连接上执行
INSERT INTO test_pxc VALUES (null, 9);查询插入数据,后续生成的 ID 在不同节点上都能自动跟随,且继续保持连续和自增,与 MySQL 完全兼容:
SELECT * FROM test_pxc ORDER BY number;
+---------+--------+
| id | number |
+---------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 1000000 | 6 |
| 1000001 | 7 |
| 1000002 | 8 |
| 1000003 | 9 |
+---------+--------+执行 ALTER TABLE 变更 AUTO_INCREMENT 的起始值,然后从不同节点插入数据:
-- 在 CN2 连接上执行
ALTER TABLE test_pxc AUTO_INCREMENT = 10000000;
-- 在 CN2 连接上执行
INSERT INTO test_pxc VALUES (null, 10);
-- 在 CN3 连接上执行
INSERT INTO test_pxc VALUES (0, 11);
-- 在 CN1 连接上执行
INSERT INTO test_pxc VALUES (null, 12);
-- 在 CN2 连接上执行
INSERT INTO test_pxc VALUES (null, 13);查询插入数据,能看到不同节点上都能从新的起始值开始分配,且继续保持连续和自增,与 MySQL 完全兼容:
SELECT * FROM test_pxc ORDER BY number;
+----------+--------+
| id | number |
+----------+--------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 1000000 | 6 |
| 1000001 | 7 |
| 1000002 | 8 |
| 1000003 | 9 |
| 10000000 | 10 |
| 10000001 | 11 |
| 10000002 | 12 |
| 10000003 | 13 |
+----------+--------+小结
从上面对两个数据库的常用典型场景进行对比,能看到 PolarDB-X 2.0 对 AUTO_INCREMENT 的支持与 MySQL 完全兼容。
在后续文章中,我们会对分布式数据库中全局唯一 ID 方案和与 MySQL AUTO_INCREMENT 的兼容性等方面,进行综述性的全面分析,也会介绍 PolarDB-X 2.0 中 AUTO_INCREMENT 兼容性的实现原理和性能水准,希望大家继续关注。




