# 42P04 — 重复数据库

> PostgreSQL SQLSTATE 42P04（duplicate_database）的来源与诊断参考。
---

# 42P04 — 重复数据库

## 速览 {#at-a-glance}

`42P04`（**duplicate_database**）表示数据库管理路径发现集群中已有同名数据库。这是集群级名称检查，不是当前库内的关系冲突；CREATE 和 RENAME 的外围检查也不同。

<!-- BEGIN SQLSTATE FACTS: generated by scripts/generate.py; do not edit -->

| 字段 | 值 |
| --- | --- |
| SQLSTATE | `42P04` |
| 条件名 | `duplicate_database` |
| 状态 | `有效` |
| 已知存在于 | `7.4` |
| 锁定快照 | `9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3` |
| 宏 | `ERRCODE_DUPLICATE_DATABASE` |
| 别名 | `—` |

<!-- source facts: data/errcodes/42P04.json -->
<!-- END SQLSTATE FACTS -->

## 含义 {#meaning}

`createdb` 会用 `get_database_oid(dbname, true)` 检查目标名称，冲突时报告 ERROR `database "%s" already exists`。`RenameDatabase` 在查找旧数据库、检查所有权和 `CREATEDB` 权限之后，对 `newname` 做同样检查。因此 `%s` 在 CREATE 中是请求的数据库名，在 RENAME 中是新名称。

utility 分发器在进入 `createdb` 前调用 `PreventInTransactionBlock(isTopLevel, "CREATE DATABASE")`。所以在显式事务中执行 CREATE DATABASE 是另一种事务块错误，不能据此声称发出了 `42P04`；RENAME 则有独立的旧名、所有权、权限和新名检查。

## 诊断 {#diagnosis}

确认目标集群和准确名称，检查 `pg_database`、标识符折叠和迁移竞争。CREATE 另查目标名称、模板和所有者前提；RENAME 同时查旧名、新名、所有权和 `CREATEDB`。旧数据库不存在或权限不足不应误判为 `42P04`。

## 处理 {#response}

已有库就是目标时让编排幂等并检查它；否则选择未占用名称。CREATE DATABASE 要在顶层、显式事务块之外执行。RENAME 只有在确认旧库、所有权、`CREATEDB`、活动会话、依赖和集群身份后才选择可用新名。如果 RENAME 在显式事务中报错，下一条命令前应执行 `ROLLBACK`；若必须保留外层事务，则回滚到改名前建立的保存点。删除或改名不是所有 `42P04` 的通用修复。

## 消息变体 {#messages}

选定路径均为 `ERROR` `database "%s" already exists`：`createdb` 使用请求名称，`RenameDatabase` 使用新名称。utility 中的 `PreventInTransactionBlock` 证明 CREATE DATABASE 有独立事务限制，不是另一条 `42P04` 报文。

## 版本 {#versions}

目录范围从 7.4 到 18.6、19beta3，不是精确的功能引入判断。选定的是 18.6 固定 CREATE、RENAME 和分发器事务检查路径，未运行数据库。

## 相关 {#related}

- [`42P07`](../42p07/)
- [`42P06`](../42p06/)
- [`42710`](../42710/)

## 来源 {#sources}
- `src.errcodes.42P04.18.6` — `src/backend/utils/errcodes.txt` line 379，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L379)）。

- `src.call.42P04.465a77b5605c341bc91f6990` — `src/backend/commands/dbcommands.c` lines 1393-1395，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `64b77d2197dce16eb1ad19d8168382459d621a03df0b00be157f7db39ca22acf`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/dbcommands.c#L1393-L1395)）。
- `src.call.42P04.b0d1644def83c14a7504fec4` — `src/backend/commands/dbcommands.c` lines 1949-1951，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `64b77d2197dce16eb1ad19d8168382459d621a03df0b00be157f7db39ca22acf`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/commands/dbcommands.c#L1949-L1951)）。
- `src.call.42P04.create-tx-guard` — `src/backend/tcop/utility.c` lines 769-773，固定于 `724edf9bde9d356724ad384a2e196edc3c9f80f7`；SHA-256 `7aae5d07628b6debf8456d1d4ea96f28912232192e56ea25773b4c4b61235a00`（[源码](https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/tcop/utility.c#L769-L773)）。
- `src.calls.REL_18_6.42P04` — 固定本地核心调用扫描；SHA-256 `9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf`。
- [`作者证据`](../../data/evidence/42p04.json) — 记录源码断言、消息角色和运行边界。
