【问题标题】:Unaccent issue when restoring a Postgres database恢复 Postgres 数据库时出现不突出的问题
【发布时间】:2014-05-29 17:42:40
【问题描述】:

我也想将另一个数据库名称下的特定数据库恢复到另一个服务器。到目前为止,一切顺利。

我使用了这个命令:

pg_dump -U postgres -F c -O -b -f maindb.dump maindb

转储生产服务器上的主数据库。我使用这个命令:

 pg_restore --verbose -O -l -d restoredb maindb.dump

在我们的测试服务器上的另一个数据库中恢复数据库。它恢复大部分正常,但有一些错误,如:

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 3595; 1259 213452 INDEX idx_clientnomclient maindbuser
pg_restore: [archiver (db)] could not execute query: ERROR:  function unaccent(text) does not exist
LINE 1:  SELECT unaccent(lower($1)); 
                ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
QUERY:   SELECT unaccent(lower($1)); 
CONTEXT:  SQL function "cyunaccent" during inlining
Command was: CREATE INDEX idx_clientnomclient ON client USING btree (public.cyunaccent((lower((nomclient)::text))::character varying));

cyunaccent 是一个位于公共 shcema 中的函数,并且确实是通过还原创建的。

还原后,我可以使用相同的 sql 完美地重新创建这些索引,没有任何错误。

我也尝试使用 pg_restore 的 -i 选项进行恢复以执行单个事务,但没有帮助。

我做错了什么?

【问题讨论】:

  • 看来问题的根源在于缺少功能。 unaccent(text) 是它抱怨的第一个。您确定它是从备份中重新创建的吗?
  • 是的,它正在重新创建。当 pg_restore 完成时,该函数存在,并且我能够创建索引而不会出错。我将还原到一个新创建的数据库中,但在那时(在还原之前),它没有。
  • 可能是按照错误的顺序重新创建的。
  • Unaccent 似乎是文本搜索功能的一部分。是否安装在目标机器上?您是否以 postgres 用户身份运行恢复?
  • 是的,因为目标机器上的其他数据库确实有它。是的,我首先尝试以数据库所有者的身份进行还原,但部分还原出现了问题,例如创建扩展。所以我最终以 postgres 用户的身份进行操作。 @wilsotc 这就是我所相信的,因为我可以在之后重新创建索引。但是这样做是非常不可编写脚本的......

标签: database postgresql backup restore


【解决方案1】:

我刚刚发现了问题,并且能够将其缩小到一个简单的测试用例。

CREATE SCHEMA intranet;
CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA public;
SET search_path = public, pg_catalog;
CREATE FUNCTION cyunaccent(character varying) RETURNS character varying
    LANGUAGE sql IMMUTABLE
    AS $_$ SELECT unaccent(lower($1)); $_$;
SET search_path = intranet, pg_catalog;
CREATE TABLE intranet.client (
    codeclient character varying(10) NOT NULL,
    noclient character varying(7),
    nomclient character varying(200) COLLATE pg_catalog."fr_CA"
 );
ALTER TABLE ONLY client ADD CONSTRAINT client_pkey PRIMARY KEY (codeclient);
CREATE INDEX idx_clientnomclient ON client USING btree (public.cyunaccent((lower((nomclient)::text))::character varying));

这个测试用例来自一个以纯文本形式完成的 pg_dump。

如您所见,cyunaccent 函数是在公共 shcema 中创建的,因为它稍后会被其他架构中的其他表使用。

psql/pg_restore 不会重新创建索引,因为它找不到函数,尽管指定了 shcema 名称来引用它。问题出在

SET search_path = intranet, pg_catalog;

打电话。改成

SET search_path = intranet, public, pg_catalog;

解决问题。我已经向 postgres 提交了一份关于此问题的错误报告,但尚未在队列中。

【讨论】:

  • 此外,将功能更改为: SELECT public. unaccent(lower($1)) 完全解决了问题。所以,最后它只是在缺少的函数中缺少了一个 shchema 规范。
  • 你的错误报告有没有引起注意? 2021 年我仍然会达到这个目标
  • @isset 不。这是 PG itseft 中的一个很大的错误,但在定义函数的方式上。函数现在定义为:CREATE OR REPLACE FUNCTION public.cyunaccent(character varying) RETURNS character varying AS ' SELECT lower(public.unaccent($1)); ' LANGUAGE sql IMMUTABLE COST 100; 在我们的数据库中,hense 解决了这个问题.
  • @nicolasross 有一些关于明确设置模式规范的需要的文档吗?在我的例子中,函数和 pg_restore 已经在正确的模式中,所以我不明白为什么我们需要明确它。
  • 没关系,找到了:stackoverflow.com/a/63518355/6731248
猜你喜欢
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
相关资源
最近更新 更多