【标题描述】:
【测试类型:SQL功能/存储功能/接口功能/工具功能/性能/并发/压力长稳/故障注入/安全/资料/编码规范】【测试版本:2.0.0】 问题描述
【操作系统和硬件信息】(查询命令: cat /etc/system-release, uname -a):
【测试环境】(单机/1主x备x级联备):
单机
【被测功能】:
在线重建索引
【测试类型】:
功能测试
【数据库版本】(查询命令: gaussdb –V):
【预置条件】:
关闭ustore
DROP INDEX idx_local_list_btree ;
DROP TABLE t_rebuild_p_list cascade;
CREATE TABLE t_rebuild_p_list (
id int,
name varchar(20)
)partition by list(id)
(partition p1 values (1,3,5),
partition p2 values (2,4,6),
partition p3 values (7,8,9,10));
INSERT INTO t_rebuild_p_list values(1,'liuyi');
INSERT INTO t_rebuild_p_list values(2,'chener');
INSERT INTO t_rebuild_p_list values(3,'zhangsan');
INSERT INTO t_rebuild_p_list values(4,'lisi');
INSERT INTO t_rebuild_p_list values(5,'wangwu');
INSERT INTO t_rebuild_p_list values(6,'zhaoliu');
INSERT INTO t_rebuild_p_list values(7,'sunqi');
INSERT INTO t_rebuild_p_list values(8,'zhouba');
INSERT INTO t_rebuild_p_list values(9,'wujiu');
CREATE INDEX idx_local_list_btree ON t_rebuild_p_list using btree(id) local;
【操作步骤】(请填写详细的操作步骤):
--打开两个会话
--会话1不断执行DML和DQL操作:
do language plpgsql $$
declare
begin
for i in 5..100000 loop
INSERT INTO t_rebuild_p_list values(10,'zhengshi');
DELETE FROM t_rebuild_p_list WHERE id=10;
PERFORM name FROM t_rebuild_p_list WHERE id<6 order by name;
commit;
end loop;
end;
$$;
--会话2重建索引
REINDEX INDEX concurrently idx_local_list_btree ;
REINDEX INDEX concurrently idx_local_list_btree partition p1_id_idx ;
REINDEX INDEX concurrently idx_local_list_btree partition p2_id_idx ;
REINDEX INDEX concurrently idx_local_list_btree partition p3_id_idx ;
【预期输出】:
执行DML及重建索引均成功
【实际输出】:
DML报错partition xxx does not exist on relation xxx
【原因分析】:
【日志信息】(请附上日志文件、截图、coredump信息):
【测试代码】:
Hey @XiyeLan, Welcome to openGauss Community.
All of the projects in openGauss Community are maintained by @opengauss-bot.
That means the developers can comment below every pull request or issue to trigger Bot Commands.
Please follow instructions at Here to find the details.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
Hi @XiyeLan, please use the command /sig xxx to add a SIG label to this issue.
For example: /sig sqlengine or /sig storageengine or /sig om or /sig ai and so on.
You can find more SIG labels from Here.
If you have no idea about that, please contact with @zhangxubo , @xiangxinyong .
原因分析:
直接原因是因为二级分区表的实现代码,可能会在整个sql执行过程多个阶段的不同地方调用heap_open或partitionOpen这些函数,触发消费InvalidationMessage,导致索引分区oid找不到而报错。
为什么索引分区oid不存在(一般这种情况都会通过加锁在解决并发问题),是因为 在线重建索引 后面会进行swap,原索引分区oid的parentid换成了临时创建的索引oid,导致代码中索引和原索引分区之间的关系变了。
出现缺陷中的问题的其中一个流程:
在PartIterator执行算子开始执行时,会触发ExecReScanIndexScan()->ExecInitNextPartitionForIndexScan(),其中会重新调用heap_open去获取Relation,该函数会去消费InvalidationMessage;
ExecEndIndexScan()->releasePartitionList()-> SubPartitionOidGetParentRelation(),在索引扫描最后释放Partition,发现Partition的parentid不等于 索引oid,后面把Partition当成二级分区索引尝试去打开分区的Relation,最终找不到相关系统条目,报 ERROR。
间接原因是因为 在线重建索引 中的swap步骤,这个swap动作已经属于 DDL 范畴,对于swap的对象必须要加 排它锁 来处理并发问题。
登录 后才可以发表评论