public inbox for [email protected]
help / color / mirror / Atom feedFrom: Chao Li <[email protected]>
To: Postgres hackers <[email protected]>
Subject: Fix a server crash problem from pg_get_database_ddl
Date: Wed, 15 Apr 2026 13:51:31 +0800
Message-ID: <[email protected]> (raw)
Hi,
While doing some testing, I hit a server crash:
```
2026-04-15 11:30:17.377 CST [98179] LOG: client backend (PID 41260) was terminated by signal 11: Segmentation fault: 11
2026-04-15 11:30:17.377 CST [98179] DETAIL: Failed process was running: SELECT * FROM pg_get_database_ddl('db1'::regdatabase);
2026-04-15 11:30:17.377 CST [98179] LOG: terminating any other active server processes
2026-04-15 11:30:17.380 CST [44361] FATAL: the database system is in recovery mode
```
After debugging it, I found that the crash happened because I had mistakenly deleted the tablespace entry directly from pg_tablespace, and pg_get_database_ddl_internal() calls get_tablespace_name() without checking whether the return value is NULL.
So this doesn't seem like a bug a normal user could hit. It is more like a superuser-only mistake that creates an invalid catalog state. I think that even in such an edge case, we should raise a proper error instead of crashing the backend.
BTW, I have verified that in this case, ALTER DATABASE ... SET TABLESPACE can move the database to a valid tablespace and recover from the issue.
This patch fixes that by checking for a NULL result and throwing an error.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Attachments:
[application/octet-stream] v1-0001-ddlutils-error-out-when-pg_get_database_ddl-sees-.patch (1.4K, 2-v1-0001-ddlutils-error-out-when-pg_get_database_ddl-sees-.patch)
download | inline diff:
From 4529c77c01bd0a2f1718c6dc45a2896191b72001 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Wed, 15 Apr 2026 13:32:12 +0800
Subject: [PATCH v1] ddlutils: error out when pg_get_database_ddl() sees a
missing tablespace
pg_get_database_ddl_internal() calls get_tablespace_name() for a
database's dattablespace, and then passes the result to
pg_strcasecmp() without checking for NULL first.
Fix that by detecting the missing tablespace explicitly and raising an
ERROR with ERRCODE_UNDEFINED_OBJECT.
Author: Chao Li <[email protected]>
Reviewed-by:
Discussion: https://postgr.es/m/
---
src/backend/utils/adt/ddlutils.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/backend/utils/adt/ddlutils.c b/src/backend/utils/adt/ddlutils.c
index c4f9f86c43e..6ab354e42f6 100644
--- a/src/backend/utils/adt/ddlutils.c
+++ b/src/backend/utils/adt/ddlutils.c
@@ -976,6 +976,13 @@ pg_get_database_ddl_internal(Oid dbid, bool pretty,
{
char *spcname = get_tablespace_name(dbform->dattablespace);
+ if (spcname == NULL)
+ ereport(ERROR,
+ errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("tablespace with OID %u does not exist",
+ dbform->dattablespace),
+ errhint("To recover, try ALTER DATABASE ... SET TABLESPACE ... to a valid tablespace."));
+
if (pg_strcasecmp(spcname, "pg_default") != 0)
append_ddl_option(&buf, pretty, 4, "TABLESPACE = %s",
quote_identifier(spcname));
--
2.50.1 (Apple Git-155)
view thread (10+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected]
Subject: Re: Fix a server crash problem from pg_get_database_ddl
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox