PostgreSQL

О теме

Индексы, транзакции, MVCC — почему план меняется и куда деваются мёртвые строки.

Лекции

PostgreSQL
N+1, JOIN и prepared statements

N+1 — это N сетевых кругов вместо одного запроса, а не «сложная сортировка в планировщике». JOIN или батч-preload лечат чтение. Prepared statement снимает parse на горячем пути и не заменяет индекс.

PostgreSQL
Пул соединений и PgBouncer

Каждое клиентское соединение в PostgreSQL — отдельный серверный процесс. Лимит max_connections невелик. Пул в приложении и PgBouncer решают разные этажи одной задачи.

PostgreSQL
WAL, replay, лаг реплики и failover

WAL — журнал изменений: локальная durability и канал для физической реплики. Асинхронная реплика отстаёт. Failover — это promote и то, как клиенты найдут новый primary, а не «перезапустили под».

PostgreSQL
EXPLAIN ANALYZE: Seq Scan, Index Scan, buffers

EXPLAIN показывает оценку планировщика. EXPLAIN ANALYZE выполняет запрос и даёт фактические цифры. Читают actual rows против planned, тип узла и буферы, а не «стрелочки красивого дерева».

PostgreSQL
Блокировки строк, FOR UPDATE, deadlock

MVCC не отменяет локи писателей. FOR UPDATE берёт row lock без изменения данных. При тупике PostgreSQL прерывает одну транзакцию. Не держите лок, пока ходите в сеть.

PostgreSQL
MVCC, xmin/xmax, vacuum и bloat

UPDATE в PostgreSQL не переписывает строку на месте: появляется новая версия, старая жива, пока её кто-то может видеть. Vacuum подбирает мёртвое. Долгая транзакция удерживает горизонт и раздувает bloat.

PostgreSQL
Read Committed, Repeatable Read, Serializable

По умолчанию в PostgreSQL — Read Committed. Repeatable Read здесь это snapshot isolation. Serializable ловит write skew ценой ретраев по serialization_failure.

PostgreSQL
ACID коротко: зачем транзакция

Транзакция задаёт границу «всё или ничего» для нескольких изменений. ACID описывает свойства этой границы, а не магию изоляции и не бизнес-инварианты приложения.

PostgreSQL
Составной индекс и leftmost prefix

Индекс (a, b, c) работает как телефонная книга: сначала a, потом b. Без ведущей колонки классический B-tree почти бесполезен для поиска.

PostgreSQL
B-tree индексы, Seq Scan и covering

B-tree — индекс по умолчанию в PostgreSQL. Seq Scan не ошибка: на малой таблице или при низкой селективности он дешевле. Covering-индекс с INCLUDE даёт шанс на Index Only Scan.