- •Предисловие
- •Об этой книге
- •Глава 1. Обзор статистики
- •Внутреннее устройство PostgreSQL
- •Установка соединений и работа сеансов
- •Запросы как базовая единица рабочей нагрузки
- •Планирование и выполнение запросов
- •Ввод-вывод при выполнении запросов
- •Журнал сообщений СУБД
- •Репликация изменений
- •Архивирование журнала предзаписи
- •Фоновая синхронизация данных
- •Автоочистка
- •Интерфейс статистики
- •Статистика как отправная точка инструментов мониторинга
- •Особенности статистики
- •Тестовое окружение
- •Глава 2. Статистика активности
- •Ключ к пониманию происходящего в СУБД
- •Взаимодействие клиента и сервера
- •Источники информации об активности
- •Представление pg_stat_activity
- •Представление pg_locks
- •Особенности pg_stat_activity и pg_locks
- •Представление pg_stat_database
- •Подключенные клиенты
- •Отслеживание клиентских сеансов
- •Транзакционная активность
- •Статусы завершения сеансов
- •Состояния сеансов
- •Отслеживание состояний
- •Ожидания и блокировки
- •Отслеживание состояний с учетом ожиданий
- •Взаимоблокировки
- •Бездействующие транзакции
- •Время выполнения запросов и транзакций
- •Отслеживание времени ожидания блокировок
- •Использование pg_locks.waitstart
- •Использование pg_stat_activity.state_change
- •Дерево блокировок
- •Глава 3. Выполнение запросов и функций
- •Зачем нужен мониторинг запросов
- •Расширение pg_stat_statements
- •Метаданные запроса
- •Планирование запроса
- •Исполнение запроса
- •Сквозная идентификация с queryid
- •Построение отчетов на основе pg_stat_statements
- •Представление pg_stat_statements_info
- •Выполнение процедур и функций
- •Глава 4. Базы данных
- •Иерархия объектов СУБД
- •Кластер баз данных
- •Табличные пространства
- •Базы данных
- •Схемы
- •Таблицы и индексы
- •TOAST
- •События в кластере баз данных
- •Рабочая нагрузка в отношении таблиц и индексов
- •Ошибки и нежелательные события
- •Функции для работы с объектами СУБД
- •Определение размеров объектов СУБД
- •Размещение объектов в файловой системе
- •Глава 5. Область общей памяти и ввод-вывод
- •Анализ общей памяти
- •Представление pg_buffercache
- •Представление pg_shmem_allocations
- •Анализ памяти клиентских процессов
- •Оценка использования SLRU-кешей
- •Ввод-вывод в контексте объектов СУБД
- •Базы данных
- •Ввод-вывод в контексте выполнения запросов
- •Временные файлы
- •Уровень баз данных
- •Ввод-вывод при выполнении запросов
- •Отслеживание в журнале сообщений
- •Отслеживание активных временных файлов
- •Ввод-вывод фоновых процессов
- •Глава 6. Журнал упреждающей записи
- •Отслеживание активности в журнале
- •Представление pg_stat_wal
- •Представление pg_stat_statements
- •Архивирование журнала
- •Представление pg_stat_archiver
- •Очередь архивирования
- •Глава 7. Репликация
- •Обзор репликации
- •Инструменты отслеживания репликации
- •Представление pg_stat_replication
- •Представление pg_stat_wal_receiver
- •Cлоты репликации и pg_replication_slots
- •Публикации и подписки
- •Конфликты восстановления
- •Глава 8. Очистка
- •Введение в очистку
- •Особенности очистки на практике
- •Когда выполняется автоочистка?
- •Статистика выполнения очистки
- •Счетчик транзакций и предотвращение ошибок, связанных с его зацикливанием
- •Раздувание таблиц и индексов
- •Отслеживание активных процессов очистки
- •Представление pg_stat_activity
- •Представление pg_stat_progress_vacuum
- •Глава 9. Ход выполнения операций
- •Представление pg_stat_progress_analyze
- •Представление pg_stat_progress_basebackup
- •Представление pg_stat_progress_cluster
- •Представление pg_stat_progress_create_index
- •Представление pg_stat_progress_copy
- •Предметный указатель
190Глава 7. Репликация
приводит к ошибке.Автоматическое разрешение конфликтов отсутствует; процесс синхронизации или применения изменений останавливается и требует ручного вмешательства администратора. Чтобы таких конфликтов не возникало, при начальной синхронизации таблицы на стороне подписчика должны быть пустыми, а при действующей репликации следует избегатьвнесенияизмененийнасторонеподписки.Нодажеприсоблюденииэтихусловийполезно отслеживать появление ошибок с помощью представления pg_stat_subscription_stats, в котором есть следующие поля:
•subid,subname—уникальный идентификатор и имя подписки;
•apply_error_count — общее количество ошибок, возникших при применении изменений в режиме действующей репликации;
•sync_error_count—общее количество ошибок,возникших во время начальной синхронизации таблиц;
•stats_reset—отметка времени сброса этой статистики.
Когда механизм публикаций и подписок был добавлен, подобные ошибки фиксировались только в журнале сообщений,который приходилось обрабатывать и анализировать.После добавления pg_stat_subscription_stats отслеживать подобные ошибки стало проще.
7.3. Конфликты восстановления
Один из сценариев применения физической репликации связан с распределением нагрузки таким образом, что часть запросов от приложений выполняются на основном узле, а часть запросов (на чтение) — на репликах, благодаря чему более эффективно используются вычислительные ресурсы всего кластера СУБД.
В процессе воспроизведения изменений на реплике,выполняющей нагрузку на чтение,существуетвероятностьтого,чтоприменениеочереднойжурнальнойзаписиприведеткневозможности продолжить выполнение запроса. Такая ситуация называется конфликтом восстановления (recovery conflict). Перед СУБД встает вопрос: продолжить выполнение запроса, но при этом остановить процесс применения изменений (то есть приостановить репликацию), или отменить запрос и применить изменения. СУБД поступает следующим образом: применение измененийприостанавливаетсянавеличинуmax_standby_streaming_delay (поумолчанию30секунд),чтобыдатьзапросувозможностьвыполниться.Еслизапроснеуспелвыполнитьсязаэто время, то СУБД принудительно завершает его и возобновляет применение изменений. Важно отметить, что во время отсчета этой задержки СУБД продолжает получать от основного узла новые журнальные записи, но не применяет их. В лучшем случае запросы, задерживающие репликацию,появляются редко и отставание,накопленное за время выполнения таких запросов, будет быстро наверстываться. В худшем же случае применение журнальных записей может постоянно откладываться из-за большого количества одновременно выполняемых запросов: в этом случае после завершения одного конфликтующего запросата же журнальная
7.3. Конфликты восстановления |
191 |
запись может вступить в конфликт уже со следующим запросом, из-за чего отставание может накапливаться.
В случае принудительной отмены запроса приложение получит ошибку, которая будет также зафиксирована в журнале сообщений:
ERROR: canceling statement due to conflict with recovery
DETAIL: User query might have needed to see row versions that must be removed.
Конфликты восстановления могут возникать и при восстановлении из архива, когда вместо потоковой репликации сегменты журнала копируются из WAL-архива.Втаком случае величина задержки определяется значением max_standby_archive_delay,по умолчанию равнымтем же 30 секундам.
Как поступать с такими ошибками, зависит от бизнес-требований: важно определить, что является наименьшим из двух зол — отставание от основного узла или прерывание запросов. Если важно выполнение запросов без ошибок, то имеет смысл увеличить величину задержки max_standby_streaming_delay, что потенциально может приводить к еще большему отставанию реплики. Если же, наоборот, отставание реплики недопустимо (например, реплика является основным кандидатом для аварийного переключения), то ошибки можно игнорировать или обрабатывать их на стороне приложения, повторяя сбойные запросы на основном узле. Другим частым решением является использование отдельной реплики с очень большой величинойдопустимойзадержкиипотенциальнобольшимотставанием.Такаярепликаиспользуется преимущественно для выполнения продолжительных запросов и не участвует в процедурах аварийного переключения.
Помимо журнала сообщений, конфликты восстановления можно отследить с помощью pg_stat_database.conflicts: этот счетчик учитывает все типы конфликтов для каждой из существующих баз данных. Более детально причины конфликтов можно отследить в представленииpg_stat_database_conflicts.Этопредставлениеактуальнотолькодляреплик,поскольку конфликты происходят только там. Представление содержит список баз и счетчики для каждого типа конфликтов:
•datid,datname—уникальный идентификатор и имя базы данных;
•confl_tablespace — общее количество запросов, отмененных по причине удаления табличного пространства;
•confl_lock — общее количество запросов, отмененных по причине истечения тайм-аута блокировки;
•confl_snapshot—общее количество запросов,отмененных по причине устаревания снимка данных;
•confl_bufferpin — общее количество запросов, отмененных по причине закрепления буфера в общем кеше;
•confl_deadlock — общее количество запросов, отмененных по причине возникновения взаимоблокировки.
192Глава 7. Репликация
Обычно конфликты восстановления относят к ошибкам и при появлении ненулевых значений в pg_stat_database.conflicts детали и причины конфликтов расследуются уже с помощью журнала сообщений (какие именно запросы вызвали конфликты) и представления pg_stat_database_conflicts (какие именно конфликты возникали).
Причинамиконфликтовмогутбытьразныесобытия,возникающиенаосновномузле.Напрактике чаще всего встречается отмена запросов из-за очистки: изменения, вызванные очисткой устаревших версий строк, попадают на реплику, в то время как на ней выполняется запрос, которому все еще нужны эти версии (счетчик confl_snapshot). Как правило, это продолжительные аналитические запросы,обрабатывающие большие объемыданных,из-за чего они могут выполняться непредсказуемо долго и требовать большого объема ресурсов. Отмена и повторение таких запросов может обходиться дорого как по ресурсам, так и по времени ожидания результата. Для уменьшения вероятности отмены запросов есть две меры, которые можно принимать как по отдельности, так и вместе. Первая — это увеличение величины допустимой задержи max_standby_streaming_delay. Вторая — включение обратной связи hot_standby_feedback. С помощью обратной связи процесс walsender будет получать от реплики необходимый ей горизонт и учитывать его при удалении устаревших версий строк (этот горизонт виден в pg_stat_replication.backend_xmin, если слот не используется, или в pg_replication_slots.xmin, если используется). В этом случае конфликтующих изменений не возникнет (подробно о том, что такое транзакционный горизонт, можно узнать в главе 8, посвященной очистке). Однако ни один из этих способов не дает 100% гарантии, что запрос будет выполнен, и оказывают определенное негативное влияние. Увеличение задержки может приводить к росту отставания, но, если время выполнения запроса превысит задержку, запросвсеравнобудетотменен(вкрайнемслучаеможнозаставитьрепликуждатьбесконечно, установив значение параметра в −1). Обратная связь гарантирует защиту только от очистки, но за счет откладывания очистки таблицы будут раздуваться; кроме того, остаются и другие причины, по которым могут произойти конфликт и последующая отмена запроса. Поэтому идеального решения проблемы не существует и следует отталкиваться от бизнес-требований о допустимости отмены запросов и возможной величине отставания. В качестве компромиссного решения для аналитических запросов можно сделать отдельную реплику с большим значениемдопустимойзадержки,нонеиспользоватьееввыборахосновногоузла.Тогдабольшое отставание будет допустимо; при этом можно отказаться от использования обратной связи и минимизировать эффекты раздувания.
Резюме
•Репликация практически всегда используется в производственной среде.
•Репликация работает на основе передачи WAL-журнала.
•Репликация бывает физической и логической.
•pg_stat_replication—основной инструмент отслеживания репликации.
Резюме 193
•Для отслеживания репликации на репликах используется pg_stat_wal_receiver.
•Отставание репликации—самая часто возникающая проблема.
•Величину отставания можно измерять в байтах или секундах.
•Слоты репликации позволяют исключить риск необратимого отставания реплик, но добавляют риск исчерпания места на диске.
•Для отслеживания слотов репликации используется представление pg_replication_slots.
•Логическая репликация использует модель публикаций и подписок.
•Для отслеживания слотов логической репликации можно использовать представление pg_stat_replication_slots.
•Для отслеживания подписок можно использовать представления pg_stat_subscription
и pg_stat_subscription_stats.
•Конфликты восстановления могут возникать при выполнении запросов на репликах.
•Для отслеживания конфликтов восстановления можно использовать представления pg_stat_database и pg_stat_database_conflicts.
