当达到 max_wal_size 以上后,Postgresql 无法归档 WAL
我已经使用 crunchydata
k8s 运算符部署了 PostgreSQL(v13)。
目前我发现 max_wal_size
是 1GB
使用:
DB=# show max_wal_size;
max_wal_size
--------------
1GB
(1 row)
但当前的 /pgdata/pg13_wal
大小是 4.9Gi
。为什么 PostgreSQL 无法归档 wal
并减少 wal
大小。
日志
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: 100
max_worker_processes setting: 8
max_wal_senders setting: 10
max_prepared_xacts setting: 0
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: 1
I have deployed PostgreSQL(v13) using crunchydata
k8s operator.
currently I found max_wal_size
is 1GB
using:
DB=# show max_wal_size;
max_wal_size
--------------
1GB
(1 row)
But the current /pgdata/pg13_wal
size is 4.9Gi
. Why PostgreSQL cannot archive wal
and reduce wal
size.
Logs
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: 100
max_worker_processes setting: 8
max_wal_senders setting: 10
max_prepared_xacts setting: 0
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: 1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
max_wal_size 是让 WAL 在自动检查点期间增长的最大大小。这是一个软限制;在特殊情况下,例如重负载、archive_command 失败或 wal_keep_size 设置较高,WAL 大小可能会超过 max_wal_size。如果指定该值时没有单位,则以兆字节为单位。默认值为 1 GB。增加此参数可以增加崩溃恢复所需的时间。该参数只能在 postgresql.conf 文件或服务器命令行中设置。
The max_wal_size is Maximum size to let the WAL grow during automatic checkpoints. This is a soft limit; WAL size can exceed max_wal_size under special circumstances, such as heavy load, a failing archive_command, or a high wal_keep_size setting. If this value is specified without units, it is taken as megabytes. The default is 1 GB. Increasing this parameter can increase the amount of time needed for crash recovery. This parameter can only be set in the postgresql.conf file or on the server command line.
Postgres 中的 max_wal_size 参数被描述为软限制,以帮助防止 WAL 变得太大。默认值为 1024 MB(参数以 MB 为单位设置)。这并不是很多。
当达到这个值时,它基本上会通知 Postgres 执行检查点并将缓冲区中的所有数据刷新到磁盘。一旦检查点完成,那些本来可以在缓冲区中的数据的 WAL 段就可以被删除。完成检查点可能需要一些时间,因为 Postgres 确实需要等待事务完成。因此是软限制。
检查站的费用并不便宜。管理员倾向于将时间段保持相对较长,以最大限度地提高吞吐量。但另一方面,如果数据库发生故障,您的恢复时间取决于 WAL 的大小,您必须重播该 WAL 才能恢复数据库。这意味着您需要增加检查点频率。
此描述中没有任何内容与逻辑复制相关。在这些情况下,您会发现管理员建议您持有足够的 WAL 来弥补最大延迟。
为此,您需要设置 wal_keep_size,而不是 max_wal_size。这是要保留的最小 WAL 大小。例如,如果您认为只读副本或备用服务器的停机时间最长可达 2 小时,则您可以将 wal_keep_size 设置为至少最大 wal 大小/小时 * 2 小时。
keep_wal_size 的默认值为 0。这并不是很多。
此外,这一切仍然没有涉及数据管道的变更数据捕获 (CDC)。有没有?
是的,有。 wal_keep_size 是你的规则,无论你喜欢与否。
您需要让管理员设置 keep_wal_size。然后,您需要在达到保留大小之前的几个小时内提取 WAL。否则,您可能需要重新启动 CDC 并拍摄新快照,因为一旦发生检查点,您可能无法再获取最旧的 WAL 段。
简而言之,
您的 CDC 需要像数据库一样思考并立即读取 WAL,这就是预期的设计。
快照完成后,您将看到 Debezium 进行读取。使用 DDD-3 减少锁定。 Estuary 立即执行 WAL 读取并并行启动增量快照,没有任何延迟,并将快照与 WAL 读取合并。这是最好的方法。
The max_wal_size parameter in Postgres is described as a soft limit to help prevent the WAL from growing too big. The default value is 1024 MB (the parameter is set in MB.) That’s not a lot.
When it’s reached, it basically signals Postgres to do a checkpoint and flush all data in buffers to disk. Once a checkpoint is complete, those WAL segments for the data that could have been in the buffers can be dropped. Completing a checkpoint can take time because Postgres does need to wait for transactions to complete. Hence the soft limit.
Checkpoints aren’t cheap. Admins are tempted to keep the time periods relatively long to maximize throughput. But on the flip side if the database fails, your recovery time is dependent on the size of your WAL, which you have to replay to restore the database. That means you’d want to increase your checkpoint frequency.
Nothing in this description was related to logical replication. In those cases, you will find admins recommending you hold enough WAL to cover the max delays.
To do that you need to set wal_keep_size, not max_wal_size. It’s the minimum WAL size to keep around. For example, if you believe a read-only replica or standby server could have 2 hours of downtime max, you would set your wal_keep_size to be at least the max wal size/hour * 2 hours.
The default value for keep_wal_size is 0. That’s not a lot.
Also, there’s still nothing in any of this about change data capture (CDC) for data pipelines. Is there?
Yes, there is. The wal_keep_size is your rule, whether you like it or not.
You need to get your admin to set keep_wal_size. Then you need to extract the WAL within the number of hours before the keep size is hit. Otherwise, you may need to restart your CDC and take a new snapshot because once a checkpoint happens, you may no longer be able to get the oldest WAL segments.
So in short,
Your CDC needs to think like a database and immediately read of the WAL, which was the intended design.
You'll see Debezium reads once the snapshot is done. Use DDD-3 to reduce locking. Estuary does immediate WAL reads and starts an incremental snapshot in parallel, without any delay, and merges the snapshot with the WAL reads. That's the best approach.