我想将另一个数据库名称下的特定数据库还原到另一个服务器。到目前为止,非常好。
我使用了这个命令:
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是一个在公共场景中的功能,并且可以通过恢复来创建。
恢复后,我可以使用相同的sql完全重新创建这些索引,没有任何错误。
我还尝试使用pg_restore的-i选项进行恢复以执行单个事务,但它没有帮助。
我做错了什么?
答案 0 :(得分:2)
我刚刚发现了问题,我能够将其缩小到一个简单的测试用例。
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提交了一份关于此问题的错误报告,尚未列入队列。