pg_restore: [archiver (db)] ไม่สามารถดำเนินการค้นหา: ข้อผิดพลาด: schema“ สาธารณะ” มีอยู่แล้ว


18

ฉันใช้ pg_dump / pg_restore เพื่อสำรองและกู้คืนฐานข้อมูล PostgreSQL แต่ฉันได้รับข้อความแสดงข้อผิดพลาด (และสถานะทางออกที่ไม่เป็นศูนย์) จาก pg_restore ฉันลองใช้เคสพื้นฐานแบบง่าย ๆ (อธิบายไว้ด้านล่าง) แต่ยังมีข้อผิดพลาดเหล่านี้:

pg_restore: [archiver (db)] ข้อผิดพลาดขณะประมวลผล TOC:
pg_restore: [archiver (db)] ข้อผิดพลาดจากรายการ TOC 5; 2615 2200 SCHEMA postgres สาธารณะ
pg_restore: [archiver (db)] ไม่สามารถดำเนินการค้นหา: ข้อผิดพลาด: schema "สาธารณะ" มีอยู่แล้ว
    คำสั่งคือ: สร้างสาธารณะ SCHEMA;

ขั้นตอนในการทำซ้ำ:

  1. ติดตั้ง vanilla Ubuntu 14.04 distro สดใหม่ (ฉันใช้ Vagrant กับกล่อง Vagrant นี้ )
  2. ติดตั้ง PostgreSQL 9.3 กำหนดค่าเพื่ออนุญาตการเชื่อมต่อท้องถิ่นในฐานะผู้ใช้ PostgreSQL "postgres" จากผู้ใช้ Linux ใด ๆ
  3. สร้างฐานข้อมูลทดสอบ ฉันแค่ทำ:

    vagrant @ vagrant-ubuntu-trusty-64: ~ $ psql - ชื่อผู้ใช้ = postgres postgres
    psql (9.3.5)
    พิมพ์ "ความช่วยเหลือ" เพื่อขอความช่วยเหลือ
    
    postgres = # สร้างฐานข้อมูล mydb;
    สร้างฐานข้อมูล
    postgres = # \ q
    vagrant @ vagrant-ubuntu-trusty-64: ~ $ psql - ชื่อผู้ใช้ = postgres mydb
    psql (9.3.5)
    พิมพ์ "ความช่วยเหลือ" เพื่อขอความช่วยเหลือ
    
    mydb = # create data table (entry bigint);
    สร้างตาราง
    mydb = # insert เป็นค่าข้อมูล (1);
    INSERT 0 1
    mydb = # insert เป็นค่าข้อมูล (2);
    INSERT 0 1
    mydb = # insert เป็นค่าข้อมูล (3);
    INSERT 0 1
    mydb = # \ q
    
  4. สร้างการสำรองข้อมูลของฐานข้อมูลดังนี้:

    PGPASSWORD = "postgres" pg_dump --dbname = mydb --username = postgres --format = กำหนดเอง> pg_backup.dump
  5. ลบบางแถวออกจากตารางข้อมูลใน mydb ดังนั้นเราจะสามารถบอกได้ว่าเรากู้คืนข้อมูลสำเร็จหรือไม่

  6. กู้คืนฐานข้อมูลด้วย:

    PGPASSWORD = "postgres" pg_restore - สะอาด - สร้าง - dbname = postgres - ชื่อผู้ใช้ = postgres pg_backup.dump

ข้อมูลถูกกู้คืน แต่คำสั่ง pg_restore ในขั้นตอนที่ 6 จบด้วยสถานะ1และแสดงเอาต์พุตต่อไปนี้:

pg_restore: [archiver (db)] ข้อผิดพลาดขณะประมวลผล TOC:
pg_restore: [archiver (db)] ข้อผิดพลาดจากรายการ TOC 5; 2615 2200 SCHEMA postgres สาธารณะ
pg_restore: [archiver (db)] ไม่สามารถดำเนินการค้นหา: ข้อผิดพลาด: schema "สาธารณะ" มีอยู่แล้ว
    คำสั่งคือ: สร้างสาธารณะ SCHEMA;



คำเตือน: ข้อผิดพลาดถูกละเว้นเมื่อกู้คืน: 1

ฉันไม่สามารถเพิกเฉยได้เพราะฉันใช้คำสั่งนี้โดยทางโปรแกรมและจำเป็นต้องใช้สถานะออกเพื่อตรวจสอบว่าการคืนค่าล้มเหลวหรือไม่ ตอนแรกฉันสงสัยว่าปัญหานี้เกิดขึ้นเพราะฉันใส่ฐานข้อมูลของฉันในที่สาธารณะ (schema เริ่มต้น) ฉันให้เหตุผลว่าสาธารณะจะถูกสร้างขึ้นเนื่องจาก--createตัวเลือกโดย pg_restore ก่อนที่ข้อมูลจะถูกกู้คืน (ซึ่งอาจลองสร้าง schema นั้นเช่นกันเนื่องจากเป็นที่ที่ตารางของฉันอยู่) แต่เมื่อฉันลองขั้นตอนข้างต้นกับตารางของฉัน ในสคีมาที่ต่างกันผลลัพธ์จะเหมือนกันและข้อความแสดงข้อผิดพลาดเหมือนกัน

