mirror of
https://github.com/postgres/postgres.git
synced 2025-12-17 00:03:29 -05:00
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 7526e10224f0 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 <alvherre@kurilemu.de> Reported-by: Giovanni Fabris <giovanni.fabris@icon.it> Reported-by: Arthur Nascimento <tureba@gmail.com> Backpatch-through: 13 Discussion: https://postgr.es/m/202511031106.h4fwyuyui6fz@alvherre.pgsql
This commit is contained in:
parent
c09a06918d
commit
a95e3d84c0
@ -2556,7 +2556,9 @@ deleted:
|
|||||||
workitem->avw_active = true;
|
workitem->avw_active = true;
|
||||||
LWLockRelease(AutovacuumLock);
|
LWLockRelease(AutovacuumLock);
|
||||||
|
|
||||||
|
PushActiveSnapshot(GetTransactionSnapshot());
|
||||||
perform_work_item(workitem);
|
perform_work_item(workitem);
|
||||||
|
PopActiveSnapshot();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for config changes before acquiring lock for further jobs.
|
* Check for config changes before acquiring lock for further jobs.
|
||||||
|
|||||||
@ -24,23 +24,61 @@ $node->safe_psql(
|
|||||||
create index brin_wi_idx on brin_wi using brin (a) with (pages_per_range=1, autosummarize=on);
|
create index brin_wi_idx on brin_wi using brin (a) with (pages_per_range=1, autosummarize=on);
|
||||||
'
|
'
|
||||||
);
|
);
|
||||||
|
# Another table with an index that requires a snapshot to run
|
||||||
|
$node->safe_psql(
|
||||||
|
'postgres',
|
||||||
|
'create table journal (d timestamp) with (fillfactor = 10);
|
||||||
|
create function packdate(d timestamp) returns text language plpgsql
|
||||||
|
as $$ begin return to_char(d, \'yyyymm\'); end; $$
|
||||||
|
returns null on null input immutable;
|
||||||
|
create index brin_packdate_idx on journal using brin (packdate(d))
|
||||||
|
with (autosummarize = on, pages_per_range = 1);
|
||||||
|
'
|
||||||
|
);
|
||||||
|
|
||||||
my $count = $node->safe_psql('postgres',
|
my $count = $node->safe_psql('postgres',
|
||||||
"select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
|
"select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
|
||||||
);
|
);
|
||||||
is($count, '1', "initial index state is correct");
|
is($count, '1', "initial brin_wi_index index state is correct");
|
||||||
|
$count = $node->safe_psql('postgres',
|
||||||
|
"select count(*) from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)"
|
||||||
|
);
|
||||||
|
is($count, '1', "initial brin_packdate_idx index state is correct");
|
||||||
|
|
||||||
$node->safe_psql('postgres',
|
$node->safe_psql('postgres',
|
||||||
'insert into brin_wi select * from generate_series(1, 100)');
|
'insert into brin_wi select * from generate_series(1, 100)');
|
||||||
|
$node->safe_psql('postgres',
|
||||||
|
"insert into journal select * from generate_series(timestamp '1976-08-01', '1976-10-28', '1 day')"
|
||||||
|
);
|
||||||
|
|
||||||
|
# Give a little time for autovacuum to react. This matches the naptime
|
||||||
|
# configured above.
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
$node->poll_query_until(
|
$node->poll_query_until(
|
||||||
'postgres',
|
'postgres',
|
||||||
"select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)",
|
"select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)",
|
||||||
't');
|
't');
|
||||||
|
|
||||||
$count = $node->safe_psql('postgres',
|
$count = $node->safe_psql(
|
||||||
"select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
|
'postgres',
|
||||||
|
"select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)
|
||||||
|
where not placeholder;"
|
||||||
);
|
);
|
||||||
is($count, 't', "index got summarized");
|
cmp_ok($count, '>', '1', "$count brin_wi_idx ranges got summarized");
|
||||||
|
|
||||||
|
$node->poll_query_until(
|
||||||
|
'postgres',
|
||||||
|
"select count(*) > 1 from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)",
|
||||||
|
't');
|
||||||
|
|
||||||
|
$count = $node->safe_psql(
|
||||||
|
'postgres',
|
||||||
|
"select count(*) from brin_page_items(get_raw_page('brin_packdate_idx', 2), 'brin_packdate_idx'::regclass)
|
||||||
|
where not placeholder;"
|
||||||
|
);
|
||||||
|
cmp_ok($count, '>', '1', "$count brin_packdate_idx ranges got summarized");
|
||||||
|
|
||||||
$node->stop;
|
$node->stop;
|
||||||
|
|
||||||
done_testing();
|
done_testing();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user