ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

ฉันอยากจะแบ่งปันประสบการณ์ความสำเร็จครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres ให้มีฟังก์ชันการทำงานเต็มรูปแบบ ฉันคุ้นเคยกับ Postgres DBMS เมื่อครึ่งปีที่แล้ว ก่อนหน้านั้น ฉันไม่มีประสบการณ์ในการจัดการฐานข้อมูลเลย

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

ฉันทำงานเป็นวิศวกรกึ่ง DevOps ในบริษัทไอทีขนาดใหญ่ บริษัทของเราพัฒนาซอฟต์แวร์สำหรับบริการที่มีการโหลดสูง และฉันต้องรับผิดชอบด้านประสิทธิภาพ การบำรุงรักษา และการปรับใช้ ฉันได้รับงานมาตรฐาน: อัปเดตแอปพลิเคชันบนเซิร์ฟเวอร์เดียว แอปพลิเคชันเขียนด้วยภาษา Django ในระหว่างดำเนินการย้ายข้อมูลอัปเดต (การเปลี่ยนแปลงโครงสร้างฐานข้อมูล) และก่อนที่กระบวนการนี้เราจะถ่ายโอนฐานข้อมูลแบบเต็มผ่านโปรแกรม pg_dump มาตรฐาน ในกรณีนี้

เกิดข้อผิดพลาดที่ไม่คาดคิดขณะทำการดัมพ์ (Postgres เวอร์ชัน 9.5):

pg_dump: Oumping the contents of table “ws_log_smevlog” failed: PQgetResult() failed.
pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989
pg_dump: The command was: COPY public.ws_log_smevlog [...]
pg_dunp: [parallel archtver] a worker process dled unexpectedly

แมลง "หน้าไม่ถูกต้องในการบล็อก" พูดถึงปัญหาในระดับระบบไฟล์ซึ่งแย่มาก ในกระดานสนทนาต่างๆ ก็แนะนำให้ทำ สุญญากาศเต็ม พร้อมตัวเลือก zero_damaged_pages เพื่อแก้ไขปัญหานี้ เอาล่ะ มาลองกัน...

การเตรียมตัวสำหรับการฟื้นฟู

คำเตือน! อย่าลืมสำรองข้อมูล Postgres ก่อนที่จะพยายามกู้คืนฐานข้อมูลของคุณ หากคุณมีเครื่องเสมือน ให้หยุดฐานข้อมูลและถ่ายภาพสแนปช็อต หากไม่สามารถถ่ายภาพสแน็ปช็อตได้ ให้หยุดฐานข้อมูลและคัดลอกเนื้อหาของไดเร็กทอรี Postgres (รวมถึงไฟล์ wal) ไปยังที่ปลอดภัย สิ่งสำคัญในธุรกิจของเราคือการไม่ทำให้สิ่งต่างๆ แย่ลง อ่าน มัน.

เนื่องจากโดยทั่วไปแล้วฐานข้อมูลใช้งานได้สำหรับฉัน ฉันจึงจำกัดตัวเองให้อยู่ในดัมพ์ฐานข้อมูลทั่วไป แต่ไม่รวมตารางที่มีข้อมูลที่เสียหาย (ตัวเลือก -T, --ไม่รวมตาราง=TABLE ใน pg_dump)

เซิร์ฟเวอร์เป็นแบบฟิสิคัล จึงไม่สามารถถ่ายภาพสแนปช็อตได้ ข้อมูลสำรองถูกลบออกแล้ว ดำเนินการต่อได้เลย

การตรวจสอบระบบไฟล์

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

ในกรณีของฉัน ระบบไฟล์ที่มีฐานข้อมูลถูกเมานท์อยู่ "/srv" และประเภทคือ ex4

การหยุดฐานข้อมูล: systemctl หยุด [ป้องกันอีเมล] และตรวจสอบว่าระบบไฟล์ไม่ได้ถูกใช้งานโดยใครก็ตาม และสามารถยกเลิกการต่อเชื่อมได้โดยใช้คำสั่ง ลซ:
lsof +D /srv

ฉันยังต้องหยุดฐานข้อมูล Redis เนื่องจากฐานข้อมูลนั้นใช้งานอยู่ด้วย "/srv". ต่อไปฉันยกเลิกการต่อเชื่อม / srv (จำนวน)

