New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
duplicate gp_fastsequence value (ctid) appears in ao table #13699
Comments
RCA: If we run But for AO table, the relfilenode should not be changed to
|
Thanks for reporting. The problem is worst for 6X_STABLE as truncate even outside create table will produce duplicate CTID and hence incorrect indexes. drop table if exists ao;
DROP TABLE
create table ao(a int, b int) with (appendonly=true) distributed by (a);
CREATE TABLE
--create index idx on ao(b);
insert into ao values(1,1);
INSERT 0 1
select gp_segment_id, xmin, xmax, * from gp_dist_random('gp_fastsequence') where gp_segment_id=1 and objid in (select segrelid from pg_appendonly where relid = 'ao'::regclass);
gp_segment_id | xmin | xmax | objid | objmod | last_sequence
---------------+------+------+-------+--------+---------------
1 | 732 | 0 | 24599 | 1 | 100
1 | 732 | 0 | 24599 | 0 | 0
(2 rows)
insert into ao values(1,1);
INSERT 0 1
insert into ao values(1,1);
INSERT 0 1
select gp_segment_id, xmin, xmax, * from gp_dist_random('gp_fastsequence') where gp_segment_id=1 and objid in (select segrelid from pg_appendonly where relid = 'ao'::regclass);
gp_segment_id | xmin | xmax | objid | objmod | last_sequence
---------------+------+------+-------+--------+---------------
1 | 732 | 0 | 24599 | 1 | 300
1 | 732 | 0 | 24599 | 0 | 0
(2 rows)
select ctid, * from ao;
ctid | a | b
----------------+---+---
(33554432,2) | 1 | 1
(33554432,102) | 1 | 1
(33554432,202) | 1 | 1
(3 rows)
begin;
BEGIN
truncate table ao;
TRUNCATE TABLE
insert into ao values(1,2);
INSERT 0 1
select gp_segment_id, xmin, xmax, * from gp_dist_random('gp_fastsequence') where gp_segment_id=1 and objid in (select segrelid from pg_appendonly where relid = 'ao'::regclass);
gp_segment_id | xmin | xmax | objid | objmod | last_sequence
---------------+------+------+-------+--------+---------------
1 | 732 | 0 | 24599 | 1 | 100
1 | 732 | 0 | 24599 | 0 | 0
(2 rows)
abort;
ROLLBACK
select gp_segment_id, xmin, xmax from gp_dist_random('gp_fastsequence') where gp_segment_id=1 and objid in (select segrelid from pg_appendonly where relid = 'ao'::regclass);
gp_segment_id | xmin | xmax
---------------+------+------
1 | 732 | 0
1 | 732 | 0
(2 rows)
insert into ao values(1,3);
INSERT 0 1
select gp_segment_id, xmin, xmax, * from gp_dist_random('gp_fastsequence') where gp_segment_id=1 and objid in (select segrelid from pg_appendonly where relid = 'ao'::regclass);
gp_segment_id | xmin | xmax | objid | objmod | last_sequence
---------------+------+------+-------+--------+---------------
1 | 732 | 0 | 24599 | 1 | 200
1 | 732 | 0 | 24599 | 0 | 0
(2 rows)
select ctid, gp_segment_id,* from ao order by ctid;
ctid | gp_segment_id | a | b
----------------+---------------+---+---
(33554432,2) | 1 | 1 | 1
(33554432,102) | 1 | 1 | 3 <<====================
(33554432,102) | 1 | 1 | 1
(33554432,202) | 1 | 1 | 1
(4 rows) hence the fix in #13762 becomes much more important. The reason its more serious for 6X_STABLE as in master branch inserts after truncate is using only segfile 0 due to code in |
This is to fix #13699. As we know, AO/AOCO table relies on the last_sequence to generate a new first row number to a new var block, this value will store in the heap table gp_fastsequence. Whenever we generate a new variable-length storage block, we need to obtain a continuous row number from the gp_fastsequence table as the first row number of the var block, and also as the unique identifier of the tuple when creating an index. So, the row number should not be same and not reuse deleted tuple's row number. Therefore, Greenplum must ensure that row numbers are not repeated and always increment. But sub-transaction will break it: begin; create table t (a int, b int) with (appendonly = true); insert into t values (1, 1); savepoint sub; truncate table t; insert into t values (2, 2); rollback to sub; abort; After finished truncate table t;, the table's auxiliary table, such as pg_aoseg.pg_aoseg_<OID> and visitmap will have a new relation file node. This will lead to generating a new last_sequence in gp_fastsequence when we do INSERT next, and this can not rollback. So if we want to fix this problem, we should let table gp_fastsequence can be rollback as other auxiliary tables in transaction.
Bug Report
Greenplum version or build
master 59eb923
OS version and uname -a
Linux 3.10.0-1160.49.1.el7.x86_64 #1 SMP Tue Nov 30 15:51:32 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
autoconf options used ( config.status --config )
Installation information ( pg_config )
Expected behavior
no duplicate gp_fastsequence value (ctid) appears in ao table
Actual behavior
duplicate gp_fastsequence value (ctid) appears in ao table
Step to reproduce the behavior
panic with index
The text was updated successfully, but these errors were encountered: