psql (9.3.9)
我在 Ubuntu 14.04 上使用。
我使用命令创建了数据库的转储:
pg_dump db1 > db1.backup
我删除了数据库并重新创建了它。
尝试恢复它,psql -d db1 -f /tmp/db1.backup
结果出现数百行错误,并且没有向数据库添加任何内容。
Query buffer reset (cleared).
psql:/tmp/db1.backup:19658: invalid command \n
Query buffer reset (cleared).
psql:/tmp/db1.backup:19659: invalid command \n*
Query buffer reset (cleared).
psql:/tmp/db1.backup:19660: invalid command \<text data from my db>
Query buffer reset (cleared).
psql:/tmp/db1.backup:19662: invalid command \n<text data from my db>
Query buffer reset (cleared).
psql:/tmp/db1.backup:19663: invalid command \n<more text data from my db>
第一个输出如下所示:
SET
SET
SET
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
SET
Query buffer reset (cleared).
Query buffer reset (cleared).
Query buffer reset (cleared).
...
恢复转储的其他建议方法因同样的错误而失败:
postgres=# \i /tmp/db1.backup
正如官方文件所建议的方法一样:
psql db1 < db1.backup
使用pg_restore
也失败:
pg_restore -d db1 /tmp/db1.backup
pg_restore: [archiver] input file appears to be a text format dump. Please use psql.
从转储恢复数据库的正确方法是什么?
编辑:
将所有输出发送到文本文件进行研究后,我发现了实际错误。这似乎与权限有关。
psql:/tmp/db1:50: ERROR: permission denied to create "pg_catalog.attachments"
DETAIL: System catalog modifications are currently disallowed.
psql:/tmp/db1:53: ERROR: schema "public" does not exist
psql:/tmp/db1:64: ERROR: permission denied to create "pg_catalog.attachments_id_seq"
DETAIL: System catalog modifications are currently disallowed.
psql:/tmp/db1:67: ERROR: schema "public" does not exist
psql:/tmp/db1:73: ERROR: relation "attachments_id_seq" does not exist
psql:/tmp/db1:97: ERROR: permission denied to create "pg_catalog.auth_sources"
DETAIL: System catalog modifications are currently disallowed.
psql:/tmp/db1:100: ERROR: schema "public" does not exist
psql:/tmp/db1:111: ERROR: permission denied to create "pg_catalog.auth_sources_id_seq"
DETAIL: System catalog modifications are currently disallowed.
psql:/tmp/db1:114: ERROR: schema "public" does not exist
psql:/tmp/db1:120: ERROR: relation "auth_sources_id_seq" does not exist
psql:/tmp/db1:137: ERROR: permission denied to create "pg_catalog.boards"
...
EDIT2:-v ON_ERROR_STOP=1
我能够得到这个输出:
postgres@dbhost:$ psql -d db1 -v ON_ERROR_STOP=1 < db1.backup
SET
SET
SET
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
SET
ERROR: permission denied to create "pg_catalog.attachments"
DETAIL: System catalog modifications are currently disallowed.
我使用以下命令授予 postgres-user 对目标数据库的权限:
grant all privileges on database db1 to postgres;
EDIT3:这是我用来创建转储的确切命令:
root@dbhost:~# su -c "pg_dump db1 > db1.backup" postgres
编辑4:
postgres@dbhost:/ head -50 db1.backup
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: attachments; Type: TABLE; Schema: public; Owner: mydbuser; Tablespace:
--
CREATE TABLE attachments (
id integer NOT NULL,
container_id integer,
container_type character varying(30) DEFAULT NULL::character varying,
filename character varying(255) DEFAULT ''::character varying NOT NULL,
disk_filename character varying(255) DEFAULT ''::character varying NOT NULL,
filesize integer DEFAULT 0 NOT NULL,
content_type character varying(255) DEFAULT ''::character varying,
digest character varying(40) DEFAULT ''::character varying NOT NULL,
downloads integer DEFAULT 0 NOT NULL,
author_id integer DEFAULT 0 NOT NULL,
created_on timestamp without time zone,
description character varying(255),
disk_directory character varying(255)
);
id integer NOT NULL,
--
postgres@dbhost:/$ grep search_path db1.backup
SET search_path = public, pg_catalog;
这也匹配了我数据库中的数百行数据,我不得不忽略它们。可能还漏掉了一些命令:
postgres@dbhost:/$ grep attachments db1.backup
-- Name: attachments; Type: TABLE; Schema: public; Owner: dbuser; Tablespace:
CREATE TABLE attachments (
ALTER TABLE public.attachments OWNER TO dbuser;
-- Name: attachments_id_seq; Type: SEQUENCE; Schema: public; Owner: dbuser
CREATE SEQUENCE attachments_id_seq
ALTER TABLE public.attachments_id_seq OWNER TO dbuser;
-- Name: attachments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: dbuser
ALTER SEQUENCE attachments_id_seq OWNED BY attachments.id;
ALTER TABLE ONLY attachments ALTER COLUMN id SET DEFAULT nextval('attachments_id_seq'::regclass);
-- Data for Name: attachments; Type: TABLE DATA; Schema: public; Owner: dbuser
COPY attachments (id, container_id, container_type, filename, disk_filename, filesize, content_type, digest, downloads, author_id, created_on, description, disk_directory) FROM stdin;
-- Name: attachments_id_seq; Type: SEQUENCE SET; Schema: public; Owner: dbuser
--
root@dbhost:~# grep -i 'create schema' db1.backup
<no results>
答案1
看起来原始转储中确实有一些奇怪的东西。CREATE TABLE pg_catalog.attachments
转储中一定有类似语句的东西。这不可能,因为pg_catalog
除非调试选项allow_system_table_mods
为,否则您无法创建表on
。
我能想到的发生这种情况的唯一其他方式是,如果脚本search_path
设置的pg_dump
在某种程度上无效。例如,如果CREATE SCHEMA myschema
未运行,search_path
可能是myschema,pg_catalog
,如果myschema
缺少 ,则会导致pg_catalog
成为 的目标CREATE TABLE
。
在正常运行中这是不可能的pg_dump
。
答案2
仅补充一下我的经验:
我必须事先创建要恢复的架构。如果架构在恢复之前不存在,则恢复会以这种方式失败。否则,没有问题。
奇怪的是,我只在我的一个数据库中遇到了这个问题,这些数据库(据我所知)都以相同的方式设置,并且大多采用默认设置。这是多次备份的情况。今天第一次看到这种情况,经过几个月的操作后,我删除了一个架构并让它不存在,然后从转储中恢复它。可怕...
答案3
当你尝试备份所有数据库时,值得使用pg_dumpall至于特定的数据库备份 - 当我按照以下方式执行时,我没有遇到任何问题:
- 创建转储 -
pg_dump -o -h <host> -U roleName -d dbName -n "\"SCHEMA\"" > schema_name.dump
- 在转储文件中全局更改所有者(适用于小尺寸)
vi schema_name.dump
然后:%s/roleName/newRoleName/g
或仅适用于任何尺寸sed -i -- 's/roleName/newRoleName/g' schema_name.dump
- 恢复转储
psql -U newRoleName newDbName -h <host> < schema_name.dump
答案4
检查您用于恢复目的的转储(备份)中的 search_path。当您使用用户(例如:postgresql)进行备份时,备份转储中的 search_path 将类似于 set search_path = postgres,pg_catalog, sys,dbo,并且在恢复时,如果它找不到 postgresql 模式,它将尝试在 pg_catalog 模式中恢复,但会失败。