KingbaseES Reindex concurrently过程

前言

KES中我们经常遇到表膨胀情况,然而索引也会膨胀,随着业务DML语句的增长,稍不留神索引就会膨胀的很严重,膨胀后的索引只有VACUUM FULL才会真正释放磁盘空间,对于新构建的索引往往比更新的旧索引提供更好的访问性能。所以,我们需要重建膨胀的索引。

REINDEX命令需要ACCESS EXCLUSIVE锁,这是最高级别的锁,阻塞一切业务语句。所以我们会用到CONCURRENTLY 选项,这样锁级别就变成了SHARE UPDATE EXCLUSIVE锁,不会阻塞DML语句。

锁机制详见文档:KingabseES 锁机制 - KINGBASE研究院 - 博客园

Reindex Concurrently 的主要实现步骤

首先会根据传入的 RelationOid,找到所有需要进行 Reindex 的 IndexId,

拿到需要进行Reindex的索引Oid 之后,然后进入 Reindex Concurrently 的几个阶段:

1.创建新的索引,创建后表中有一个临时的新索引,名称以idx_ccnew开头;
2.build 新创建的索引,即扫描全表数据,构建新索引的内容;
3.validate 新创建的索引,将前一个阶段新插入的数据加入到索引中,这个和 create index concurrently 类似;
4.进行交换索引,将新创建的索引和它对应的需要 reindex 的索引进行交换,旧的索引标识为 invalid;
5.将旧的索引设置为 dead 状态,即 indislive、indisready、indisvalid 均为 false;

6.最后将旧的索引删掉;

如何识别无效索引:

SELECT c.relname as index_name, sys_size_pretty(sys_relation_size(c.oid)) 
FROM sys_index i JOIN sys_class c 
ON i.indexrelid = c.oid
WHERE -- New index built using REINDEX CONCURRENTLY c.relname LIKE '%_ccnew' 
-- In INVALID state AND NOT indisvalid 
LIMIT 10;
posted @ 2024-03-29 18:37  KINGBASE研究院  阅读(21)  评论(0编辑  收藏  举报