Environment
- PostgreSQL v13
- wal disk 10GB
- max_wal_size 30MB
Preparation
パブリッシャ
walは8.3G余りの状態
# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/mapper/xlog 10G 1.8G 8.3G 18% /test/pg_wal
テスト用のテーブルを作成する。
CREATE TABLE test.test_publication_table ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, data TEXT );
パブリケーションを作成する。
CREATE PUBLICATION test_publication FOR TABLE test.test_publication_table;
サブスクライバ
サブスクリプションを作成する。
CREATE SUBSCRIPTION test_subscription CONNECTION 'host=xxx dbname=xxx user=xxx password=xxx port=xxx application_name=test_subscription' PUBLICATION test_publication;
レプリケーションがasyncであることを確認する。
select * from pg_stat_replication; pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_ lag | replay_lag | sync_priority | sync_state | reply_time ------+----------+-----------+---------------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+------- ----+------------+---------------+------------+------------------------------- 2663 | 16445 | xxx | test_subscription | xxx | | 44270 | 2024-09-20 19:19:29.591677+09 | | streaming | 2/2C0000D8 | 2/2C0000D8 | 2/2C0000D8 | 2/2C0000D8 | | | | 0 | async | 2024-09-20 19:19:59.739753+09
Testing
サブスクライバでサブスクリプションを無効化する。
alter subscription test_subscription disable;
パブリッシャでwalを600MBほど生成する
DO $$ DECLARE i INTEGER; BEGIN FOR i IN 1..10000 LOOP INSERT INTO test.test_publication_table (data) VALUES (repeat('test', 100)); END LOOP; END $$;
1000000レコード作成する、1レコードおよそ420byteあった。
SELECT pg_column_size(id) + pg_column_size(data) AS total_size FROM test.test_publication_table WHERE id = 'xxx'; total_size ------------ 420
レプリケーションスロットはスタンバイがwal segmentを受信するまでプライマリがwal segmentを削除しないようにする仕組みなので、レプリケーションを再開しない限りwalは増え続ける。そのため、サブスクライバとの接続断が続いた場合にwal diskが枯渇する可能性がある。
SELECT slot_name, database, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS replication_slot_size FROM pg_replication_slots; slot_name | database | replication_slot_size ---------------------------+----------+----------------------- test_subscription | test | 606 MB
レプリケーションスロットが存在する場合、スロットが参照しているWALファイルは削除されないため、max_wal_sizeの設定値にも依存しない。
レプリケーションの再開
サブスクリプションを有効化する。
alter subscription test_subscription enable;
10secほどでスロットのWALは転送された。
SELECT slot_name, database, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS replication_slot_size FROM pg_replication_slots; slot_name | database | replication_slot_size ---------------------------+----------+----------------------- test_subscription | xxx | 2778 kB