ข้อผิดพลาด pg_restore: ไม่มีฟังก์ชัน Raise_err (ไม่ทราบ)

ฉันสำรองข้อมูลฐานข้อมูลของฉันทุกวันโดยใช้ pg_dump และ pg_restore ที่เพิ่งหยุดทำงานหลังจากที่ฉันพุชการอัปเดต

ฉันมีฟังก์ชัน validate_id ซึ่งเป็นคำสั่ง Case/When เช่นเดียวกับการตรวจสอบข้อมูลบางส่วนที่มีปัญหาด้านความสมบูรณ์อย่างรวดเร็ว มีลักษณะดังนี้:

CREATE OR REPLACE FUNCTION validate_id(
    _string text,
    _type type
) RETURNS boolean AS
$$
SELECT
    CASE WHEN (stuff) THEN TRUE
    WHEN (other stuff) THEN TRUE
    When (more stuff) THEN raise_err('Not an accepted type, the accepted types are: x y z')
ELSE FALSE
$$
LANGUAGE SQL;

เนื่องจากฉันเพิ่มฟังก์ชันนี้ เมื่อฉันดัมพ์โดยใช้คำสั่งนี้:

pg_dump -U postgres -h ipaddress -p 5432 -w -F t databaseName > backupsfolder/databaseName.tar

เมื่อฉันใช้คำสั่งนี้:

pg_restore -U postgres -h localhost -p 5432 -d postgres -C "backupsfolder/databaseName.tar"

เมื่อสองวันก่อน ตอนนี้เกิดข้อผิดพลาด:

pg_restore: error: could not execute query: ERROR: function raise_err(unknown) does not exist

ฉันค่อนข้างหลงทางว่าจะทำอย่างไร ฉันคิดว่าสิ่งที่อาจเกิดขึ้นคือพยายามกู้คืนฟังก์ชันนี้ก่อนที่จะกู้คืนฟังก์ชัน raise_err ซึ่งฉันคิดว่ามีอยู่แล้วใน postgres (ฉันทำได้ SELECT raise_err('Hello, World');) เป็นไปได้ไหม? มันเป็นคำสั่ง CASE ของฉันหรือเปล่าเพราะฉันต้องส่งคืนเฉพาะ Booleans เท่านั้น การอนุญาตทั้งหมดดูเหมือนถูกต้องและการกู้คืนด้วยการสำรองข้อมูลก่อนหน้านี้ก็ใช้ได้ดี


person HelpMeExitVim    schedule 20.08.2020    source แหล่งที่มา
comment
ล็อกอินเข้าสู่ฐานข้อมูลต้นทางของคุณด้วย psql และทำ \df+ raise_err นั่นไม่ใช่ฟังก์ชันมาตรฐานเท่าที่ฉันรู้ คุณไม่จำเป็นต้องมีฟังก์ชันอื่นในการเพิ่มข้อผิดพลาดเนื่องจากคุณสามารถทำได้ raise error   -  person Mike Organek    schedule 21.08.2020
comment
มันใช้งานได้กับฟังก์ชันที่เขียนด้วย sql หรือต้องเป็น plpgsql?   -  person HelpMeExitVim    schedule 21.08.2020
comment
\df+ raise_err ไม่...ส่งคืนฟังก์ชัน มันไม่ใช่สิ่งที่ฉันจำได้อย่างชัดเจนถึงการสร้าง แต่ฉันหมายถึง สิ่งต่างๆ เกิดขึ้น   -  person HelpMeExitVim    schedule 21.08.2020
comment
ขออภัยฉันไม่ได้คิดเรื่องนั้น language sql จะไม่รองรับ และนั่นอาจอธิบายได้ว่าทำไมคุณถึงเขียนมันเป็นฟังก์ชัน นอกจากนี้ มันคือ raise exception ไม่ใช่ raise error อย่างที่ฉันพูดผิดในความคิดเห็นก่อนหน้า ดูเหมือนว่าบางครั้งสิ่งนี้จะเกิดขึ้น: stackoverflow.com/q/30707533/13808319   -  person Mike Organek    schedule 21.08.2020
comment
สุดยอด! นี่มันฉันรู้สึกโง่สุดๆ ขอขอบคุณสำหรับความช่วยเหลือของคุณ!   -  person HelpMeExitVim    schedule 21.08.2020
comment
คุณใช้สิ่งนี้เป็นฟังก์ชัน CHECK หรือไม่ หากเป็นเช่นนั้น createtable ที่ไม่สามารถทำได้: ในปัจจุบัน ให้ตรวจสอบนิพจน์ ไม่สามารถมีแบบสอบถามย่อยหรืออ้างอิงถึงตัวแปรอื่นนอกเหนือจากคอลัมน์ของแถวปัจจุบัน (ดูหัวข้อ 5.4.1) คอลัมน์ระบบ tableoid อาจอ้างอิงได้ แต่ไม่ใช่คอลัมน์ระบบอื่นๆ   -  person Adrian Klaver    schedule 21.08.2020
comment
อย่ารู้สึกโง่ การสร้างฟังก์ชันนั้นสมเหตุสมผลดี IMO ฉันสงสัยว่าความจริงที่ว่านี่คือฟังก์ชัน language sql ทำให้อัลโกสับสนในการพยายามค้นหาการพึ่งพาระหว่าง pg_backup   -  person Mike Organek    schedule 21.08.2020


คำตอบ (2)


ปัญหาคือ raise_err ไม่ผ่านคุณสมบัติสคีมาในโค้ดฟังก์ชันของคุณ

สิ่งนี้อาจเป็นอันตราย: ผู้ใช้ที่ประสงค์ร้ายสามารถสร้างฟังก์ชันของตนเอง raise_err และตั้งค่า search_path เพื่อให้เรียกใช้ฟังก์ชันที่ไม่ถูกต้อง

เนื่องจากโดยทั่วไปแล้ว pg_restore จะถูกเรียกใช้โดย superuser นี่อาจเป็นปัญหาด้านความปลอดภัยได้ ลองนึกภาพฟังก์ชันดังกล่าวที่ใช้ในคำจำกัดความของดัชนี!

ด้วยเหตุผลเหล่านี้ pg_dump และ pg_restore จึงตั้งค่า search_path ว่างใน PostgreSQL เวอร์ชันปัจจุบัน

วิธีแก้ไขปัญหาของคุณคือการใช้สคีมาของฟังก์ชันในคำสั่ง SQL ของคุณอย่างชัดเจน

person Laurenz Albe    schedule 21.08.2020

ฉันลงเอยด้วยการแก้ไขปัญหานี้ด้วยการตั้งค่าเส้นทางการค้นหาสำหรับทั้งสองฟังก์ชันอย่างชัดเจน raise_err() และ validate_id() เป็น public:

ALTER FUNCTION validate_id(text,text) SET search_path=public;
ALTER FUNCTION raise_err(text,text) SET search_path=public;
person HelpMeExitVim    schedule 25.08.2020