Ответ
Replication slots в PostgreSQL — это механизм, который гарантирует, что WAL-логи (Write-Ahead Logs) не будут удалены до тех пор, пока они не будут получены всеми репликами. Их мониторинг критически важен для предотвращения заполнения диска.
1. Основной запрос для просмотра слотов:
-- Показать все слоты репликации с основной информацией
SELECT * FROM pg_replication_slots;
-- Структурированный вывод с ключевыми метриками
SELECT
slot_name,
plugin,
slot_type,
active,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS replication_lag_bytes,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag_pretty,
confirmed_flush_lsn,
restart_lsn,
wal_status,
safe_wal_size
FROM pg_replication_slots
ORDER BY replication_lag_bytes DESC NULLS LAST;
2. Мониторинг лага репликации:
-- Лаг в байтах для каждого слота
SELECT
slot_name,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS lag_bytes,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag_human
FROM pg_replication_slots
WHERE active = true;
-- Мониторинг с предупреждениями (для интеграции в системы мониторинга)
SELECT
slot_name,
CASE
WHEN pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) > 1073741824 THEN 'CRITICAL: >1GB lag'
WHEN pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) > 536870912 THEN 'WARNING: >512MB lag'
ELSE 'OK'
END AS status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS current_lag
FROM pg_replication_slots
WHERE active = true;
3. Проверка использования диска WAL-логами:
-- Оценка, сколько WAL хранится из-за слотов
SELECT
slot_name,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
) AS retained_wal,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) *
(SELECT setting::numeric FROM pg_settings WHERE name = 'wal_segment_size')
/ 16777216
) AS estimated_disk_usage
FROM pg_replication_slots
WHERE restart_lsn IS NOT NULL;
4. Управление слотами (административные операции):
-- Создание физического слота репликации
SELECT * FROM pg_create_physical_replication_slot('replica_slot_1');
-- Создание логического слота для логической репликации
SELECT * FROM pg_create_logical_replication_slot('logical_slot_1', 'pgoutput');
-- Принудительное продвижение restart_lsn (осторожно!)
SELECT pg_replication_slot_advance('slot_name', '0/FFFFFFF');
-- Удаление слота (только если реплика больше не нужна)
SELECT pg_drop_replication_slot('slot_name');
5. Интеграция с мониторингом (пример скрипта для Prometheus):
#!/bin/bash
# Скрипт для сбора метрик replication slots
PGHOST="localhost"
PGPORT=5432
PGDATABASE="postgres"
PGUSER="monitoring_user"
QUERY="
SELECT
'pg_replication_slot_lag_bytes{slot="' || slot_name || '"}' AS metric,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS value
FROM pg_replication_slots
WHERE active = true AND restart_lsn IS NOT NULL
UNION ALL
SELECT
'pg_replication_slots_total',
COUNT(*)::text
FROM pg_replication_slots
"
psql -h $PGHOST -p $PGPORT -U $PGUSER -d $PGDATABASE
-t -A -F " " -c "$QUERY" 2>/dev/null | while read metric value; do
echo "$metric $value"
done
6. Автоматизация очистки застрявших слотов:
-- Найти неактивные слоты старше N дней
SELECT slot_name, active, xmin
FROM pg_replication_slots
WHERE active = false
AND (now() - pg_stat_file('pg_wal/' ||
pg_walfile_name(restart_lsn))::timestamp) > interval '7 days';
-- Процедура для безопасного удаления старых неактивных слотов
CREATE OR REPLACE PROCEDURE cleanup_stale_replication_slots(max_age_days INT DEFAULT 7)
LANGUAGE plpgsql
AS $$
DECLARE
slot_record RECORD;
BEGIN
FOR slot_record IN
SELECT slot_name
FROM pg_replication_slots
WHERE active = false
AND (now() - pg_stat_file('pg_wal/' ||
pg_walfile_name(restart_lsn))::timestamp) >
(max_age_days || ' days')::interval
LOOP
RAISE NOTICE 'Dropping stale replication slot: %', slot_record.slot_name;
PERFORM pg_drop_replication_slot(slot_record.slot_name);
END LOOP;
END;
$$;
-- Вызов процедуры
CALL cleanup_stale_replication_slots(7);
Критические моменты для DevOps:
- Мониторинг lag: Лаг больше 1GB может указывать на проблемы с сетью или производительностью реплики
- Дисковое пространство: Каждый незавершенный слот удерживает WAL-логи, что может заполнить диск
- Активность слотов: Неактивные слоты (
active = false) часто указывают на проблемы с подключением реплики - Резервные копии: При использовании PITR (Point-in-Time Recovery) слоты могут конфликтовать с
archive_cleanup_command
Рекомендации по настройке:
- Установите
max_slot_wal_keep_sizeдля ограничения удерживаемых WAL-логов - Настройте алертинг при превышении лага (например, > 100GB)
- Регулярно проверяйте неактивные слоты и удаляйте ненужные
- Используйте логические слоты для логической репликации только когда это действительно необходимо