Здесь вы часто измеряете задержку клиент-сервер и выполнение PL / pgSQL.
Разница вызвана необходимостью синхронизации WAL с диском.
Если вы используетене заблокированная таблица, и вы не используете оператор LOCK
, WAL не записывается и ничего не должно синхронизироваться в COMMIT
время.
Явные блокировки таблицы приводят к тому, что запись WAL будетнаписано, поэтому COMMIT
все равно придется синхронизировать WAL, и вы потеряете преимущество, которое у вас есть от незарегистрированной таблицы.
Вы можете использовать pg_waldump
для проверки файлов WAL, тогда вы увидите, какой журнал транзакцийзаписи записаны.
Но я могу показать это вам с моим PostgreSQL v11, построенным с -DWAL_DEBUG
.
Это моя тестовая таблица:
postgres=# \d t
Unlogged table "public.t"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | integer | | |
ЗдесьINSERT
без LOCK TABLE
:
postgres=# SET wal_debug=on;
SET
postgres=# BEGIN;
BEGIN
postgres=# INSERT INTO t VALUES (100);
INSERT 0 1
postgres=# COMMIT;
LOG: INSERT @ 0/166BFB8: - Transaction/COMMIT: 2018-05-18 20:34:20.060635+02
STATEMENT: COMMIT;
COMMIT
Произошел коммит, но без сброса WAL.
postgres=# BEGIN;
BEGIN
postgres=# LOCK TABLE t;
LOG: INSERT @ 0/166C038: - Standby/LOCK: xid 569 db 13344 rel 16384
STATEMENT: LOCK TABLE t;
LOCK TABLE
postgres=# INSERT INTO t VALUES (101);
INSERT 0 1
postgres=# COMMIT;
LOG: INSERT @ 0/166C138: - Transaction/COMMIT: 2018-05-18 20:36:15.419081+02
STATEMENT: COMMIT;
LOG: xlog flush request 0/166C138; write 0/166BFF0; flush 0/166BFF0
STATEMENT: COMMIT;
COMMIT
Теперь у нас есть сброс WAL, и это дорогая часть.
Вы видите, что была записана запись Standby/LOCK
.
Один из способов обойти это уменьшить wal_level
до minimal
и max_wal_senders
до 0
, тогда эти записи WAL записывать не нужно.Но тогда у вас не будет возможности архивации WAL и восстановления на определенный момент времени.
Другой обходной путь - использовать более низкий уровень блокировки, чем ACCESS EXCLUSIVE
.Это должно быть хорошо, если вам абсолютно не нужно блокировать читателей.