pg_restore: [archiver (db)] không thể thực thi truy vấn: ERROR: lược đồ


17

Tôi đang sử dụng pg_dump / pg_restore để sao lưu và khôi phục cơ sở dữ liệu PostgreQuery, nhưng tôi nhận được một số thông báo lỗi (và trạng thái thoát khác không) từ pg_restore. Tôi đã thử một trường hợp cơ bản siêu đơn giản (được nêu dưới đây) nhưng vẫn gặp các lỗi sau:

pg_restore: [archiver (db)] Lỗi trong khi quá trình xử lý:
pg_restore: [archiver (db)] Lỗi từ mục TOC 5; 2615 2200 SCHema công khai
pg_restore: [archiver (db)] không thể thực thi truy vấn: ERROR: lược đồ "công khai" đã tồn tại
    Lệnh là: TẠO SCHema công khai;

Các bước để tái sản xuất:

  1. Cài đặt bản phân phối Ubuntu 14.04 tươi, vani (Tôi đang sử dụng Vagrant với hộp Vagrant này ).
  2. Cài đặt PostgreQuery 9.3, cấu hình để cho phép các kết nối cục bộ là "postgres" của người dùng PostgreSQL từ bất kỳ người dùng Linux nào.
  3. Tạo một cơ sở dữ liệu thử nghiệm. Tôi chỉ đang làm:

    vagrant @ vagrant-ubfox-trusty-64: ~ $ psql --username = postgres postgres
    psql (9.3.5)
    Nhập "trợ giúp" để được giúp đỡ.
    
    postgres = # tạo cơ sở dữ liệu mydb;
    TẠO NÊN CƠ SỞ DỮ LIỆU
    postgres = # \ q
    vagrant @ vagrant-ub Ubuntu-trusty-64: ~ $ psql --username = postgres mydb
    psql (9.3.5)
    Nhập "trợ giúp" để được giúp đỡ.
    
    mydb = # tạo dữ liệu bảng (mục bigint);
    TẠO BẢNG
    mydb = # chèn vào giá trị dữ liệu (1);
    XÁC NHẬN 0 1
    mydb = # chèn vào giá trị dữ liệu (2);
    XÁC NHẬN 0 1
    mydb = # chèn vào giá trị dữ liệu (3);
    XÁC NHẬN 0 1
    mydb = # \ q
    
  4. Tạo một bản sao lưu của cơ sở dữ liệu như vậy:

    PGPASSWORD = "postgres" pg_dump --dbname = mydb --username = postgres --format = custom> pg_backup.dump
  5. Xóa một số hàng ra khỏi bảng dữ liệu trong mydb để chúng tôi có thể biết liệu chúng tôi có khôi phục dữ liệu thành công hay không.

  6. Khôi phục cơ sở dữ liệu với:

    PGPASSWORD = "postgres" pg_restore --clean --create --dbname = postgres --username = postgres pg_backup.dump

Dữ liệu được khôi phục, nhưng lệnh pg_restore trong bước 6 thoát với trạng thái 1và hiển thị đầu ra sau:

pg_restore: [archiver (db)] Lỗi trong khi quá trình xử lý:
pg_restore: [archiver (db)] Lỗi từ mục TOC 5; 2615 2200 SCHema công khai
pg_restore: [archiver (db)] không thể thực thi truy vấn: ERROR: lược đồ "công khai" đã tồn tại
    Lệnh là: TẠO SCHema công khai;



CẢNH BÁO: lỗi bỏ qua khi khôi phục: 1

Tôi không thể bỏ qua điều này bởi vì tôi đang chạy lệnh này theo chương trình và cần sử dụng trạng thái thoát để xác định xem khôi phục có thất bại hay không. Ban đầu, tôi tự hỏi liệu vấn đề này có phải là do tôi đặt cơ sở dữ liệu của mình ở chế độ công khai (lược đồ mặc định). Tôi đã lập luận rằng công khai sẽ được tạo ra do kết quả của --createtùy chọn bởi pg_restore trước khi dữ liệu được khôi phục (có thể cố gắng tạo ra lược đồ đó vì đó là bảng của tôi), nhưng khi tôi thử các bước trên với bảng của mình trong một lược đồ khác, các kết quả là như nhau và các thông báo lỗi giống hệt nhau.

