-
Notifications
You must be signed in to change notification settings - Fork 1
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
Detect table rewrites #40
Conversation
9dcf607
to
99a6eba
Compare
Eugene 🔒 trace report of
|
Started at | Total duration (ms) | Number of dangerous locks |
---|---|---|
2024-05-10T22:08:00.529153772+00:00 | 4 | 2 ❌ |
All locks found
Schema | Object | Mode | Relkind | OID | Safe | Duration held (ms) |
---|---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books |
AccessShareLock |
Table | 16416 | ✅ | 1 |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ | 1 |
Dangerous locks found
AccessExclusiveLock
would block the following operations onpublic.books
:SELECT
FOR UPDATE
FOR NO KEY UPDATE
FOR SHARE
FOR KEY SHARE
UPDATE
DELETE
INSERT
MERGE
ShareRowExclusiveLock
would block the following operations onpublic.books
:UPDATE
DELETE
INSERT
MERGE
Statement number 1 for 3 ms
SQL
create table authors(id serial primary key, name text not null)
Locks at start
No locks held at the start of this statement.
New locks taken
No new locks taken by this statement.
Statement number 2 for 0 ms
SQL
alter table books alter column title set not null
Locks at start
No locks held at the start of this statement.
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
Hints
Validating table with a new NOT NULL
column
ID: E2
A column was changed from NULL
to NOT NULL
. This blocks all table access until all rows are validated. A safer way is: Add a CHECK
constraint as NOT VALID
, validate it later, then make the column NOT NULL
.
The column title
in the table public.books
was changed to NOT NULL
. If there is a CHECK (title IS NOT NULL)
constraint on public.books
, this is safe. Splitting this kind of change into 3 steps can make it safe:
- Add a
CHECK (title IS NOT NULL) NOT VALID;
constraint onpublic.books
. - Validate the constraint in a later transaction, with
ALTER TABLE public.books VALIDATE CONSTRAINT ...
. - Make the column
NOT NULL
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took AccessExclusiveLock
on the Table public.books
without a timeout. It blocks SELECT
, FOR UPDATE
, FOR NO KEY UPDATE
, FOR SHARE
, FOR KEY SHARE
, UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 3 for 0 ms
SQL
alter table books add column author_id integer not null
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Statement number 4 for 1 ms
SQL
alter table books add foreign key (author_id) references authors(id)
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
Hints
Validating table with a new constraint
ID: E1
A new constraint was added and it is already VALID
. This blocks all table access until all rows are validated. A safer way is: Add the constraint as NOT VALID
and validate it with ALTER TABLE ... VALIDATE CONSTRAINT
later.
A new constraint books_author_id_fkey
of type FOREIGN KEY
was added to the table public.books
as VALID
. Constraints that are NOT VALID
can be made VALID
by ALTER TABLE public.books VALIDATE CONSTRAINT books_author_id_fkey
which takes a lesser lock.
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took ShareRowExclusiveLock
on the Table public.books
without a timeout. It blocks UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 5 for 0 ms
SQL
select * from books
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Eugene 🔒 trace report of
|
Started at | Total duration (ms) | Number of dangerous locks |
---|---|---|
2024-05-10T22:11:45.458000205+00:00 | 4 | 2 ❌ |
All locks found
Schema | Object | Mode | Relkind | OID | Safe | Duration held (ms) |
---|---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books |
AccessShareLock |
Table | 16416 | ✅ | 1 |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ | 1 |
Dangerous locks found
AccessExclusiveLock
would block the following operations onpublic.books
:SELECT
FOR UPDATE
FOR NO KEY UPDATE
FOR SHARE
FOR KEY SHARE
UPDATE
DELETE
INSERT
MERGE
ShareRowExclusiveLock
would block the following operations onpublic.books
:UPDATE
DELETE
INSERT
MERGE
Statement number 1 for 3 ms
SQL
create table authors(id serial primary key, name text not null)
Locks at start
No locks held at the start of this statement.
New locks taken
No new locks taken by this statement.
Statement number 2 for 0 ms
SQL
alter table books alter column title set not null
Locks at start
No locks held at the start of this statement.
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
Hints
Validating table with a new NOT NULL
column
ID: E2
A column was changed from NULL
to NOT NULL
. This blocks all table access until all rows are validated. A safer way is: Add a CHECK
constraint as NOT VALID
, validate it later, then make the column NOT NULL
.
The column title
in the table public.books
was changed to NOT NULL
. If there is a CHECK (title IS NOT NULL)
constraint on public.books
, this is safe. Splitting this kind of change into 3 steps can make it safe:
- Add a
CHECK (title IS NOT NULL) NOT VALID;
constraint onpublic.books
. - Validate the constraint in a later transaction, with
ALTER TABLE public.books VALIDATE CONSTRAINT ...
. - Make the column
NOT NULL
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took AccessExclusiveLock
on the Table public.books
without a timeout. It blocks SELECT
, FOR UPDATE
, FOR NO KEY UPDATE
, FOR SHARE
, FOR KEY SHARE
, UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 3 for 0 ms
SQL
alter table books add column author_id integer not null
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Statement number 4 for 1 ms
SQL
alter table books add foreign key (author_id) references authors(id)
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
Hints
Validating table with a new constraint
ID: E1
A new constraint was added and it is already VALID
. This blocks all table access until all rows are validated. A safer way is: Add the constraint as NOT VALID
and validate it with ALTER TABLE ... VALIDATE CONSTRAINT
later.
A new constraint books_author_id_fkey
of type FOREIGN KEY
was added to the table public.books
as VALID
. Constraints that are NOT VALID
can be made VALID
by ALTER TABLE public.books VALIDATE CONSTRAINT books_author_id_fkey
which takes a lesser lock.
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took ShareRowExclusiveLock
on the Table public.books
without a timeout. It blocks UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 5 for 0 ms
SQL
select * from books
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Eugene 🔒 trace report of
|
Started at | Total duration (ms) | Number of dangerous locks |
---|---|---|
2024-05-10T22:18:26.946574551+00:00 | 4 | 2 ❌ |
All locks found
Schema | Object | Mode | Relkind | OID | Safe | Duration held (ms) |
---|---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books |
AccessShareLock |
Table | 16416 | ✅ | 1 |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ | 1 |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ | 1 |
Dangerous locks found
AccessExclusiveLock
would block the following operations onpublic.books
:SELECT
FOR UPDATE
FOR NO KEY UPDATE
FOR SHARE
FOR KEY SHARE
UPDATE
DELETE
INSERT
MERGE
ShareRowExclusiveLock
would block the following operations onpublic.books
:UPDATE
DELETE
INSERT
MERGE
Statement number 1 for 3 ms
SQL
create table authors(id serial primary key, name text not null)
Locks at start
No locks held at the start of this statement.
New locks taken
No new locks taken by this statement.
Statement number 2 for 0 ms
SQL
alter table books alter column title set not null
Locks at start
No locks held at the start of this statement.
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
Hints
Validating table with a new NOT NULL
column
ID: E2
A column was changed from NULL
to NOT NULL
. This blocks all table access until all rows are validated. A safer way is: Add a CHECK
constraint as NOT VALID
, validate it later, then make the column NOT NULL
.
The column title
in the table public.books
was changed to NOT NULL
. If there is a CHECK (title IS NOT NULL)
constraint on public.books
, this is safe. Splitting this kind of change into 3 steps can make it safe:
- Add a
CHECK (title IS NOT NULL) NOT VALID;
constraint onpublic.books
. - Validate the constraint in a later transaction, with
ALTER TABLE public.books VALIDATE CONSTRAINT ...
. - Make the column
NOT NULL
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took AccessExclusiveLock
on the Table public.books
without a timeout. It blocks SELECT
, FOR UPDATE
, FOR NO KEY UPDATE
, FOR SHARE
, FOR KEY SHARE
, UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 3 for 0 ms
SQL
alter table books add column author_id integer not null
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Statement number 4 for 1 ms
SQL
alter table books add foreign key (author_id) references authors(id)
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
New locks taken
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
Hints
Validating table with a new constraint
ID: E1
A new constraint was added and it is already VALID
. This blocks all table access until all rows are validated. A safer way is: Add the constraint as NOT VALID
and validate it with ALTER TABLE ... VALIDATE CONSTRAINT
later.
A new constraint books_author_id_fkey
of type FOREIGN KEY
was added to the table public.books
as VALID
. Constraints that are NOT VALID
can be made VALID
by ALTER TABLE public.books VALIDATE CONSTRAINT books_author_id_fkey
which takes a lesser lock.
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Taking dangerous lock without timeout
ID: E9
A lock that would block many common operations was taken without a timeout. This can block all other operations on the table indefinitely if any other transaction holds a conflicting lock while idle in transaction
or active
. A safer way is: Run SET LOCAL lock_timeout = '2s';
before the statement and retry the migration if necessary.
The statement took ShareRowExclusiveLock
on the Table public.books
without a timeout. It blocks UPDATE
, DELETE
, INSERT
, MERGE
while waiting to acquire the lock.
Statement number 5 for 0 ms
SQL
select * from books
Locks at start
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
New locks taken
No new locks taken by this statement.
Hints
Running more statements after taking AccessExclusiveLock
ID: E4
A transaction that holds an AccessExclusiveLock
started a new statement. This blocks all access to the table for the duration of this statement. A safer way is: Run this statement in a new transaction.
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it.
Should solve #3 -- we're tracking
oid => relfilenodeid
frompg_class
now, to discover if any table or index was moved to a new location on disk in our transaction, which would indicate it was rewritten.This will trigger on things like:
int => bigint
VACUUM FULL
,REINDEX
,CLUSTER
TRUNCATE
ALTER TABLE ... ADD COLUMN NOT NULL DEFAULT fn()
wherefn()
isVOLATILE