From 1e8bdcf69ac519eb9b8501e6efe8340722aad84d Mon Sep 17 00:00:00 2001 From: albertlast Date: Sun, 6 Sep 2026 16:12:09 +0200 Subject: [PATCH] Says so when the table being described is unlogged A table that is not written to the write-ahead log is made that way, and sessions, log_online and log_floodcontrol all are. table_sql() described them as ordinary tables, so anything rebuilding one from that SQL gave it a durability it was never meant to pay for, and the write cost that goes with it. Signed-off-by: albertlast --- Sources/Db/APIs/PostgreSQL.php | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Sources/Db/APIs/PostgreSQL.php b/Sources/Db/APIs/PostgreSQL.php index e3c39760ab..872d77e26c 100644 --- a/Sources/Db/APIs/PostgreSQL.php +++ b/Sources/Db/APIs/PostgreSQL.php @@ -1071,8 +1071,34 @@ public function table_sql(string $table_name): string // Drop it if it exists. $schema_create = 'DROP TABLE IF EXISTS ' . $table_name . ';' . "\n\n"; + // A table that is not written to the write-ahead log says so in the way + // it is made, and sessions, log_online and log_floodcontrol are all built + // that way. Rebuilding one from this without saying so would quietly give + // it a durability it was never meant to pay for. + $unlogged = ''; + + $persistence = $this->query( + 'SELECT c.relpersistence + FROM pg_class AS c + INNER JOIN pg_namespace AS n ON (n.oid = c.relnamespace) + WHERE c.relname = {string:table} + AND n.nspname = {string:schema}', + [ + 'table' => $table_name, + 'schema' => 'public', + ], + ); + + $row = $this->fetch_assoc($persistence); + + if (\is_array($row) && $row['relpersistence'] === 'u') { + $unlogged = 'UNLOGGED '; + } + + $this->free_result($persistence); + // Start the create table... - $schema_create .= 'CREATE TABLE ' . $table_name . ' (' . "\n"; + $schema_create .= 'CREATE ' . $unlogged . 'TABLE ' . $table_name . ' (' . "\n"; $index_create = ''; $seq_create = '';