ตรวจสอบระบบไฟล์โดยใช้ยูทิลิตี้ e2fsck ด้วยสวิตช์ -f (บังคับให้ตรวจสอบแม้ว่าระบบไฟล์จะถูกทำเครื่องหมายว่าสะอาดก็ตาม):

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

ถัดไปโดยใช้ยูทิลิตี้ ทิ้ง2fs (sudo dumpe2fs /dev/mapper/gu2—sys-srv | grep ตรวจสอบแล้ว) คุณสามารถตรวจสอบได้ว่ามีการดำเนินการตรวจสอบจริงหรือไม่:

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

e2fsck บอกว่าไม่พบปัญหาในระดับระบบไฟล์ ext4 ซึ่งหมายความว่าคุณสามารถพยายามกู้คืนฐานข้อมูลต่อไปหรือกลับไปที่ สูญญากาศเต็ม (แน่นอน คุณต้องเมานต์ระบบไฟล์กลับและเริ่มฐานข้อมูล)

หากคุณมีเซิร์ฟเวอร์จริง โปรดตรวจสอบสถานะของดิสก์ (ผ่าน smartctl -a /dev/XXX) หรือตัวควบคุม RAID เพื่อให้แน่ใจว่าปัญหาไม่ได้อยู่ที่ระดับฮาร์ดแวร์ ในกรณีของฉัน RAID กลายเป็น “ฮาร์ดแวร์” ดังนั้นฉันจึงขอให้ผู้ดูแลระบบในพื้นที่ตรวจสอบสถานะของ RAID (เซิร์ฟเวอร์อยู่ห่างจากฉันหลายร้อยกิโลเมตร) เขาบอกว่าไม่มีข้อผิดพลาด ซึ่งหมายความว่าเราสามารถเริ่มการบูรณะได้อย่างแน่นอน

ความพยายามที่ 1: zero_damaged_pages

เราเชื่อมต่อกับฐานข้อมูลผ่าน psql ด้วยบัญชีที่มีสิทธิ์ superuser เราต้องการ superuser เพราะ... ตัวเลือก zero_damaged_pages มีเพียงเขาเท่านั้นที่สามารถเปลี่ยนแปลงได้ ในกรณีของฉันมันคือ postgres:

psql -h 127.0.0.1 -U postgres -s [ฐานข้อมูล_ชื่อ]

ตัวเลือก zero_damaged_pages จำเป็นเพื่อเพิกเฉยต่อข้อผิดพลาดในการอ่าน (จากเว็บไซต์ postgrespro):

เมื่อ PostgreSQL ตรวจพบส่วนหัวของเพจที่เสียหาย โดยทั่วไปจะรายงานข้อผิดพลาดและยกเลิกธุรกรรมปัจจุบัน หากเปิดใช้งาน zero_damaged_pages ระบบจะออกคำเตือนแทน กำจัดหน้าที่เสียหายในหน่วยความจำเป็นศูนย์ และดำเนินการประมวลผลต่อ ลักษณะการทำงานนี้จะทำลายข้อมูล กล่าวคือ แถวทั้งหมดในเพจที่เสียหาย

เราเปิดใช้งานตัวเลือกนี้และพยายามดูดตารางทั้งหมด:

VACUUM FULL VERBOSE

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)
น่าเสียดายที่โชคร้าย

เราพบข้อผิดพลาดที่คล้ายกัน:

INFO: vacuuming "“public.ws_log_smevlog”
WARNING: invalid page in block 4123007 of relation base/16400/21396989; zeroing out page
ERROR: unexpected chunk number 573 (expected 565) for toast value 21648541 in pg_toast_106070

pg_toast - กลไกในการจัดเก็บข้อมูล "ข้อมูลขนาดยาว" ใน Poetgres หากไม่พอดีกับหน้าเดียว (8kb โดยค่าเริ่มต้น)

ความพยายามที่ 2: จัดทำดัชนีใหม่

คำแนะนำแรกจาก Google ไม่ได้ช่วยอะไร หลังจากค้นหาไม่กี่นาที ฉันพบเคล็ดลับที่สอง - ต้องทำ สร้างดัชนีใหม่ โต๊ะเสียหาย ฉันเห็นคำแนะนำนี้ในหลายๆ แห่ง แต่ไม่ได้สร้างแรงบันดาลใจให้เกิดความมั่นใจ มาจัดทำดัชนีใหม่:

reindex table ws_log_smevlog

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

สร้างดัชนีใหม่ เสร็จสิ้นโดยไม่มีปัญหา

อย่างไรก็ตาม สิ่งนี้ไม่ได้ช่วยอะไร สูญญากาศเต็ม ขัดข้องด้วยข้อผิดพลาดที่คล้ายกัน เนื่องจากฉันคุ้นเคยกับความล้มเหลว ฉันจึงเริ่มค้นหาคำแนะนำเพิ่มเติมทางอินเทอร์เน็ตและพบสิ่งที่ค่อนข้างน่าสนใจ บทความ.

ความพยายามที่ 3: เลือก, จำกัด, ออฟเซ็ต

บทความข้างต้นแนะนำให้ดูตารางทีละแถวและลบข้อมูลที่เป็นปัญหาออก ก่อนอื่นเราต้องดูทุกบรรทัด:

for ((i=0; i<"Number_of_rows_in_nodes"; i++ )); do psql -U "Username" "Database Name" -c "SELECT * FROM nodes LIMIT 1 offset $i" >/dev/null || echo $i; done

ในกรณีของฉัน ตารางมีอยู่ 1 628 991 เส้น! จำเป็นต้องดูแลอย่างดี การแบ่งพาร์ติชันข้อมูลแต่นี่เป็นหัวข้อสำหรับการสนทนาแยกต่างหาก เป็นวันเสาร์ ฉันรันคำสั่งนี้ใน tmux และเข้านอน:

for ((i=0; i<1628991; i++ )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog LIMIT 1 offset $i" >/dev/null || echo $i; done

ตอนเช้าฉันตัดสินใจตรวจสอบว่าสิ่งต่างๆ เป็นอย่างไรบ้าง ฉันประหลาดใจมากที่พบว่าหลังจาก 20 ชั่วโมง มีการสแกนข้อมูลเพียง 2% เท่านั้น! ฉันไม่ต้องการที่จะรอ 50 วัน ความล้มเหลวโดยสิ้นเชิงอีกประการหนึ่ง

แต่ฉันไม่ยอมแพ้ ฉันสงสัยว่าทำไมการสแกนจึงใช้เวลานานมาก จากเอกสาร (อีกครั้งใน postgrespro) ฉันพบว่า:

OFFSET ระบุให้ข้ามจำนวนแถวที่ระบุก่อนที่จะเริ่มส่งออกแถว
หากมีการระบุทั้ง OFFSET และ LIMIT ระบบจะข้ามแถว OFFSET ก่อน จากนั้นจึงเริ่มนับแถวสำหรับข้อจำกัด LIMIT

เมื่อใช้ LIMIT สิ่งสำคัญคือต้องใช้คำสั่งย่อย ORDER BY เพื่อให้แถวผลลัพธ์ส่งคืนในลำดับเฉพาะ มิฉะนั้น ระบบจะส่งคืนชุดย่อยของแถวที่คาดเดาไม่ได้

เห็นได้ชัดว่าคำสั่งข้างต้นผิด ประการแรกไม่มี สั่งซื้อโดยผลลัพธ์ที่ได้อาจผิดพลาดได้ ประการที่สอง Postgres ต้องสแกนและข้ามแถว OFFSET ก่อน และเพิ่มขึ้นเรื่อยๆ OFFSET ผลผลิตก็จะลดลงไปอีก

ความพยายามที่ 4: ถ่ายโอนข้อมูลในรูปแบบข้อความ

จากนั้นความคิดที่ยอดเยี่ยมก็เข้ามาในใจของฉัน: ทิ้งข้อมูลในรูปแบบข้อความและวิเคราะห์บรรทัดสุดท้ายที่บันทึกไว้

แต่ก่อนอื่นเรามาดูโครงสร้างของตารางกันก่อน ws_log_smevlog:

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

ในกรณีของเรา เรามีคอลัมน์ "Id"ซึ่งมีตัวระบุเฉพาะ (ตัวนับ) ของแถว แผนเป็นดังนี้:

  1. เราเริ่มถ่ายโอนข้อมูลในรูปแบบข้อความ (ในรูปแบบของคำสั่ง sql)
  2. ณ จุดหนึ่ง ดัมพ์จะถูกขัดจังหวะเนื่องจากมีข้อผิดพลาด แต่ไฟล์ข้อความจะยังคงถูกบันทึกไว้บนดิสก์
  3. เราดูที่ส่วนท้ายของไฟล์ข้อความดังนั้นเราจึงพบตัวระบุ (id) ของบรรทัดสุดท้ายที่ถูกลบออกได้สำเร็จ

ฉันเริ่มทิ้งข้อมูลในรูปแบบข้อความ:

pg_dump -U my_user -d my_database -F p -t ws_log_smevlog -f ./my_dump.dump

ดัมพ์ตามที่คาดไว้ ถูกขัดจังหวะด้วยข้อผิดพลาดเดียวกัน:

pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989

ผ่านต่อไป หาง ฉันดูที่ส่วนท้ายของการถ่ายโอนข้อมูล (หาง -5 ./my_dump.dump) พบว่าดัมพ์ถูกขัดจังหวะในบรรทัดด้วย id 186 525. “ดังนั้นปัญหาอยู่ในบรรทัด id 186 526 มันใช้งานไม่ได้และจำเป็นต้องลบ!” - ฉันคิด. แต่การสืบค้นไปยังฐานข้อมูล:
«เลือก * จาก ws_log_smevlog โดยที่ id=186529“ ปรากฎว่าทุกอย่างเรียบร้อยดีกับบรรทัดนี้... แถวที่มีดัชนี 186 - 530 ก็ใช้งานได้โดยไม่มีปัญหาเช่นกัน “ความคิดที่ยอดเยี่ยม” อีกอย่างหนึ่งล้มเหลว ต่อมาฉันเข้าใจว่าทำไมสิ่งนี้จึงเกิดขึ้น: เมื่อลบและเปลี่ยนแปลงข้อมูลจากตาราง พวกเขาจะไม่ถูกลบทางกายภาพ แต่ถูกทำเครื่องหมายเป็น "สิ่งอันดับที่ตายแล้ว" จากนั้นก็มา เครื่องดูดฝุ่นอัตโนมัติ และทำเครื่องหมายบรรทัดเหล่านี้ว่าลบแล้ว และอนุญาตให้ใช้บรรทัดเหล่านี้ซ้ำได้ เพื่อให้เข้าใจว่าหากข้อมูลในตารางเปลี่ยนแปลงและเปิดใช้งาน autovacuum ข้อมูลดังกล่าวจะไม่ถูกจัดเก็บตามลำดับ

ความพยายามที่ 5: SELECT, FROM, WHERE id=

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

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

หากใครไม่เข้าใจ คำสั่งจะทำงานดังนี้ โดยจะสแกนตารางทีละแถว และส่ง stdout ไปที่ / dev / nullแต่ถ้าคำสั่ง SELECT ล้มเหลว ข้อความแสดงข้อผิดพลาดจะถูกพิมพ์ (stderr ถูกส่งไปยังคอนโซล) และบรรทัดที่มีข้อผิดพลาดจะถูกพิมพ์ (ขอบคุณ || ซึ่งหมายความว่าการเลือกมีปัญหา (โค้ดส่งคืนของคำสั่ง ไม่ใช่ 0))

ฉันโชคดีที่ฉันมีดัชนีที่สร้างขึ้นบนสนาม id:

ประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres หลังจากเกิดความล้มเหลว (หน้าที่ไม่ถูกต้องในบล็อก 4123007 ของฐาน relatton/16490)

ซึ่งหมายความว่าการค้นหาบรรทัดที่มีรหัสที่ต้องการไม่ควรใช้เวลามากนัก ตามทฤษฎีแล้ว มันควรจะได้ผล เอาล่ะ เรามารันคำสั่งกัน tmux และไปนอนกันเถอะ

ในตอนเช้าฉันพบว่ามีการดูรายการประมาณ 90 รายการ ซึ่งมากกว่า 000% เท่านั้น ผลลัพธ์ที่ยอดเยี่ยมเมื่อเทียบกับวิธีก่อนหน้า (5%)! แต่ฉันไม่อยากรอถึง 2 วัน...

ความพยายามที่ 6: SELECT, FROM, WHERE id >= และ id <

ลูกค้ามีเซิร์ฟเวอร์ที่ยอดเยี่ยมสำหรับฐานข้อมูลโดยเฉพาะ: โปรเซสเซอร์คู่ Intel Xeon E5-2697 v2มีกระทู้มากถึง 48 กระทู้ในตำแหน่งของเรา! โหลดบนเซิร์ฟเวอร์อยู่ในระดับปานกลาง เราสามารถดาวน์โหลดได้ประมาณ 20 เธรดโดยไม่มีปัญหาใดๆ นอกจากนี้ยังมี RAM เพียงพอ: มากถึง 384 กิกะไบต์!

ดังนั้น คำสั่งจำเป็นต้องทำแบบขนาน:

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

ที่นี่เป็นไปได้ที่จะเขียนสคริปต์ที่สวยงามและสง่างาม แต่ฉันเลือกวิธีการขนานที่เร็วที่สุด: แบ่งช่วง 0-1628991 ด้วยตนเองออกเป็นช่วง 100 ระเบียนและเรียกใช้คำสั่ง 000 คำสั่งแยกกันของแบบฟอร์ม:

for ((i=N; i<M; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

แต่นั่นไม่ใช่ทั้งหมด ตามทฤษฎีแล้ว การเชื่อมต่อกับฐานข้อมูลยังต้องใช้เวลาและทรัพยากรระบบด้วย การเชื่อมต่อ 1 นั้นไม่ฉลาดนักคุณจะเห็นด้วย ดังนั้น เรามาดึงข้อมูล 628 แถวแทนการเชื่อมต่อแบบหนึ่งต่อหนึ่งกัน เป็นผลให้ทีมงานเปลี่ยนมาเป็น:

for ((i=N; i<M; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

เปิด 16 หน้าต่างในเซสชัน tmux และรันคำสั่ง:

1) for ((i=0; i<100000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
2) for ((i=100000; i<200000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
…
15) for ((i=1400000; i<1500000; i=$((i+1000)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
16) for ((i=1500000; i<1628991; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

วันต่อมาฉันก็ได้รับผลลัพธ์แรก! กล่าวคือ (ค่า XXX และ ZZZ จะไม่ถูกรักษาไว้อีกต่อไป):

ERROR:  missing chunk number 0 for toast value 37837571 in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value XXX in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value ZZZ in pg_toast_106070
146000

ซึ่งหมายความว่าสามบรรทัดมีข้อผิดพลาด รหัสของบันทึกที่มีปัญหาตัวแรกและตัวที่สองอยู่ระหว่าง 829 ถึง 000 รหัสของบันทึกที่สามอยู่ระหว่าง 830 ถึง 000 ต่อไป เราเพียงแค่ต้องค้นหาค่ารหัสที่แน่นอนของบันทึกที่มีปัญหา ในการทำเช่นนี้ เราจะตรวจสอบช่วงของเราที่มีบันทึกที่มีปัญหาด้วยขั้นตอนที่ 146 และระบุรหัส:

for ((i=829000; i<830000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number 2 (expected 0) for toast value 37837843 in pg_toast_106070
829449
for ((i=146000; i<147000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number ZZZ (expected 0) for toast value XXX in pg_toast_106070
146911

จบลงอย่างมีความสุข

เราพบเส้นที่มีปัญหา เราเข้าไปในฐานข้อมูลผ่าน psql แล้วลองลบมัน:

my_database=# delete from ws_log_smevlog where id=829417;
DELETE 1
my_database=# delete from ws_log_smevlog where id=829449;
DELETE 1
my_database=# delete from ws_log_smevlog where id=146911;
DELETE 1

ฉันประหลาดใจมากที่รายการถูกลบโดยไม่มีปัญหาใดๆ แม้ว่าจะไม่มีตัวเลือกก็ตาม zero_damaged_pages.

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

รับทราบและสรุป

นี่เป็นประสบการณ์ครั้งแรกของฉันในการกู้คืนฐานข้อมูล Postgres จริง ฉันจะจดจำประสบการณ์นี้ไปอีกนาน

และสุดท้ายนี้ ฉันอยากจะกล่าวขอบคุณ PostgresPro สำหรับการแปลเอกสารเป็นภาษารัสเซียและสำหรับ หลักสูตรออนไลน์ฟรีที่สมบูรณ์ซึ่งช่วยได้มากในระหว่างการวิเคราะห์ปัญหา

ที่มา: will.com

เพิ่มความคิดเห็น