1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Reduce lock levels for ALTER TABLE SET autovacuum storage options

Reduce lock levels down to ShareUpdateExclusiveLock for all autovacuum-related
relation options when setting them using ALTER TABLE.

Add infrastructure to allow varying lock levels for relation options in later
patches. Setting multiple options together uses the highest lock level required
for any option. Works for both main and toast tables.

Fabrízio Mello, reviewed by Michael Paquier, mild edit and additional regression
tests from myself
This commit is contained in:
Simon Riggs
2015-08-14 14:19:28 +01:00
parent f16d52269a
commit 47167b7907
6 changed files with 219 additions and 43 deletions

View File

@ -1914,19 +1914,19 @@ select * from my_locks order by 1;
commit;
begin; alter table alterlock set (toast.autovacuum_enabled = off);
select * from my_locks order by 1;
relname | max_lockmode
-----------+---------------------
alterlock | AccessExclusiveLock
pg_toast | AccessExclusiveLock
relname | max_lockmode
-----------+--------------------------
alterlock | ShareUpdateExclusiveLock
pg_toast | ShareUpdateExclusiveLock
(2 rows)
commit;
begin; alter table alterlock set (autovacuum_enabled = off);
select * from my_locks order by 1;
relname | max_lockmode
-----------+---------------------
alterlock | AccessExclusiveLock
pg_toast | AccessExclusiveLock
relname | max_lockmode
-----------+--------------------------
alterlock | ShareUpdateExclusiveLock
pg_toast | ShareUpdateExclusiveLock
(2 rows)
commit;
@ -1938,6 +1938,16 @@ select * from my_locks order by 1;
(1 row)
rollback;
-- test that mixing options with different lock levels works as expected
begin; alter table alterlock set (autovacuum_enabled = off, fillfactor = 80);
select * from my_locks order by 1;
relname | max_lockmode
-----------+---------------------
alterlock | AccessExclusiveLock
pg_toast | AccessExclusiveLock
(2 rows)
commit;
begin; alter table alterlock alter column f2 set storage extended;
select * from my_locks order by 1;
relname | max_lockmode
@ -2006,6 +2016,47 @@ select * from my_locks order by 1;
alterlock_pkey | AccessShareLock
(4 rows)
rollback;
create or replace view my_locks as
select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode
from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
where transactionid = txid_current()::integer)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname = 'my_locks'
group by c.relname;
-- raise exception
alter table my_locks set (autovacuum_enabled = false);
ERROR: unrecognized parameter "autovacuum_enabled"
alter view my_locks set (autovacuum_enabled = false);
ERROR: unrecognized parameter "autovacuum_enabled"
alter table my_locks reset (autovacuum_enabled);
alter view my_locks reset (autovacuum_enabled);
begin;
alter view my_locks set (security_barrier=off);
select * from my_locks order by 1;
relname | max_lockmode
----------+---------------------
my_locks | AccessExclusiveLock
(1 row)
alter view my_locks reset (security_barrier);
rollback;
-- this test intentionally applies the ALTER TABLE command against a view, but
-- uses a view option so we expect this to succeed. This form of SQL is
-- accepted for historical reasons, as shown in the docs for ALTER VIEW
begin;
alter table my_locks set (security_barrier=off);
select * from my_locks order by 1;
relname | max_lockmode
----------+---------------------
my_locks | AccessExclusiveLock
(1 row)
alter table my_locks reset (security_barrier);
rollback;
-- cleanup
drop table alterlock2;

View File

@ -1332,6 +1332,11 @@ begin; alter table alterlock alter column f2 set (n_distinct = 1);
select * from my_locks order by 1;
rollback;
-- test that mixing options with different lock levels works as expected
begin; alter table alterlock set (autovacuum_enabled = off, fillfactor = 80);
select * from my_locks order by 1;
commit;
begin; alter table alterlock alter column f2 set storage extended;
select * from my_locks order by 1;
rollback;
@ -1365,6 +1370,39 @@ alter table alterlock2 validate constraint alterlock2nv;
select * from my_locks order by 1;
rollback;
create or replace view my_locks as
select case when c.relname like 'pg_toast%' then 'pg_toast' else c.relname end, max(mode::lockmodes) as max_lockmode
from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
where transactionid = txid_current()::integer)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname = 'my_locks'
group by c.relname;
-- raise exception
alter table my_locks set (autovacuum_enabled = false);
alter view my_locks set (autovacuum_enabled = false);
alter table my_locks reset (autovacuum_enabled);
alter view my_locks reset (autovacuum_enabled);
begin;
alter view my_locks set (security_barrier=off);
select * from my_locks order by 1;
alter view my_locks reset (security_barrier);
rollback;
-- this test intentionally applies the ALTER TABLE command against a view, but
-- uses a view option so we expect this to succeed. This form of SQL is
-- accepted for historical reasons, as shown in the docs for ALTER VIEW
begin;
alter table my_locks set (security_barrier=off);
select * from my_locks order by 1;
alter table my_locks reset (security_barrier);
rollback;
-- cleanup
drop table alterlock2;
drop table alterlock;