PolarDB-X存储引擎提供了新一代多版本唯一键索引-Panda Index 。针对传统MySQL非聚簇索引的效能瓶颈,Panda Index 通过原生的多版本并发控制(MVCC)能力,避免查询路径上跨索引访问带来的额外开销,且将全局区间约束检测优化为行级锁粒度,有效规避锁范围扩散问题。
前提条件
您的实例需满足以下版本要求:
实例系列:标准版或企业版。
引擎版本:MySQL 8.0。
存储节点版本:xcluster8.4.20-20250527及以上版本,即2025-05-27发布的版本及之后版本。
计费说明
Panda Index 功能本身是免费的。然而,Panda Index 在每个唯一索引记录上会增加28个字节。对于绝大多数业务表而言,这部分存储空间的增加通常低于5%,但仍会增加相应的存储费用。
注意事项
实例版本:由于Panda Index 涉及底层存储结构变动,使用了Panda Index 的实例无法降级至不支持Panda Index 的老版本。
存量索引处理:对于已存在唯一键(UK)的表,在开启Panda Index 后,它们不会自动转换为Panda Index 。您可以通过以下方式重建索引,以使其具备Panda Index 能力。
创建新索引:
ALTER TABLE ... ADD UNIQUE INDEX idx_new ...;
更换索引名:
ALTER TABLE ... RENAME idx TO idx_old, RENAME idx_new TO idx;
删除原索引:
ALTER TABLE ... DROP INDEX idx_old;
隔离级别限制:Panda Index 主要优化Read-Committed(RC)隔离级别下的Gap锁问题。在Repeatable-Read(RR)隔离级别下,为保证可重复读,系统仍会使用Next-Key锁(记录锁+Gap锁),因此Panda Index 在此级别下无法避免Gap锁。
表与索引类型限制:Panda Index 不适用于临时表、系统表、压缩表以及多值索引。
如何使用Panda Index
1. 开启Panda Index 功能
前往PolarDB分布式版控制台,在目标集群的 页面的存储层页签中,将参数opt_index_format_panda_enabled
的值修改为ON
。此操作无需重启实例,即时生效。
将参数
opt_index_format_panda_enabled
的值修改为ON
,创建表或者新建唯一键索引时默认创建Panda Index 。将参数
opt_index_format_panda_enabled
的值修改为OFF
,创建表或者新建唯一键索引时默认创建与MySQL社区保持一致的普通唯一键索引形式。
2. 验证Panda Index 效果
您可以通过一个简单的并发场景来验证其效果。
数据准备
-- 创建表与唯一键索引
CREATE TABLE t1(
id int,
c1 int,
PRIMARY KEY(id),
UNIQUE KEY uk1(c1)
) SINGLE /* 这里以企业版的单表为例,标准版实例不需要 */;
-- 插入数据
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (100,100);
并发测试
在一个事务(Session 1)中删除一条记录并插入一条新记录,模拟常见的“先删后改”操作。
BEGIN;
DELETE FROM t1 where id=1;
INSERT INTO t1 values (2,1);
同时,在另一个事务(Session 2)中插入一条不冲突但位于间隙内的数据。
INSERT INTO t1 values (3,2);
此时,普通唯一键与Panda Index 表现各不相同。
普通唯一键:Session 2的插入操作会因等待Session 1持有的Gap锁而超时失败。
mysql> INSERT INTO t1 values (3,2); -- 报错中出现关键字:Lock wait timeout exceeded; try restarting transaction
标准版实例可以观察到锁信息中包含普通唯一键
uk1
上的GAP锁。SELECT lock_data, lock_mode FROM performance_schema.data_locks WHERE index_name ='uk1'; +-----------+---------------+ | lock_data | lock_mode | +-----------+---------------+ | 1, 1 | X,REC_NOT_GAP | | 1, 1 | S,GAP | | 100, 100 | S,GAP | | 1, 2 | S,GAP | +-----------+---------------+
Panda Index :Session 2的插入操作会立即成功,因为Panda Index 不会产生不必要的Gap锁。
mysql> INSERT INTO t1 values (3,2); Query OK, 1 row affected (0.00 sec)
标准版实例可以观察到锁信息中并无普通唯一键
uk1
上的GAP锁。SELECT lock_data, lock_mode FROM performance_schema.data_locks WHERE index_name ='uk1'; +-----------+---------------+ | lock_data | lock_mode | +-----------+---------------+ | 1, 2 | X,REC_NOT_GAP | +-----------+---------------+