10 потоков • претензии к базе — медленно работает • в мониторинге чуть более 1 потока — где-то узкое место • по факту — все проводки имеют контрагентом счёт компании
свойства A, C, I — сериалисериализация транзакций через двухфазовые блокировки (2PL)PL) • 2PL)PL проста в реализации, однако полностью блокирует доступ к ресурсу при записи
ждать блокировку • писатели не блокируют читателей • писатели сериализуются по 2PL)PL • MVCC в терминах в PostgreSQL, добавлено в версии 6.5 (Июнь, 1999)
Xmin и Xmax • необходимо “морозить” старые записи, т.к. 4 миллиарда транзакций — сериалиэто быстро • версии только в хипе (UNDO) ) • необходимость вакуумирования • множественные ссылки в индексах
записи — не надо выключать или даже тормозить вакуум • негативный эффект от долгих транзакций — сериалистрогий контроль с принудительным завершением • множественные ссылки в индексах — сериалинеобходимо следить за “здоровьем” индексов
пишущие запросы конкурируют за одинаковые ресурсы (2PL)PL) • база хранит блокировки записей в заголовке записи или в MultiXact структуре • FOR [NO KEY] UPDATE • FOR [KEY] SHARE
• FOR UPDATE SKIP LOCKED для параллельной обработки • очередь неудобна для MVCC • рекомендуется использовать несколько таблиц в ротации, с TRUNCATE после переключения • лучше всего рассмотреть готовые решения — PGQ
от пишущей активности • снимок зависит от уровня изоляции • READ COMMITTED проще для базы, но приводит к аномалиям • REPEATABLE READ и SERIALIZABLE избавляют от аномалий, но сложнее и возвращают ошибки при нарушении сериализации
данные, результаты могут отличатся в пределах транзакции • REPEATABLE READ используется pg_dump-ом для снятия логического снимка базы • подходит для сложных отчётов и выгрузки данных • пишущие запросы при конфликте видимости обрываются ошибкой сериализации
READ; UPDATE c SET color='black' WHERE color='white'; COMMIT; -- committed -- 2 BEGIN ISOLATION LEVEL REPEATABLE READ; UPDATE c SET color='white' WHERE color='black'; COMMIT; -- committed
color='black' WHERE color='white'; -- -- wait for other transaction to commit -- postgres=# COMMIT; ERROR: could not serialize access due to read/write dependencies among transactions DETAIL: Reason code: Canceled on identification as a pivot, during commit attempt. HINT: The transaction might succeed if retried.
pg_stat_activity -- WHERE (clock_timestamp() - pg_stat_activity.xact_start) >'00:00:00.1'::interval AND pg_stat_activity.pid<>pg_backend_pid() -- ORDER BY coalesce(pg_stat_activity.xact_start, pg_stat_activity.query_start); • http://bit.do/db_activity
b_id=1; . INSERT INTO a VALUES (3, 'Drei', now()); . UPDATE b SET b_name='The One' WHERE b_id=1; . . DELETE FROM a WHERE a_id=1; . ALTER TABLE a DROP CONSTRAINT p_a; . DROP TABLE b; • http://bit.do/locktree