ฉันกำลังทำอะไรผิดหรือเปล่า? เหตุใดฉันจึงเห็นข้อผิดพลาดนี้

คำตอบ:


16

ข้อผิดพลาดนั้นไม่เป็นอันตราย แต่เพื่อกำจัดมันฉันคิดว่าคุณต้องแบ่งการกู้คืนนี้ออกเป็นสองคำสั่งดังใน:

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

--cleanตัวเลือกใน pg_restore ดูไม่เหมือนมาก แต่จริง ๆ แล้วทำให้เกิดปัญหาที่ไม่น่ารำคาญ

สำหรับเวอร์ชันมากถึง 9.1

การรวมกันของ--createและ--cleanในตัวเลือก pg_restore เคยเป็นข้อผิดพลาดในรุ่น PG รุ่นเก่า (มากถึง 9.1) มีข้อโต้แย้งบางอย่างระหว่าง (อ้างถึง manpage 9.1):

- ทำความสะอาดวัตถุฐานข้อมูล (วาง) ก่อนสร้างใหม่

และ

- สร้างสร้างฐานข้อมูลก่อนที่จะกู้คืน

เพราะจุดประสงค์ของการทำความสะอาดภายในฐานข้อมูลใหม่คืออะไร

เริ่มจากเวอร์ชั่น 9.2

ชุดค่าผสมได้รับการยอมรับแล้วและหมอบอกว่าสิ่งนี้ (อ้างถึง manpage 9.3):

- ทำความสะอาดวัตถุฐานข้อมูล (หล่น) ทำความสะอาดก่อนสร้างใหม่ (สิ่งนี้อาจสร้างข้อความแสดงข้อผิดพลาดที่ไม่เป็นอันตรายหากวัตถุใด ๆ ไม่ปรากฏในฐานข้อมูลปลายทาง)

- สร้างสร้างฐานข้อมูลก่อนที่จะกู้คืน หาก --clean ถูกระบุด้วยให้ดร็อปและสร้างฐานข้อมูลเป้าหมายอีกครั้งก่อนเชื่อมต่อ

ตอนนี้การมีทั้งสองอย่างร่วมกันนำไปสู่การเรียงลำดับเช่นนี้ระหว่างการคืนค่าของคุณ:

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

ไม่มีDROPสำหรับแต่ละวัตถุเพียงหนึ่งDROP DATABASEที่จุดเริ่มต้น หากไม่ได้ใช้--createสิ่งนี้จะเป็นสิ่งที่ตรงกันข้าม

อย่างไรก็ตามลำดับนี้ทำให้เกิดข้อผิดพลาดของpublicสคีมาที่มีอยู่แล้วเนื่องจากการสร้างmydbจากtemplate0นำเข้ามาแล้ว (ซึ่งเป็นเรื่องปกติมันเป็นจุดของฐานข้อมูลแม่แบบ)

pg_restoreฉันไม่แน่ใจว่าทำไมกรณีนี้ไม่ได้ถูกจัดการโดยอัตโนมัติ บางทีสิ่งนี้อาจทำให้เกิดผลข้างเคียงที่ไม่พึงประสงค์เมื่อผู้ดูแลระบบตัดสินใจที่จะปรับแต่งtemplate0และ / หรือเปลี่ยนแปลงวัตถุประสงค์publicแม้ว่าเราไม่ควรทำเช่นนั้น


ฉันใช้ 9.6 และการระบุ--createโดยcleanไม่ได้แก้ไขปัญหา
Cerin

7

ในกรณีของฉันเหตุผลคือฉันใช้pg_restoreจาก postgresql-contrib เวอร์ชัน 11.2 เพื่อกู้คืนดัมพ์ที่ทำโดยpg_dump9.6 ไปยังคลัสเตอร์ PostgreSQL 9.6

หลังจากที่ฉันปรับลดรุ่นของฉันpg_restoreกลับเป็น 9.6 schema "public" already existsข้อผิดพลาดนี้ก็หายไปและกระบวนการกู้คืนจะทำงานเหมือนเดิม


แต่คุณกู้คืนดัมพ์โดยใช้ pg_restore 9.6 ลงในฐานข้อมูล postgres 11.2 หรือไม่?
Mariano Ruiz

@MarianoRuiz ฉันคิดว่าคำตอบดั้งเดิมของฉันชัดเจน: "ฉันใช้ pg_restore จากรุ่น postgresql-contrib 11.2 เพื่อกู้คืนการถ่ายโอนข้อมูลที่ทำโดย pg_dump 9.6 ไปยังคลัสเตอร์ PostgreSQL 9.6" ดังนั้นสำหรับคำถามของคุณ: ไม่ฉันไม่ได้ทำ pg_restore ของฉันคือ 11.2 ในขณะที่กลุ่ม pg คือ 9.6
Lu Liu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.