Closed kaaveland closed 6 months ago
add_authors.sql
This is a human readable lock tracing and migration report generated by eugene to assist you in writing safer database migration scripts.
Here are some tips for reading it:
There is a summary section for the entire script at the start of the report and then a section for each statement in the script, that goes over the state of the database at the time the script was executed, as well as effects or hints specific to that particular statement
Started at | Total duration (ms) | Number of dangerous locks |
---|---|---|
2024-05-06T07:47:04.834292838+00:00 | 2 | 2 ❌ |
Schema | Object | Mode | Relkind | OID | Safe | Duration held (ms) |
---|---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ | 0 |
public |
books |
AccessShareLock |
Table | 16416 | ✅ | 0 |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ | 0 |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ | 0 |
AccessExclusiveLock
would block the following operations on public.books
:
SELECT
FOR UPDATE
FOR NO KEY UPDATE
FOR SHARE
FOR KEY SHARE
UPDATE
DELETE
INSERT
MERGE
ShareRowExclusiveLock
would block the following operations on public.books
:
UPDATE
DELETE
INSERT
MERGE
create table authors(id serial primary key, name text not null);
No locks held at the start of this statement.
No new locks taken by this statement.
alter table books alter column title set not null;
No locks held at the start of this statement.
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
NOT NULL
columnID: make_column_not_nullable_with_lock
The column title
in the table public.books
was changed to NOT NULL
. The statement blocks until all rows in the table are validated to be NOT NULL
, unless a CHECK (title IS NOT NULL)
constraint exists, in which case it is safe. Splitting this kind of change into 3 steps can make it safer:
CHECK (title IS NOT NULL) NOT VALID;
constraint.
ALTER TABLE ... VALIDATE CONSTRAINT
.NOT NULL
alter table books add column author_id integer not null;
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
No new locks taken by this statement.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
alter table books add foreign key (author_id) references authors(id);
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
ID: validate_constraint_with_lock
A new constraint books_author_id_fkey
was added to the table books
. The constraint is of type FOREIGN KEY
and is valid. The statement blocks until all rows in the table are validated for the constraint. It is safer to add constraints as NOT VALID
and validate them later, to avoid holding dangerous locks for a long time. Constraints that are NOT VALID
affect all new inserts and updates, but not existing data. Adding the constraint initially as NOT VALID
, then validating with ALTER TABLE ... VALIDATE CONSTRAINT ...
in a later transaction minimizes time spent holding dangerous locks.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
select * from books;
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 | ✅ |
No new locks taken by this statement.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
add_authors.sql
This is a human readable lock tracing and migration report generated by eugene to assist you in writing safer database migration scripts.
Here are some tips for reading it:
There is a summary section for the entire script at the start of the report and then a section for each statement in the script, that goes over the state of the database at the time the script was executed, as well as effects or hints specific to that particular statement
Started at | Total duration (ms) | Number of dangerous locks |
---|---|---|
2024-05-06T08:49:46.369337878+00:00 | 3 | 2 ❌ |
Schema | Object | Mode | Relkind | OID | Safe | Duration held (ms) |
---|---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ | 0 |
public |
books |
AccessShareLock |
Table | 16416 | ✅ | 0 |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ | 0 |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ | 0 |
AccessExclusiveLock
would block the following operations on public.books
:
SELECT
FOR UPDATE
FOR NO KEY UPDATE
FOR SHARE
FOR KEY SHARE
UPDATE
DELETE
INSERT
MERGE
ShareRowExclusiveLock
would block the following operations on public.books
:
UPDATE
DELETE
INSERT
MERGE
create table authors(id serial primary key, name text not null);
No locks held at the start of this statement.
No new locks taken by this statement.
alter table books alter column title set not null;
No locks held at the start of this statement.
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
NOT NULL
columnID: make_column_not_nullable_with_lock
The column title
in the table public.books
was changed to NOT NULL
. The statement blocks until all rows in the table are validated to be NOT NULL
, unless a CHECK (title IS NOT NULL)
constraint exists, in which case it is safe. Splitting this kind of change into 3 steps can make it safer:
CHECK (title IS NOT NULL) NOT VALID;
constraint.
ALTER TABLE ... VALIDATE CONSTRAINT
.NOT NULL
alter table books add column author_id integer not null;
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
No new locks taken by this statement.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
alter table books add foreign key (author_id) references authors(id);
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessExclusiveLock |
Table | 16416 | ❌ |
Schema | Object | Mode | Relkind | OID | Safe |
---|---|---|---|---|---|
public |
books |
AccessShareLock |
Table | 16416 | ✅ |
public |
books |
ShareRowExclusiveLock |
Table | 16416 | ❌ |
public |
books_pkey |
AccessShareLock |
Index | 16422 | ✅ |
ID: validate_constraint_with_lock
A new constraint books_author_id_fkey
was added to the table books
. The constraint is of type FOREIGN KEY
and is valid. The statement blocks until all rows in the table are validated for the constraint. It is safer to add constraints as NOT VALID
and validate them later, to avoid holding dangerous locks for a long time. Constraints that are NOT VALID
affect all new inserts and updates, but not existing data. Adding the constraint initially as NOT VALID
, then validating with ALTER TABLE ... VALIDATE CONSTRAINT ...
in a later transaction minimizes time spent holding dangerous locks.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
select * from books;
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 | ✅ |
No new locks taken by this statement.
AccessExclusiveLock
ID: holding_access_exclusive
The statement is running while holding an AccessExclusiveLock
on the Table public.books
, blocking all other transactions from accessing it. Once holding AccessExclusiveLock
we should immediately commit the transaction. Any extra steps necessary are better done in a separate transaction.
With --commit, we can run several concurrently-statements with auto-commit. Without, we still let it fail.
Add snapshot test for create index concurrently and testcase for tracer behaviour.