การจำลองแบบไม่ใช่การสำรองข้อมูล หรือไม่? ต่อไปนี้คือวิธีที่เราใช้การจำลองแบบแบบขี้เกียจเพื่อการกู้คืนโดยการลบทางลัดโดยไม่ตั้งใจ
การจำลองแบบไม่ใช่เครื่องมือสำรองฐานข้อมูลของคุณ (gitlab-ce
ด้วยแบบจำลองที่ล่าช้า เราจึงกู้คืนข้อมูลได้ในเวลาเพียง 1,5 ชั่วโมง ดูว่ามันเป็นอย่างไร
การกู้คืนตามเวลาด้วย PostgreSQL
PostgreSQL มีฟังก์ชันในตัวที่จะกู้คืนสถานะของฐานข้อมูลไปยังเวลาที่กำหนด มันถูกเรียกว่า
ในการใช้คุณสมบัตินี้สำหรับการสำรองข้อมูลแบบ Cold เราทำการสำรองข้อมูลฐานข้อมูลพื้นฐานเป็นประจำและจัดเก็บไว้ในไฟล์เก็บถาวร (ไฟล์เก็บถาวร GitLab อยู่ใน
การจำลองแบบล่าช้าคืออะไร?
การจำลองแบบล่าช้าเป็นการนำการเปลี่ยนแปลงจาก WAL มาใช้โดยมีความล่าช้า นั่นคือการทำธุรกรรมเกิดขึ้นในชั่วโมง X
แต่จะปรากฏในแบบจำลองด้วยความล่าช้า d
ในหนึ่งชั่วโมง X + d
.
มี 2 วิธีในการตั้งค่าแบบจำลองฐานข้อมูลจริงใน PostgreSQL: การกู้คืนไฟล์เก็บถาวรและการจำลองแบบสตรีมมิง
วิธีตั้งค่าการกู้คืนข้อมูลสำรองที่ล่าช้า
recovery.conf
. ตัวอย่างเช่น:
standby_mode = 'on'
restore_command = '/usr/bin/envdir /etc/wal-e.d/env /opt/wal-e/bin/wal-e wal-fetch -p 4 "%f" "%p"'
recovery_min_apply_delay = '8h'
recovery_target_timeline = 'latest'
ด้วยการตั้งค่าเหล่านี้ เราได้กำหนดค่าแบบจำลองที่ล่าช้าพร้อมการคืนค่าไฟล์เก็บถาวร ใช้ที่นี่ restore_command
) จากไฟล์เก็บถาวร และการเปลี่ยนแปลงจะมีผลหลังจากแปดชั่วโมง (recovery_min_apply_delay
). แบบจำลองจะเฝ้าดูการเปลี่ยนแปลงไทม์ไลน์ในไฟล์เก็บถาวร เช่น เนื่องจากคลัสเตอร์ล้มเหลว (recovery_target_timeline
).
С recovery_min_apply_delay
คุณสามารถตั้งค่าการจำลองการสตรีมแบบแฝงได้ แต่มีข้อผิดพลาดสองสามประการที่เกี่ยวข้องกับสล็อตการจำลองแบบ ข้อเสนอแนะสำรองด่วน และอื่นๆ ไฟล์เก็บถาวร WAL หลีกเลี่ยงพวกเขา
พารามิเตอร์ recovery_min_apply_delay
ปรากฏเฉพาะใน PostgreSQL 9.3 ในเวอร์ชันก่อนหน้า การจำลองแบบล่าช้าต้องใช้การรวมกัน pg_xlog_replay_pause(), pg_xlog_replay_resume()
) หรือเก็บส่วน WAL ในไฟล์เก็บถาวรในช่วงระยะเวลาของการหน่วงเวลา
PostgreSQL ทำอย่างไร
เป็นเรื่องที่น่าสนใจที่จะดูว่า PostgreSQL ใช้การคืนค่าแบบขี้เกียจได้อย่างไร ลองดูที่ recoveryApplyDelay(XlogReaderState)
static bool
recoveryApplyDelay(XLogReaderState *record)
{
uint8 xact_info;
TimestampTz xtime;
long secs;
int microsecs;
/* nothing to do if no delay configured */
if (recovery_min_apply_delay <= 0)
return false;
/* no delay is applied on a database not yet consistent */
if (!reachedConsistency)
return false;
/*
* Is it a COMMIT record?
*
* We deliberately choose not to delay aborts since they have no effect on
* MVCC. We already allow replay of records that don't have a timestamp,
* so there is already opportunity for issues caused by early conflicts on
* standbys.
*/
if (XLogRecGetRmid(record) != RM_XACT_ID)
return false;
xact_info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
if (xact_info != XLOG_XACT_COMMIT &&
xact_info != XLOG_XACT_COMMIT_PREPARED)
return false;
if (!getRecordTimestamp(record, &xtime))
return false;
recoveryDelayUntilTime =
TimestampTzPlusMilliseconds(xtime, recovery_min_apply_delay);
/*
* Exit without arming the latch if it's already past time to apply this
* record
*/
TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime,
&secs, µsecs);
if (secs <= 0 && microsecs <= 0)
return false;
while (true)
{
// Shortened:
// Use WaitLatch until we reached recoveryDelayUntilTime
// and then
break;
}
return true;
}
บรรทัดล่างคือความล่าช้านั้นขึ้นอยู่กับเวลาทางกายภาพที่บันทึกไว้ในการประทับเวลาของธุรกรรมที่กระทำ (xtime
). อย่างที่คุณเห็น การหน่วงเวลามีผลกับคอมมิชชันเท่านั้นและไม่ส่งผลต่อเรกคอร์ดอื่นๆ การเปลี่ยนแปลงทั้งหมดจะถูกนำไปใช้โดยตรง และการคอมมิตจะล่าช้า ดังนั้นเราจะเห็นการเปลี่ยนแปลงหลังจากการหน่วงเวลาที่กำหนดเท่านั้น
วิธีการใช้ Lazy Replica ในการกู้คืนข้อมูล
สมมติว่าเรามีคลัสเตอร์ฐานข้อมูลในการผลิตและแบบจำลองที่มีความล่าช้าแปดชั่วโมง ลองดูวิธีการกู้คืนข้อมูลโดยใช้ตัวอย่าง
เมื่อเราทราบปัญหาแล้ว
SELECT pg_xlog_replay_pause();
เมื่อหยุดชั่วคราว เราไม่มีความเสี่ยงที่ตัวจำลองจะทำซ้ำคำขอ DELETE
. สิ่งที่มีประโยชน์ถ้าคุณต้องการเวลาในการคิดทุกอย่างออก
บรรทัดล่างคือแบบจำลองที่ล่าช้าจะต้องไปถึงช่วงเวลาก่อนคำขอ DELETE
. เรารู้เวลาทางกายภาพของการกำจัดโดยประมาณ เราลบออก recovery_min_apply_delay
และเพิ่ม recovery_target_time
в recovery.conf
. ดังนั้นแบบจำลองจึงมาถึงช่วงเวลาที่เหมาะสมโดยไม่ชักช้า:
recovery_target_time = '2018-10-12 09:25:00+00'
ด้วยการประทับเวลา จะเป็นการดีกว่าที่จะลดส่วนเกินเพื่อไม่ให้พลาด จริงอยู่ที่ยิ่งลดลงมากเท่าใด ข้อมูลก็ยิ่งสูญเสียมากขึ้นเท่านั้น อีกครั้งหากเราข้ามคำขอ DELETE
ทุกอย่างจะถูกลบอีกครั้งและคุณจะต้องเริ่มต้นใหม่ (หรือแม้แต่ทำการสำรองข้อมูลแบบเย็นสำหรับ PITR)
เรารีสตาร์ทอินสแตนซ์ Postgres ที่ล่าช้า และส่วน WAL ถูกทำซ้ำจนกว่าจะถึงเวลาที่กำหนด คุณสามารถติดตามความคืบหน้าในขั้นตอนนี้ได้โดยการสอบถาม:
SELECT
-- current location in WAL
pg_last_xlog_replay_location(),
-- current transaction timestamp (state of the replica)
pg_last_xact_replay_timestamp(),
-- current physical time
now(),
-- the amount of time still to be applied until recovery_target_time has been reached
'2018-10-12 09:25:00+00'::timestamptz - pg_last_xact_replay_timestamp() as delay;
หากการประทับเวลาไม่เปลี่ยนแปลงอีกต่อไป แสดงว่าการคืนค่าเสร็จสมบูรณ์ คุณสามารถปรับแต่งการกระทำ recovery_target_action
ฐานข้อมูลมาถึงสถานะก่อนคำขอที่โชคร้าย ตอนนี้คุณสามารถส่งออกข้อมูลได้ เราได้ส่งออกข้อมูลฉลากระยะไกลและลิงก์ทั้งหมดไปยังปัญหาและรวมคำขอและโอนไปยังฐานข้อมูลการผลิต หากการสูญเสียมีมาก คุณสามารถโปรโมตแบบจำลองและใช้เป็นตัวหลักได้ แต่การเปลี่ยนแปลงทั้งหมดจะหายไปหลังจากช่วงเวลาที่เรากู้คืน
ควรใช้รหัสธุรกรรมแทนการประทับเวลา การบันทึก ID เหล่านี้มีประโยชน์ เช่น สำหรับคำสั่ง DDL (เช่น DROP TABLE
), โดยใช้ log_statements = 'ddl'
. ถ้าเรามี ID ธุรกรรม เราจะใช้ recovery_target_xid
และดำเนินการทุกอย่างลงไปที่การทำธุรกรรมก่อนการร้องขอ DELETE
.
การกลับไปทำงานนั้นง่ายมาก: ลบการเปลี่ยนแปลงทั้งหมดจาก recovery.conf
และรีสตาร์ท postgres อีกไม่นาน สัญญาณจะดีเลย์แปดชั่วโมงอีกครั้ง และเราพร้อมสำหรับปัญหาในอนาคต
ผลประโยชน์การกู้คืน
ด้วยแบบจำลองที่ล่าช้า แทนที่จะเป็นการสำรองข้อมูลแบบเย็น คุณไม่จำเป็นต้องใช้เวลาหลายชั่วโมงในการกู้คืนสแน็ปช็อตทั้งหมดจากไฟล์เก็บถาวร ตัวอย่างเช่น เราต้องใช้เวลาห้าชั่วโมงในการสำรองข้อมูลพื้นฐานขนาด 2 TB ทั้งหมด จากนั้นคุณยังคงต้องใช้ WAL รายวันทั้งหมดเพื่อกู้คืนไปยังสถานะที่ต้องการ (ในกรณีที่เลวร้ายที่สุด)
แบบจำลองที่ล่าช้านั้นดีกว่าการสำรองข้อมูลแบบเย็นในสองวิธี:
- คุณไม่จำเป็นต้องรับข้อมูลสำรองฐานทั้งหมดจากไฟล์เก็บถาวร
- มีช่วงเวลาแปดชั่วโมงคงที่สำหรับส่วน WAL ที่ต้องทำซ้ำ
นอกจากนี้ เรากำลังตรวจสอบอย่างต่อเนื่องเพื่อดูว่า WAL สามารถเป็น PITRed ได้หรือไม่ และเราจะสังเกตเห็นความเสียหายหรือปัญหาอื่นๆ อย่างรวดเร็วกับไฟล์เก็บถาวร WAL โดยการตรวจสอบงานในมือของแบบจำลองที่ล่าช้า
ในตัวอย่างนี้ เราใช้เวลา 50 นาทีในการกู้คืน กล่าวคือ ความเร็วคือข้อมูล WAL 110 GB ต่อชั่วโมง (ไฟล์เก็บถาวรยังเปิดอยู่
สรุป: ที่การจำลองแบบล่าช้ามีประโยชน์ (และที่ใดไม่)
ใช้การจำลองแบบล่าช้าเป็นการปฐมพยาบาลหากคุณสูญเสียข้อมูลโดยไม่ตั้งใจและสังเกตเห็นภัยพิบัตินี้ภายในการหน่วงเวลาที่กำหนด
แต่โปรดจำไว้ว่า: การจำลองแบบไม่ใช่การสำรองข้อมูล
การสำรองข้อมูลและการทำซ้ำมีวัตถุประสงค์ที่แตกต่างกัน การสำรองข้อมูลแบบเย็นจะมีประโยชน์หากคุณทำโดยไม่ตั้งใจ DELETE
หรือ DROP TABLE
. เราทำการสำรองข้อมูลจากห้องเย็นและกู้คืนสถานะก่อนหน้าของตารางหรือฐานข้อมูลทั้งหมด แต่ในเวลาเดียวกันคำขอ DROP TABLE
ทำซ้ำเกือบจะทันทีในแบบจำลองทั้งหมดบนคลัสเตอร์การทำงาน ดังนั้นการจำลองแบบปกติจะไม่บันทึกที่นี่ การจำลองตัวเองทำให้ฐานข้อมูลพร้อมใช้งานเมื่อเซิร์ฟเวอร์แต่ละเครื่องถูกเช่าและกระจายโหลด
แม้กับเรพลิกาที่ล่าช้า บางครั้งเราก็ต้องการการสำรองข้อมูลแบบเย็นในที่ปลอดภัย หากเกิดความล้มเหลวของศูนย์ข้อมูล ความเสียหายที่ซ่อนเร้น หรือเหตุการณ์อื่นๆ ที่คุณไม่ได้สังเกตเห็นโดยทันที ที่นี่จากการจำลองแบบครั้งเดียวไม่มีเหตุผล
หมายเหตุ. บน
ที่มา: will.com