Skip to content

Commit a95e3d8

Browse files
committed
BRIN autosummarization may need a snapshot
It's possible to define BRIN indexes on functions that require a snapshot to run, but the autosummarization feature introduced by commit 7526e10 fails to provide one. This causes autovacuum to leave a BRIN placeholder tuple behind after a failed work-item execution, making such indexes less efficient. Repair by obtaining a snapshot prior to running the task, and add a test to verify this behavior. Author: Álvaro Herrera <[email protected]> Reported-by: Giovanni Fabris <[email protected]> Reported-by: Arthur Nascimento <[email protected]> Backpatch-through: 13 Discussion: https://postgr.es/m/[email protected]
1 parent c09a069 commit a95e3d8

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/backend/postmaster/autovacuum.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,9 @@ do_autovacuum(void)
25562556
workitem->avw_active = true;
25572557
LWLockRelease(AutovacuumLock);
25582558

2559+
PushActiveSnapshot(GetTransactionSnapshot());
25592560
perform_work_item(workitem);
2561+
PopActiveSnapshot();
25602562

25612563
/*
25622564
* Check for config changes before acquiring lock for further jobs.

src/test/modules/brin/t/01_workitems.pl

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,61 @@
2424
create index brin_wi_idx on brin_wi using brin (a) with (pages_per_range=1, autosummarize=on);
2525
'
2626
);
27+
# Another table with an index that requires a snapshot to run
28+
$node->safe_psql(
29+
'postgres',
30+
'create table journal (d timestamp) with (fillfactor = 10);
31+
create function packdate(d timestamp) returns text language plpgsql
32+
as $$ begin return to_char(d, \'yyyymm\'); end; $$
33+
returns null on null input immutable;
34+
create index brin_packdate_idx on journal using brin (packdate(d))
35+
with (autosummarize = on, pages_per_range = 1);
36+
'
37+
);
38+
2739
my $count = $node->safe_psql('postgres',
2840
"select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
2941
);
30-
is($count, '1', "initial index state is correct");
42+
is($count, '1', "initial brin_wi_index index state is correct");
43+
$count = $node->safe_psql('postgres',
44+
"select count(*) from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)"
45+
);
46+
is($count, '1', "initial brin_packdate_idx index state is correct");
3147

3248
$node->safe_psql('postgres',
3349
'insert into brin_wi select * from generate_series(1, 100)');
50+
$node->safe_psql('postgres',
51+
"insert into journal select * from generate_series(timestamp '1976-08-01', '1976-10-28', '1 day')"
52+
);
53+
54+
# Give a little time for autovacuum to react. This matches the naptime
55+
# configured above.
56+
sleep(1);
3457

3558
$node->poll_query_until(
3659
'postgres',
3760
"select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)",
3861
't');
3962

40-
$count = $node->safe_psql('postgres',
41-
"select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
63+
$count = $node->safe_psql(
64+
'postgres',
65+
"select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)
66+
where not placeholder;"
67+
);
68+
cmp_ok($count, '>', '1', "$count brin_wi_idx ranges got summarized");
69+
70+
$node->poll_query_until(
71+
'postgres',
72+
"select count(*) > 1 from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)",
73+
't');
74+
75+
$count = $node->safe_psql(
76+
'postgres',
77+
"select count(*) from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)
78+
where not placeholder;"
4279
);
43-
is($count, 't', "index got summarized");
80+
cmp_ok($count, '>', '1', "$count brin_packdate_idx ranges got summarized");
81+
4482
$node->stop;
4583

4684
done_testing();

0 commit comments

Comments
 (0)