显示重复功能的 postgres 转储
postgres dump showing duplicate FUNCTION
我的 postgres 版本是 9.0.4 我已经创建了我的数据库的 postgres 转储并且包含自定义的重复条目 FUNCTIONS.When 我直接查询我的数据库我没有看到任何重复的条目,但是转储有这个重复项.
以下是我使用 pg_restore -l 命令获取的列表。
37; 1255 16402 FUNCTION public sql_dirdepth(character varying) nidhin
31; 1255 16402 FUNCTION public sql_dirdepth(character varying) nidhin
29; 1255 16403 FUNCTION public sql_getdir(character varying) nidhin
35; 1255 16403 FUNCTION public sql_getdir(character varying) nidhin
30; 1255 16404 FUNCTION public sql_subdir(character varying, integer, integer) nidhin
36; 1255 16404 FUNCTION public sql_subdir(character varying, integer, integer) nidhin
32; 1255 16405 FUNCTION public unnest(anyarray) nidhin
38; 1255 16405 FUNCTION public unnest(anyarray) nidhin
我检查了 DB 中的函数,没有看到任何重复的条目。
CDB=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+-----------------+-------------------+-------------------------------------+--------
public | sql_dirdepth | integer | character varying | normal
public | sql_getdir | character varying | character varying | normal
public | sql_subdir | character varying | character varying, integer, integer | normal
(3 rows)
所以我想知道 pg_dump 是如何在我的转储文件中创建这些函数的重复条目的。
查询
SELECT *
FROM pg_proc
WHERE proname || '' IN ('unnest', 'sql_dirdepth', 'sql_getdir', 'sql_subdir');
给出以下结果。
我可以看到其中有重复项,如何删除重复的函数?
| proname | pronamespace | proowner | prolang | procost | prorows | provariadic | proisagg | proiswindow | prosecdef | proisstrict | proretset | provolatile | pronargs | pronargdefaults | prorettype | proargtypes | proallargtypes | proargmodes | proargnames | proargdefaults | prosrc | probin | proconfig | proacl |
|--------------|--------------|----------|---------|---------|---------|-------------|----------|-------------|-----------|-------------|-----------|-------------|----------|-----------------|------------|-------------|----------------|-------------|-------------|----------------|------------------------------------------------------------------------------|-------------------------|-----------|--------|
| unnest | 11 | 10 | 12 | 1 | 100 | 0 | f | f | f | t | t | i | 1 | 0 | 2283 | 2277 | | | | | array_unnest | | | |
| sql_getdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 1043 | 1043 | | | | | sql_getdir | /opt/openkaz/lib/kazsql | | |
| sql_subdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 3 | 0 | 1043 | 1043 23 23 | | | | | sql_subdir | /opt/openkaz/lib/kazsql | | |
| sql_dirdepth | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 23 | 1043 | | | | | sql_dirdepth | /opt/openkaz/lib/kazsql | | |
| unnest | 2200 | 10 | 14 | 100 | 1000 | 0 | f | f | f | f | t | i | 1 | 0 | 2283 | 2277 | | | | | "select [i] from generate_series(array_lower(,1), array_upper(,1)) i;" | | | |
| sql_subdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 3 | 0 | 1043 | 1043 23 23 | | | | | sql_subdir | /opt/openkaz/lib/kazsql | | |
| sql_dirdepth | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 23 | 1043 | | | | | sql_dirdepth | /opt/openkaz/lib/kazsql | | |
| unnest | 2200 | 10 | 14 | 100 | 1000 | 0 | f | f | f | f | t | i | 1 | 0 | 2283 | 2277 | | | | | "select [i] from generate_series(array_lower(,1), array_upper(,1)) i;" | | | |
| sql_getdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 1043 | 1043 | | | | | sql_getdir | /opt/openkaz/lib/kazsql | | |
那是目录数据损坏,因为在 pg_proc
目录中实际上有重复的条目,即使有一个唯一索引保证模式名称、函数名称和参数列表的组合是唯一的。
您应该立即关闭(使数据库崩溃)并对数据目录进行物理备份。这始终是处理数据损坏的第一步。
重新启动数据库后,采用集群的文本模式pg_dumpall
,并手动从转储文件中删除重复的条目。将转储恢复到新集群并删除旧集群。
成功消除数据损坏后,您应该立即在新硬件上升级到 PostgreSQL v12,因为 9.0 的旧版本包含许多已知错误,可以导致各种数据损坏。
这是一个很好的例子,为什么升级不仅仅是 IT 部门为了保住工作和惹恼最终用户而发明的东西。
我的 postgres 版本是 9.0.4 我已经创建了我的数据库的 postgres 转储并且包含自定义的重复条目 FUNCTIONS.When 我直接查询我的数据库我没有看到任何重复的条目,但是转储有这个重复项.
以下是我使用 pg_restore -l 命令获取的列表。
37; 1255 16402 FUNCTION public sql_dirdepth(character varying) nidhin
31; 1255 16402 FUNCTION public sql_dirdepth(character varying) nidhin
29; 1255 16403 FUNCTION public sql_getdir(character varying) nidhin
35; 1255 16403 FUNCTION public sql_getdir(character varying) nidhin
30; 1255 16404 FUNCTION public sql_subdir(character varying, integer, integer) nidhin
36; 1255 16404 FUNCTION public sql_subdir(character varying, integer, integer) nidhin
32; 1255 16405 FUNCTION public unnest(anyarray) nidhin
38; 1255 16405 FUNCTION public unnest(anyarray) nidhin
我检查了 DB 中的函数,没有看到任何重复的条目。
CDB=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+-----------------+-------------------+-------------------------------------+--------
public | sql_dirdepth | integer | character varying | normal
public | sql_getdir | character varying | character varying | normal
public | sql_subdir | character varying | character varying, integer, integer | normal
(3 rows)
所以我想知道 pg_dump 是如何在我的转储文件中创建这些函数的重复条目的。
查询
SELECT *
FROM pg_proc
WHERE proname || '' IN ('unnest', 'sql_dirdepth', 'sql_getdir', 'sql_subdir');
给出以下结果。
我可以看到其中有重复项,如何删除重复的函数?
| proname | pronamespace | proowner | prolang | procost | prorows | provariadic | proisagg | proiswindow | prosecdef | proisstrict | proretset | provolatile | pronargs | pronargdefaults | prorettype | proargtypes | proallargtypes | proargmodes | proargnames | proargdefaults | prosrc | probin | proconfig | proacl |
|--------------|--------------|----------|---------|---------|---------|-------------|----------|-------------|-----------|-------------|-----------|-------------|----------|-----------------|------------|-------------|----------------|-------------|-------------|----------------|------------------------------------------------------------------------------|-------------------------|-----------|--------|
| unnest | 11 | 10 | 12 | 1 | 100 | 0 | f | f | f | t | t | i | 1 | 0 | 2283 | 2277 | | | | | array_unnest | | | |
| sql_getdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 1043 | 1043 | | | | | sql_getdir | /opt/openkaz/lib/kazsql | | |
| sql_subdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 3 | 0 | 1043 | 1043 23 23 | | | | | sql_subdir | /opt/openkaz/lib/kazsql | | |
| sql_dirdepth | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 23 | 1043 | | | | | sql_dirdepth | /opt/openkaz/lib/kazsql | | |
| unnest | 2200 | 10 | 14 | 100 | 1000 | 0 | f | f | f | f | t | i | 1 | 0 | 2283 | 2277 | | | | | "select [i] from generate_series(array_lower(,1), array_upper(,1)) i;" | | | |
| sql_subdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 3 | 0 | 1043 | 1043 23 23 | | | | | sql_subdir | /opt/openkaz/lib/kazsql | | |
| sql_dirdepth | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 23 | 1043 | | | | | sql_dirdepth | /opt/openkaz/lib/kazsql | | |
| unnest | 2200 | 10 | 14 | 100 | 1000 | 0 | f | f | f | f | t | i | 1 | 0 | 2283 | 2277 | | | | | "select [i] from generate_series(array_lower(,1), array_upper(,1)) i;" | | | |
| sql_getdir | 2200 | 10 | 13 | 1 | 0 | 0 | f | f | f | t | f | i | 1 | 0 | 1043 | 1043 | | | | | sql_getdir | /opt/openkaz/lib/kazsql | | |
那是目录数据损坏,因为在 pg_proc
目录中实际上有重复的条目,即使有一个唯一索引保证模式名称、函数名称和参数列表的组合是唯一的。
您应该立即关闭(使数据库崩溃)并对数据目录进行物理备份。这始终是处理数据损坏的第一步。
重新启动数据库后,采用集群的文本模式pg_dumpall
,并手动从转储文件中删除重复的条目。将转储恢复到新集群并删除旧集群。
成功消除数据损坏后,您应该立即在新硬件上升级到 PostgreSQL v12,因为 9.0 的旧版本包含许多已知错误,可以导致各种数据损坏。
这是一个很好的例子,为什么升级不仅仅是 IT 部门为了保住工作和惹恼最终用户而发明的东西。