English version is here
Этот FAQ основан на вопросах, заданных в Telegram-канале https://t.me/pgsql и ответах на них.
Главное, что нужно понять, это то, что deadlock всегда разруливается на стороне приложения и есть только 3 способа борьбы с ним:
- Приложение, чья транзакция завершилась аварийно должно уметь обрабатывать эту ситуацию и повторять запрос.
- Разные транзакции должны обновлять одни и те же данные в одном и том же порядке. В таком случае deadlock невозможен в принципе.
- Приложение блокирует все строки, которые оно собирается обновить, непосредственно перед обновлением.
virtualxid это "виртуальный" идентификатор транзакции, который состоит из pid бэкэнда и значения некоторого счётчика,
например "2/19". virtualxid назначается транзакции, которая не обновляла строки в базе данных а значит, ей не нужно
сохранять свой идентификатор в системных столбцах xmin
, xmax
. Делается это для того, чтобы 32 битный счётчик
"реальных" транзакций не закончился слишком быстро. Как только транзакция попытается обновить данные в базе данных
(или вызовет функцию txid_current()
) ей будет назначен реальный xid
.
- Официальная консольная утилита psql
- pgAdmin-III
- pgAdmin 4
- okmeter.io - предоставляет довольно подробную статистику, но платный и требует создания специального пользователя в БД и запуска демона, который отвечает за отправку статистики на сервис.
- vividcortex.com - похожий по набору функций сервис, кроме PostgreSQL поддерживает Redis, MongoDB и MySQL.
- OpsDash - ещё один онлайн сервис для мониторинга.
- pgwatch2 - гибкое Open-Source решение для мониторинга PostgreSQL
- PASH-Viewer - аналог ораклового Top Activity, написан на Java, см. Мониторим активные сессии PostgreSQL 10, как в Oracle
- pg_activity - консольное приложение (ncurses-based) для мониторинга текущих сессий в PostgreSQL
- pg_top - 'top' для PostgreSQL
Вставка данных будет происходить быстрее, если на таблице отсутствуют индексы и внешние ключи. Для того, чтобы загрузить данные в таблицу из файла, можно воспользоваться командой COPY. Если данные нужно сгенерировать "на лету", можно использовать функцию generate_series. Например:
create table test(id bigint);
insert into test select n from generate_series(1, 1000000000) n;
Для того, чтобы следить за ходом выполнения операции (и не только, см. Почему длинные транзакции это плохо?), можно разбить INSERT
на несколько или написать хранимую процедуру:
do $$
declare
i integer;
begin
for i in 1 .. 1000 loop
insert into test select n from generate_series(1, 1000000) n;
raise warning '% total rows inserted', i*1000000;
end loop;
end;
$$ language plpgsql;
- Препятствуют удалению ненужных строк автовакуумом
- Опасность переполнения счётчика транзакций.
- Блокировки.
- Ресуры - любые запросы потребляют ресурсы - CPU, диск, коннект к базе. Поддержание транзакции, хоть и виртуальной в нашем случае, тоже небесплатно.
- Длинные запросы на реплике могут уронить её - например, забить временными файлами диск.
- OLAP запросы будут плохо работать на нормализованных OLTP данных - обычно требуется много вычислений внутри запроса (это CPU) и много соединений таблиц (это диск). Также OLAP запросы часто требуют создания дополнительных индексов, которые также поддерживаются небесплатно.
- OLAP запросы поднимают мнгого данных в кеш и, соответственно, вымывают из кеша данные, нужные для выполнения OLTP запросов (не так критично на репликах, но нужно об этом помнить).
- При большой нагрузке на реплику она начивает отставать от мастера (WAL сегменты на реплике применяются всегда один поток), а при синхронной репликации начинают появляться задержки при коммитах на мастере.
Подробнее см. Are Long Running Transactions Bad? и Why avoid long transactions?.
- Есть слот репликации, который препятствует удалению WAL файлов, проверить это можно следующим запросом:
SELECT slot_name,
lpad((pg_control_checkpoint()).timeline_id::text, 8, '0') ||
lpad(split_part(restart_lsn::text, '/', 1), 8, '0') ||
lpad(substr(split_part(restart_lsn::text, '/', 2), 1, 2), 8, '0')
AS wal_file
FROM pg_replication_slots;
- Включено архивирование WAL, но команда
archive_command
не отрабатывает корректно (см. логи) - Количество файлов в
pg_xlog
ещё не превысило значение параметраwal_keep_segments
- По какой-либо причине долгое время не происходит
chekpoint
(например, из-за ошибки)
Проанализировать вывод:
\dx+ <extension-name>