การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต
ติดตามการเก็บรักษา WAL ในสล็อตจำลองแบบ เพื่อป้องกันการใช้ดิสก์บนระบบหลักเพิ่มขึ้นอย่างควบคุมไม่ได้
การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต เป็นบทเรียน PostgreSQL Performance & Query Optimization ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน PostgreSQL Performance & Query Optimization และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส PostgreSQL Performance & Query Optimization มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
Why Slots Can Eat Your Disk
Logical replication slots make subscribers durable: the primary will retain WAL until every active slot has confirmed it consumed the changes. That guarantee is the same mechanism that can fill your data disk.
- A slot that is inactive (consumer down, network split, slow apply) pins WAL forever.
- WAL accumulates in
pg_wal/, the partition fills, and the primary can stop accepting writes.
This lesson is about observing that retention early, before it becomes an outage. The core question is always: how far behind is each slot, in bytes?
The Authoritative View: pg_replication_slots
Every slot is visible in pg_replication_slots. The columns that matter for bloat are active, restart_lsn, and on PostgreSQL 13+ the retention bookkeeping columns wal_status and safe_wal_size.
restart_lsn— the oldest LSN the slot still needs; WAL before it can be recycled.active— whether a consumer is currently connected.wal_status—reserved,extended,unreserved, orlost.
SELECT slot_name,
slot_type,
active,
restart_lsn,
wal_status,
safe_wal_size
FROM pg_replication_slots
ORDER BY active, slot_name;Measuring Retention in Bytes
The single most useful number is the gap between the current WAL write position and each slot's restart_lsn. That difference is the WAL the primary is forced to keep just for that slot.
LSNs are pg_lsn values; subtracting two of them yields bytes. Wrap it with pg_size_pretty() for human-readable output.
SELECT slot_name,
active,
pg_size_pretty(
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
) AS retained_wal
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC;Distinguishing Flush Lag from Slot Bloat
Two different lags are often confused:
- Replication lag — how far behind the consumer is right now. Visible on the primary in
pg_stat_replicationas the gap betweensent_lsn,flush_lsn, andreplay_lsn. - Slot bloat — how much WAL is physically retained because of a slot, whether or not a consumer is connected.
A healthy, connected replica can have near-zero bloat but transient lag. A disconnected slot has zero live lag (no row in pg_stat_replication) yet unbounded bloat. Always check both views.
Live Lag from pg_stat_replication
For currently connected standbys and logical subscribers, pg_stat_replication exposes per-connection lag in bytes. Compute the write/flush/replay distances against the sender's current WAL position.
The state column (streaming, catchup) and the time-based write_lag/flush_lag/replay_lag intervals tell you whether the consumer is keeping up.
SELECT application_name,
client_addr,
state,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn)) AS pending_send,
pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) AS apply_backlog,
write_lag,
flush_lag,
replay_lag
FROM pg_stat_replication
ORDER BY apply_backlog DESC;Reading wal_status: reserved, extended, lost
Since PostgreSQL 13, max_slot_wal_keep_size caps how much WAL a slot may force the primary to retain. The wal_status column reports where each slot sits relative to that cap:
reserved— withinmax_wal_size, safe.extended— exceedingmax_wal_sizebut still undermax_slot_wal_keep_size.unreserved— past the cap; WAL is being removed and the slot may soon be invalidated.lost— required WAL was already removed; the slot is permanently broken and its consumer must reseed.
safe_wal_size tells you how many bytes can still be written before the slot risks becoming lost. A small or negative value is an urgent alert.
Capping Retention with max_slot_wal_keep_size
The defensive trade-off in logical replication architectures: do you protect the subscriber's durability or the primary's uptime? Setting max_slot_wal_keep_size chooses primary uptime — a stuck slot gets invalidated instead of filling the disk.
- Default
-1means unlimited retention (the dangerous default). - A concrete value (e.g.
10GB) bounds worst-case bloat per slot.
If a slot is invalidated, its subscriber loses its place and must be recreated and resynced — acceptable for ephemeral pipelines, not for a critical replica.
ALTER SYSTEM SET max_slot_wal_keep_size = '10GB';
SELECT pg_reload_conf();
SHOW max_slot_wal_keep_size;Confirmed Flush vs Restart LSN
Logical slots carry two LSNs worth distinguishing:
restart_lsn— the point from which decoding would have to restart; this is what pins WAL retention.confirmed_flush_lsn— the LSN the subscriber has acknowledged as durably applied.
The gap between confirmed_flush_lsn and restart_lsn exists because decoding must restart from the beginning of the oldest running transaction. A long-running transaction on the primary holds restart_lsn back even when the subscriber is fully caught up — a classic cause of stubborn bloat with no apparent lag.
SELECT slot_name,
confirmed_flush_lsn,
restart_lsn,
pg_size_pretty(
pg_wal_lsn_diff(confirmed_flush_lsn, restart_lsn)
) AS decode_restart_gap
FROM pg_replication_slots
WHERE slot_type = 'logical'
ORDER BY decode_restart_gap DESC;A Single Health Query for Alerting
For dashboards and alert rules, combine retention, activity, and WAL status into one row per slot. Flag any slot that is inactive while retaining significant WAL, or whose wal_status has left reserved.
Wire this query's severity output into your monitoring system (Prometheus exporter, cron + alert, etc.).
SELECT slot_name,
active,
wal_status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained,
CASE
WHEN wal_status IN ('unreserved', 'lost') THEN 'critical'
WHEN NOT active
AND pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) > 1073741824
THEN 'warning'
ELSE 'ok'
END AS severity
FROM pg_replication_slots
ORDER BY severity, retained DESC;Finding the Transaction That Pins the Slot
When bloat persists on a logical slot with a caught-up subscriber, the culprit is usually the oldest in-progress transaction holding the catalog xmin. Inspect catalog_xmin on the slot, then hunt the offending backend.
pg_replication_slots.catalog_xmin is the oldest transaction whose catalog changes must remain decodable. Long-lived transactions (forgotten BEGIN, idle-in-transaction sessions) keep it pinned.
SELECT pid,
state,
xact_start,
now() - xact_start AS xact_age,
left(query, 80) AS query
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL
OR state = 'idle in transaction'
ORDER BY xact_start
LIMIT 10;Dropping Orphaned Slots Safely
When a subscriber is gone for good (decommissioned pipeline, failed-over replica), its slot must be dropped or it will retain WAL indefinitely. A slot can only be dropped while inactive.
- Verify
active = falsefirst; dropping an active slot errors out. - Use
pg_drop_replication_slot()on the primary that owns the slot.
This is the fastest way to recover a disk that is filling because of a dead consumer — but it permanently breaks that subscriber, so confirm it is truly abandoned.
SELECT pg_drop_replication_slot(slot_name)
FROM pg_replication_slots
WHERE active = false
AND slot_name = 'sub_analytics_dead';Quick Check: Diagnosing the Bloat
A logical replication slot is retaining 40 GB of WAL. The subscriber is connected, pg_stat_replication shows replay_lag near zero, and state is streaming. What is the most likely cause of the retained WAL?
Recap: Keeping Slots Honest
You now have a full monitoring playbook for replication slot bloat:
- Retained WAL in bytes =
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)per slot — the number to alert on. - Two distinct signals: live lag in
pg_stat_replicationvs physical retention inpg_replication_slots. A dead slot has no live lag but unbounded bloat. - wal_status (
reserved→extended→unreserved→lost) andsafe_wal_sizeshow how close a slot is to invalidation. - max_slot_wal_keep_size bounds worst-case bloat, trading subscriber durability for primary uptime.
- Stubborn bloat with zero lag usually means a long-running transaction pinning
restart_lsn/catalog_xmin— find it inpg_stat_activity. - Orphaned slots must be dropped with
pg_drop_replication_slot()once confirmed inactive.
เรียนรู้ SQL ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 22
- บทเรียน
- 88
คำถามที่พบบ่อย
บทเรียน “การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส PostgreSQL Performance & Query Optimization ให้อัปเกรดเป็น CoddyKit PRO คอร์ส PostgreSQL Performance & Query Optimization มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต”
ติดตามการเก็บรักษา WAL ในสล็อตจำลองแบบ เพื่อป้องกันการใช้ดิสก์บนระบบหลักเพิ่มขึ้นอย่างควบคุมไม่ได้ คุณปฏิบัติ PostgreSQL Performance & Query Optimization ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน PostgreSQL Performance & Query Optimization หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน PostgreSQL Performance & Query Optimization บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน PostgreSQL Performance & Query Optimization นี้ได้ไหม
ได้ บทเรียน PostgreSQL Performance & Query Optimization ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สิ่งพิมพ์ การสมัครรับข้อมูล และอัตลักษณ์ของแบบจำลอง
- การถ่ายโอนภาระงานอ่านและวิเคราะห์
- การอัปเกรดเวอร์ชันหลักโดยแทบไม่หยุดให้บริการ
- การตรวจสอบความล่าช้าของการจำลองแบบและการพองตัวของสล็อต