수집을 위한 WAL과 체크포인트 조정
I/O 정체 없이 높은 쓰기 속도를 유지하도록 WAL 설정과 로그 기록 제외 테이블을 조정하는 방법을 배웁니다.
수집을 위한 WAL과 체크포인트 조정은(는) CoddyKit의 무료 PostgreSQL Performance & Query Optimization 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 PostgreSQL Performance & Query Optimization 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. PostgreSQL Performance & Query Optimization 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Why WAL Matters for Ingestion
Every change you commit in PostgreSQL is first written to the Write-Ahead Log (WAL) before the data files are updated. This guarantees durability and crash recovery, but during heavy bulk loads the WAL becomes a major source of I/O.
- Each
INSERTorCOPYgenerates WAL records. - Periodically a checkpoint flushes dirty pages from shared buffers to disk.
- If checkpoints fire too often, you pay double I/O and get stalls.
Tuning WAL and checkpoint behaviour is the key to sustaining high write rates without I/O spikes.
Inspecting Current WAL Settings
Before changing anything, look at what your server is running with. The relevant knobs live in pg_settings and can be queried with SHOW.
The most important ingestion-related parameters are max_wal_size, checkpoint_timeout, checkpoint_completion_target, and wal_compression.
SELECT name, setting, unit
FROM pg_settings
WHERE name IN (
'max_wal_size',
'min_wal_size',
'checkpoint_timeout',
'checkpoint_completion_target',
'wal_compression'
);Raising max_wal_size
A checkpoint is triggered either by checkpoint_timeout elapsing or by WAL volume reaching max_wal_size. During a big load the default (often 1 GB) is hit constantly, forcing checkpoint after checkpoint.
- Raising
max_wal_sizelets WAL accumulate longer between checkpoints. - Fewer checkpoints means dirty pages get coalesced and written once instead of repeatedly.
For an ingestion window, values like 8–32 GB are common.
ALTER SYSTEM SET max_wal_size = '16GB';
SELECT pg_reload_conf();Spreading Checkpoint I/O
checkpoint_completion_target controls how much of the interval PostgreSQL uses to spread out the checkpoint writes. A value of 0.9 means the writes are smeared across 90% of the time until the next checkpoint, avoiding a sharp I/O burst.
Combined with a longer checkpoint_timeout, this turns spiky checkpoint storms into a smooth, sustained write stream.
ALTER SYSTEM SET checkpoint_timeout = '30min';
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
SELECT pg_reload_conf();Compressing WAL Records
When full-page images are written after a checkpoint (the first modification of a page), they bloat the WAL. wal_compression compresses those full-page images, trading a little CPU for substantially less WAL volume and disk I/O.
- On modern PostgreSQL you can choose the algorithm, e.g.
lz4orzstd. - Less WAL written also means faster replication and fewer checkpoints from the size trigger.
ALTER SYSTEM SET wal_compression = 'lz4';
SELECT pg_reload_conf();Unlogged Tables: Skip the WAL Entirely
An unlogged table writes no WAL at all. For staging tables in an ETL pipeline this can dramatically increase throughput, because you bypass the single biggest write cost.
- Data is still written to disk, but not durably logged.
- Trade-off: the table is truncated automatically after a crash and is not replicated to standbys.
Perfect for re-buildable staging data; never for the system of record.
CREATE UNLOGGED TABLE staging_events (
id bigint,
payload jsonb,
loaded_at timestamptz DEFAULT now()
);The Staging-to-Final Pattern
A robust ETL design loads raw rows into a fast unlogged staging table, transforms them, then moves the cleaned result into the durable final table.
- The bulk
COPYhits the unlogged table at full speed. - The final
INSERT ... SELECTwrites WAL only once, for validated data.
You get speed where durability does not matter and safety where it does.
INSERT INTO events (id, payload, loaded_at)
SELECT id, payload, loaded_at
FROM staging_events
WHERE payload IS NOT NULL;
TRUNCATE staging_events;Promoting an Unlogged Table
If a staging table needs to become durable after the load completes, you can convert it in place instead of copying rows. Setting it to LOGGED rewrites the table and begins WAL-logging it.
- The conversion itself generates WAL for the whole table, so do it once at the end.
- Going back to
UNLOGGEDbefore the next load avoids per-row WAL again.
ALTER TABLE staging_events SET LOGGED;COPY Beats Row-by-Row INSERT
Even with WAL tuned, how you load matters. COPY batches rows into far fewer, larger WAL records than thousands of individual INSERT statements, and avoids per-statement parse and plan overhead.
Combine COPY with an unlogged staging table and you reach the highest sustainable ingest rate.
COPY staging_events (id, payload)
FROM '/data/events.csv'
WITH (FORMAT csv, HEADER true);Monitoring Checkpoint Pressure
To know whether your tuning worked, watch the checkpoint statistics. The key signal is the ratio of requested (size-triggered) checkpoints to timed ones.
- Many
requestedcheckpoints meansmax_wal_sizeis still too small for your load. - Mostly
timedcheckpoints means WAL volume is comfortably within budget.
In newer versions these counters live in pg_stat_checkpointer; older versions use pg_stat_bgwriter.
SELECT num_timed, num_requested,
buffers_written, write_time, sync_time
FROM pg_stat_checkpointer;Resetting After the Load
Aggressive ingestion settings are great during a load window but waste recovery time and disk afterwards. Once the batch finishes, restore conservative values and force a clean checkpoint so the next crash recovery is fast.
- Lower
max_wal_sizeandcheckpoint_timeoutback to steady-state values. - Run a manual
CHECKPOINTto flush everything immediately.
ALTER SYSTEM SET max_wal_size = '2GB';
ALTER SYSTEM SET checkpoint_timeout = '5min';
SELECT pg_reload_conf();
CHECKPOINT;Quick Check
You are bulk-loading 200 million rows into a re-buildable staging table that will be validated and copied into the durable table afterward. Which choice most directly reduces WAL write volume during the load?
Recap
To sustain high write rates without I/O stalls:
- Raise max_wal_size and checkpoint_timeout so checkpoints fire less often, and set checkpoint_completion_target near 0.9 to spread the writes.
- Enable wal_compression to shrink full-page images.
- Use UNLOGGED staging tables to skip WAL for re-buildable data, then move validated rows into the durable table.
- Prefer COPY over row-by-row inserts.
- Monitor
pg_stat_checkpointerfor requested-vs-timed checkpoints, and reset conservative values after the load.
자주 묻는 질문
“수집을 위한 WAL과 체크포인트 조정” 강의는 무료인가요?
네 — “수집을 위한 WAL과 체크포인트 조정” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 PostgreSQL Performance & Query Optimization 강의 전체를 잠금 해제할 수 있습니다. PostgreSQL Performance & Query Optimization 강의에는 총 4개의 강의가 포함되어 있습니다.
“수집을 위한 WAL과 체크포인트 조정”에서 뭘 배우나요?
I/O 정체 없이 높은 쓰기 속도를 유지하도록 WAL 설정과 로그 기록 제외 테이블을 조정하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 PostgreSQL Performance & Query Optimization을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
PostgreSQL Performance & Query Optimization을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 PostgreSQL Performance & Query Optimization은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“수집을 위한 WAL과 체크포인트 조정” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 PostgreSQL Performance & Query Optimization 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 PostgreSQL Performance & Query Optimization 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- COPY와 다중 행 INSERT 처리량 비교
- 로드 중 인덱스와 제약 조건 지연
- 수집을 위한 WAL과 체크포인트 조정
- ON CONFLICT를 활용한 대규모 업서트