Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Troubleshooting PostgreSQL Streaming Replication

Alexey Lesovsky
November 07, 2017

Troubleshooting PostgreSQL Streaming Replication

Slides from my talk at Highload++ 2017 Moscow, Russia.
http://www.highload.ru/2017/abstracts/2937

Alexey Lesovsky

November 07, 2017

Transcript

53 slides
  1. План Немного теории или как работает постгресовая репликация. Troubleshooting tools

    или что есть у PostgreSQL и сообщества. Troubleshooting cases — симптомы, проблемы, диагностика, решения. Итоги, вопросы — ответы.
  2. Зачем всё это? Для лучшего понимания потоковой репликации. Научиться быстро

    находить и устранять проблемы. https://www.slideshare.net/alexeylesovsky/presentations
  3. План Немного теории или как работает постгресовая репликация. Troubleshooting tools

    или что есть у PostgreSQL и сообщества. Troubleshooting cases — симптомы, проблемы, диагностика, решения. Итоги, вопросы — ответы.
  4. Немного теории Write-Ahead Log (XLOG) — история всех изменений в

    БД. • Бэкенды синхронно пишут все изменения в XLOG; • Либо это делает WAL writer асинхронно. Каталог pg_xlog/ (pg_wal/) в $DATADIR. Потоковая репликация основана на XLOG.
  5. Немного теории Write-Ahead Log (XLOG) — история всех изменений в

    БД. почти;) • Бэкенды синхронно пишут все изменения в XLOG; • Либо это делает WAL writer асинхронно. Каталог pg_xlog/ (pg_wal/) в $DATADIR. Потоковая репликация основана на XLOG.
  6. План Немного теории или как работает постгресовая репликация. Troubleshooting tools

    или что есть у PostgreSQL и сообщества. Troubleshooting cases — проблемы, симптомы и диагностика. Итоги, вопросы — ответы.
  7. Сторонние инструменты Top (procps) — утилизация CPU , load average,

    использование mem/swap. Iostat (sysstat), iotop — утилизация хранилища, per-process ввод/вывод. Nicstat — утилизация интерфейсов. pgCenter — статистика по репликации. Perf — подземные стуки.
  8. pg_waldump pg_waldump: • Декодирует XLOG в человеко-понятный формат; • Может

    врать при запущенном постгресе. • pg_waldump -f -p /wal_10 \ $(psql -qAtX -c "select pg_walfile_name(pg_current_wal_lsn())")
  9. План Немного теории или как работает постгресовая репликация. Troubleshooting tools

    или что есть у PostgreSQL и сообщества. Troubleshooting cases — проблемы, симптомы и диагностика. Итоги, вопросы — ответы.
  10. pg_stat_replication Column | Type | ------------------+--------------------------+ pid | integer |

    usesysid | oid | usename | name | application_name | text | client_addr | inet | client_hostname | text | client_port | integer | backend_start | timestamp with time zone | backend_xmin | xid | state | text | sent_lsn | pg_lsn | <-- Log Sequence Number — позиция внутри XLOG write_lsn | pg_lsn | flush_lsn | pg_lsn | replay_lsn | pg_lsn | write_lag | interval | <-- Отставание выраженное во времени flush_lag | interval | replay_lag | interval | sync_priority | integer | sync_state | text |
  11. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  12. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  13. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, <-- сеть? (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  14. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, <-- диски? (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  15. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, <-- диски? (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  16. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, <-- диски/CPU? (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  17. Лаги репликации # SELECT client_addr AS client, usename AS user,

    application_name AS name, state, sync_state AS mode, (pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) / 1024)::int as pending, (pg_wal_lsn_diff(sent_lsn,write_lsn) / 1024)::int as write, (pg_wal_lsn_diff(write_lsn,flush_lsn) / 1024)::int as flush, (pg_wal_lsn_diff(flush_lsn,replay_lsn) / 1024)::int as replay, (pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn))::int / 1024 as total_lag FROM pg_stat_replication; client | user | name | state | mode | pending | write | flush | replay | total_lag ---------+--------+-------------+-----------+-------+---------+-------+-------+--------+----------- 10.6.6.9 | repmgr | walreceiver | streaming | async | 0 | 0 | 0 | 410480 | 410480 10.6.6.7 | repmgr | walreceiver | streaming | async | 0 | 2845 | 95628 | 112552 | 211025 10.6.6.6 | repmgr | walreceiver | streaming | async | 0 | 0 | 3056 | 9496 | 12552 10.6.6.8 | repmgr | walreceiver | streaming | async | 847582 | 0 | 0 | 3056 | 850638
  18. Проверка гипотезы Сетевой лаг — nicstat. Проблемы в хранилище —

    iostat, iotop. Задержки восстановления — top, pg_stat_activity. Большой объем WAL: • pg_stat_activity, pg_stat_progress_vacuum; • pg_wal_lsn_diff().
  19. Варианты решения Большой объем WAL: • Уменьшить объем «изменений» в

    БД в единицу времени; • Уменьшить объем записи в WAL в целом: • full_page_writes = of; • Увеличить интервал между чекпоинтами.
  20. Распухание pg_wal/ Варианты проблем: • Тяжелый CRUD. • Забытый или

    неиспользуемый слот репликации. • Сломанная archive_command.
  21. Распухание pg_wal/ Экстренные меры (100% used space) • Отстрелить долгие

    CRUD запросы — pg_terminate_backend(); • Уменьшить reserved space ratio (ext filesystems); • Добавить еще места (LVM, ZFS, etc);
  22. Распухание pg_wal/ Экстренные меры (100% used space) • Отстрелить долгие

    CRUD запросы — pg_terminate_backend(); • Уменьшить reserved space ratio (ext filesystems); • Добавить еще места (LVM, ZFS, etc); • НИКОГДА НИЧЕГО НЕ УДАЛЯТЬ РУКАМИ ИЗ pg_xlog/, pg_wal/
  23. Распухание pg_wal/ Что делать дальше: • Снова проверить workload —

    CRUD. • Состояние репликации. • Уменьшить checkpoints_segments/max_wal_size, wal_keep_segments; • Удалить слот репликации или починить подписчика; • Починить WAL archiving; checkpoint, checkpoint, cheсkpoint...
  24. Конфликты восстановления Основные симптомы — ошибки в логах постгреса или

    приложения. • User was holding shared bufer pin for too long. • User query might have needed to see row versions that must be removed. • User was holding a relation lock for too long. • User was or might have been using tablespace that must be dropped. • User transaction caused bufer deadlock with recovery. • User was connected to a database that must be dropped.
  25. Проблемы репликации Решения: • Увеличить max_standby_streaming_delay (риск лага репликации); •

    Включить hot_standby_feedback (риск распухания таблиц/индексов); • Переписать долгие запросы; • Настроить выделенную реплику для долгих запросов.
  26. План Немного теории или как работает постгресовая репликация. Troubleshooting tools

    или что есть у PostgreSQL и сообщества. Troubleshooting cases — проблемы, симптомы и диагностика. Итоги, вопросы — ответы.
  27. Итоги Проблемы потоковой репликации всегда распределены между хостами Источниками проблем

    выступают: • Недостаток ресурсов, запросы, workload. Без мониторинга никак. Встроенные средства нужно знать и уметь.
  28. Links PostgreSQL official documentation – The Statistics Collector https://www.postgresql.org/docs/current/static/monitoring-stats.html PostgreSQL

    Mailing Lists (general, performance, hackers) https://www.postgresql.org/list/ PostgreSQL-Consulting company blog http://blog.postgresql-consulting.com Эти слайды: https://www.slideshare.net/alexeylesovsky/presentations

More Decks by Alexey Lesovsky

Other Decks in Education