首页 > 解决方案 > postgres 转储显示重复的功能

问题描述

我的 postgres 版本是 9.0.4 我创建了我的数据库的 postgres 转储并包含自定义功能的重复条目。当我直接查询我的数据库时,我没有看到任何重复条目,但转储有这个重复项。

以下是我使用 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

我检查了数据库中的函数,我没有看到任何重复的条目。

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 $1[i] from generate_series(array_lower($1,1), array_upper($1,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 $1[i] from generate_series(array_lower($1,1), array_upper($1,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 |           |        |

标签: postgresqlpg-dumppostgresql-9.0

解决方案


那是目录数据损坏,因为目录中实际上有重复的条目pg_proc,即使有一个唯一索引可以保证模式名称、函数名称和参数列表的组合是唯一的。

您应该立即关闭(使数据库崩溃)并对数据目录进行物理备份。这始终是处理数据损坏的第一步。

重新启动数据库后,采用pg_dumpall集群的文本模式并手动从转储文件中删除重复的条目。将转储恢复到新集群并删除旧集群。

一旦你成功摆脱了数据损坏,你应该立即在新硬件上升级到 PostgreSQL v12 ,因为 9.0 之前的版本包含许多可能导致各种数据损坏的已知错误。

这是一个很好的例子,为什么升级不仅仅是 IT 部门为了保住工作和惹恼最终用户而发明的东西。


推荐阅读