Bootstrap

PostgreSQL 清理 WAL 文件

PostgreSQL WAL 文件如何清理

随着系统的运行,特别是在启动 PostgreSQL 特有的发布订阅功能之后,如果下游的消费出现问题之后,WAL 文件目录就会非常的大,遇到过对应的案例。因此这篇文章介绍下如何有效的清理 WAL 目录文件。

假设我使用以下的命令创建了对应的发布:
SELECT * FROM pg_create_logical_replication_slot ('test_slot','wal2json');
SELECT * FROM pg_create_logical_replication_slot ('cdc_slot', 'decoder_raw');
SELECT * FROM pg_create_logical_replication_slot ('cdc_slot', 'pgoutput');

这里的输出插件可以根据下游消费的不同选择不同的输出。我对接过好几种输出。如果是这种引起的 WAL 目录过大,那你可以删除对应的发布然后重建发布,让下游消费重新去获取并查找问题为啥消费断了。
SELECT * FROM pg_drop_replication_slot ('test_slot');

说明:那有人说了,我怎么知道我的发布的名称呢,我们可以通过查询 pg_publication 获取对应的分布的名称。
SELECT * FROM pg_publication;

| 名称 |  描述 |
| `oid`  | 行标识符 |
| `pubname` | publication 的名称 |
| `pubowner` | publication 的拥有者 |
| `puballtables`  | 如果为真,这个 publication 自动包括数据库中的所有表,包括未来将会创建的任何表。 |
| `pubinsert`  | 如果为真,为 publication 中的表复制 `INSERT` 操作。 |
| `pubupdate`  | 如果为真,为 publication 中的表复制 `UPDATE` 操作。 |
| `pubdelete`  | 如果为真,为 publication 中的表复制 `DELETE` 操作。 |
| `pubtruncate`  | 如果为真,为 publication 中的表复制 `TRUNCATE` 操作。 |

上面我们讲了基于发布订阅的 WAL 目录大的原因,下面我们说一下另外一种情况如果清理。wal_keep_size = 0(14 版本) 或者是老版本的 wal_keep_segments (12 版本)
由于新旧版本关于保留 WAL 会有不同的选项参数实现,所以主要是这两个参数决定了保留的 WAL 文件的个数的多少。

下面我以案例 14 为例
[postgres@anolisos140 data]$ /usr/local/pgsql-14/bin/pg_controldata -D /usr/local/pgsql-14/data/
pg_control version number:            1300
Catalog version number:               202107181
Database system identifier:           7395399726573516091
Database cluster state:               in production
pg_control last modified:             Thu 08 Aug 2024 03:02:01 PM CST
Latest checkpoint location:           0/B530E40
Latest checkpoint's REDO location:    0/B530E08
Latest checkpoint's REDO WAL file:    00000001000000000000000B
Latest checkpoint's TimeLineID:       1
Latest checkpoint's PrevTimeLineID:   1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID:          0:9136
Latest checkpoint's NextOID:          33717
Latest checkpoint's NextMultiXactId:  1
Latest checkpoint's NextMultiOffset:  0
Latest checkpoint's oldestXID:        726
Latest checkpoint's oldestXID's DB:   1
Latest checkpoint's oldestActiveXID:  9136
Latest checkpoint's oldestMultiXid:   1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:0
Latest checkpoint's newestCommitTsXid:0
Time of latest checkpoint:            Thu 08 Aug 2024 03:02:01 PM CST
Fake LSN counter for unlogged rels:   0/3E8
Minimum recovery ending location:     0/0
Min recovery ending loc's timeline:   0
Backup start location:                0/0
Backup end location:                  0/0
End-of-backup record required:        no
wal_level setting:                    logical
wal_log_hints setting:                on
max_connections setting:              500
max_worker_processes setting:         8
max_wal_senders setting:              10
max_prepared_xacts setting:           1000
max_locks_per_xact setting:           64
track_commit_timestamp setting:       off
Maximum data alignment:               8
Database block size:                  8192
Blocks per segment of large relation: 131072
WAL block size:                       8192
Bytes per WAL segment:                16777216
Maximum length of identifiers:        64
Maximum columns in an index:          32
Maximum size of a TOAST chunk:        1996
Size of a large-object chunk:         2048
Date/time type storage:               64-bit integers
Float8 argument passing:              by value
Data page checksum version:           0
Mock authentication nonce:            824f8f3d1e7a76176b56f67dff2316018806cb99db272e5e8c715c6feed10a11
[postgres@anolisos140 data]$

在上面的信息中有一行信息:Latest checkpoint's REDO WAL file:    00000001000000000000000B 这里表示在这个 WAL 文件之前的文件我们都可以进行清理。

[postgres@anolisos140 data]$ /usr/local/pgsql-14/bin/pg_archivecleanup -d /usr/local/pgsql-14/data/pg_wal 00000001000000000000000B

;