PostgreSQL

PostgreSQL

All Your GUCs in a Row: max_wal_size

max_wal_size is not a maximum, and it is not the size of anything you can du. It is a checkpoint trigger denominated in bytes: once the WAL written since the last checkpoint started reaches a fixed fraction of this value (the fraction is below, and it is not 1), the next one starts, whether or not checkpoint_timeout has come

All Your GUCs in a Row: max_wal_senders

Errata: the max_connections post told you to size that parameter for “the replication connections.” On 12 and later, don’t. WAL senders have their own seats, sized by this parameter, and have not drawn from max_connections since PostgreSQL 12. The rest of that post stands; that clause is wrong for every version you should be running.

max_wal_senders is the number

All Your GUCs in a Row: max_sync_workers_per_subscription

max_sync_workers_per_subscription is how many tables a subscription copies at once. It is not how fast the initial copy goes, which is what people raise it hoping for. Each table synchronization worker copies exactly one table, start to finish, so the parameter buys parallelism across tables and nothing within one. Your largest table takes as long as it takes with this

All Your GUCs in a Row: max_standby_archive_delay and max_standby_streaming_delay

max_standby_streaming_delay is not a query timeout, whatever its name and its default suggest. It is the amount of replication lag you have agreed to buy with standby queries, and the queries are merely what gets thrown overboard when the budget runs out. max_standby_archive_delay is the same knob for WAL that arrives through restore_command instead of a walsender; I’ll treat the

All Your GUCs in a Row: max_slot_wal_keep_size

max_slot_wal_keep_size decides who dies when a replica stops consuming WAL: the replica, or the primary. The default picks the primary.

That is not an exaggeration, and it is the whole argument for the parameter. A replication slot’s job is to keep the primary from recycling WAL its consumer hasn’t received yet, and a slot keeps that promise whether the

All Your GUCs in a Row: max_replication_slots

max_replication_slots is the length of an array in shared memory, and that is all it is. It doesn’t decide who may create a slot, how much WAL a slot may pin, or when an abandoned one gets cleaned up. It decides how many entries the array has; the array is allocated once, at startup; and so the only interesting property

All Your GUCs in a Row: max_prepared_transactions

A prepared transaction is a transaction that has been cut loose from its session. After PREPARE TRANSACTION 'some-gid', the session that started it has no transaction at all; the work it did, the locks it took, and its transaction ID go on existing by themselves, written to WAL, tracked in shared memory, restored after a crash, waiting for somebody

All Your GUCs in a Row: max_pred_locks_per_transaction

max_pred_locks_per_transaction has the naming problem of max_locks_per_transaction, and then one of its own. Like its namesake, it is a table size quoted per backend slot, not a limit on any transaction. Unlike its namesake, most of what its table holds at any given moment belongs to transactions that have already committed.

The default is 64, the minimum

The Shadow Knows

ClickHouse released WalShadow last week, and it does something very… brave: it replicates PostgreSQL into ClickHouse without using logical decoding at all. It reads the physical WAL stream, the same bytes a streaming replica gets, decodes heap records itself, and writes ClickHouse-native blocks. The latency and throughput numbers they published are good, and I believe with them.

The interesting

All Your GUCs in a Row: max_pred_locks_per_page and max_pred_locks_per_relation

Under SERIALIZABLE, PostgreSQL has to remember what every transaction read, and it has a fixed amount of shared memory to remember it in. These two parameters decide when it gives up remembering rows and remembers the page instead, and when it gives up on pages and remembers the whole table. Each step down in precision is paid for in