Tôi có làm điều gì sai? Tại sao tôi thấy lỗi này?

Câu trả lời:


16

Lỗi là vô hại nhưng để loại bỏ nó, tôi nghĩ bạn cần chia khôi phục này thành hai lệnh, như trong:

dropdb -U postgres mydb && \
 pg_restore --create --dbname=postgres --username=postgres pg_backup.dump

Các --cleantùy chọn trong pg_restore không giống như nhiều nhưng thực sự đặt ra những vấn đề không tầm thường.

Đối với phiên bản lên tới 9.1

Sự kết hợp của --create--cleantrong các tùy chọn pg_restore từng là một lỗi trong các phiên bản PG cũ hơn (tối đa 9.1). Thực sự có một số mâu thuẫn giữa (trích dẫn trang man 9.1):

--clean Clean (drop) các đối tượng cơ sở dữ liệu trước khi tạo lại chúng

--create Tạo cơ sở dữ liệu trước khi khôi phục vào nó.

Bởi vì những gì cần làm sạch bên trong một cơ sở dữ liệu hoàn toàn mới?

Bắt đầu từ phiên bản 9.2

Sự kết hợp hiện được chấp nhận và tài liệu nói điều này (trích dẫn trang man 9.3):

--clean Clean (drop) các đối tượng cơ sở dữ liệu trước khi tạo lại chúng. (Điều này có thể tạo ra một số thông báo lỗi vô hại, nếu có bất kỳ đối tượng nào không có trong cơ sở dữ liệu đích.)

--create Tạo cơ sở dữ liệu trước khi khôi phục vào nó. Nếu --clean cũng được chỉ định, hãy thả và tạo lại cơ sở dữ liệu đích trước khi kết nối với nó.

Bây giờ có cả hai cùng dẫn đến loại trình tự này trong quá trình khôi phục của bạn:

DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...

Không có DROPcho mỗi đối tượng riêng lẻ, chỉ có một DROP DATABASEở đầu. Nếu không sử dụng --createthì điều này sẽ ngược lại.

Dù sao, trình tự này làm tăng lỗi của publiclược đồ đã tồn tại vì việc tạo mydbtừ template0đã nhập nó rồi (điều này là bình thường, đó là điểm của cơ sở dữ liệu mẫu).

Tôi không chắc tại sao trường hợp này không được xử lý tự động pg_restore. Có thể điều này sẽ gây ra tác dụng phụ không mong muốn khi quản trị viên quyết định tùy chỉnh template0và / hoặc thay đổi mục đích public, ngay cả khi chúng tôi không phải làm điều đó.


Tôi đang sử dụng 9.6 và chỉ định --createcleankhông khắc phục sự cố.
Cerin

6

Trong trường hợp của tôi, lý do là tôi đã sử dụng pg_restoretừ phiên bản postgresql-contrib 11.2 để khôi phục kết xuất được tạo bởipg_dump 9.6 thành cụm PostgreQuery 9.6.

Sau khi tôi hạ thấp pg_restorelưng xuống 9.6, schema "public" already existslỗi này đã biến mất và quá trình khôi phục hoạt động như trước.


Nhưng bạn đã khôi phục kết xuất bằng pg_restore 9.6 vào cơ sở dữ liệu postgres 11.2 chưa?
Mariano Ruiz

@MarianoRuiz Tôi nghĩ rằng câu trả lời ban đầu của tôi rất rõ ràng: "Tôi đã sử dụng pg_restore từ phiên bản postgresql-contrib 11.2 để khôi phục kết xuất được tạo bởi pg_dump 9.6 sang cụm PostgreQuery 9.6." Vì vậy, với câu hỏi của bạn: Không, tôi đã không. Pg_restore của tôi là 11,2 trong khi cụm pg là 9,6
Lu Liu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.