Crash Recovery: إيه اللي بيحصل بعد ما الداتابيز تقع؟
الكهربا قطعت والداتابيز فيها ترانزاكشنز عملت COMMIT وصفحاتها لسه في الذاكرة، وترانزاكشنز ماخلصتش وصفحاتها اتكتبت على الديسك. أول ما ترجع، لازم ترجّع الأولى وتلغي التانية. الدرس ده بيشرح الـ Recovery: خوارزمية ARIES بمراحلها التلاتة، وإزاي InnoDB و PostgreSQL بيطبقوها، وإزاي نفس الـ Log ده بيعمل الـ Replication والـ Backups.
- تفهم مشكلة الـ Recovery: إيه اللي لازم يتعاد وإيه اللي لازم يتلغى
- تفهم سياسات Steal / No-Force وليه الداتابيز محتاجة Undo و Redo
- تشرح ARIES بمراحلها: Analysis و Redo و Undo
- تعرف الفرق بين Recovery في InnoDB و PostgreSQL
- تفهم إزاي الـ WAL نفسه بيعمل الـ Replication والـ PITR
1. المشكلة
لحظة الـ Crash، الداتا على الديسك ممكن تبقى في أي حالة من دول:
| الترانزاكشن | صفحاتها على الديسك؟ | المطلوب في الـ Recovery |
|---|---|---|
| عملت COMMIT | لأ، لسه في الذاكرة | Redo: نعيد تطبيق تعديلاتها |
| عملت COMMIT | آه | ولا حاجة |
| ماخلصتش | لأ | ولا حاجة (ضاعت مع الذاكرة) |
| ماخلصتش | آه، اتكتبت قبل ما تخلص | Undo: نلغي تعديلاتها |
ليه ممكن صفحات ترانزاكشن ماخلصتش تتكتب على الديسك؟ وليه صفحات ترانزاكشن خلصت ممكن تكون لسه في الذاكرة؟ ده قرار في تصميم الداتابيز.
2. Steal و No-Force
| السياسة | معناها | ليه | النتيجة |
|---|---|---|---|
| Steal | ينفع صفحة عليها تعديلات ترانزاكشن لسه ماخلصتش تتكتب على الديسك | الـ Buffer Pool محدود. ترانزاكشن بتعدّل 10 مليون صف مش هتفضل كلها في الذاكرة | محتاج Undo في الـ Recovery |
| No-Force | مش لازم صفحات الترانزاكشن تتكتب على الديسك وقت الـ COMMIT | كتابة الصفحات العشوائية مع كل COMMIT بطيئة جداً (درس الـ Durability) | محتاج Redo في الـ Recovery |
كل الداتابيز الحقيقية بتعمل Steal + No-Force، لأنها أسرع اختيار. وتمنه إن الـ Recovery لازم يعمل الاتنين: Redo للي خلص وماوصلش، و Undo للي ماخلصش ووصل.
3. ARIES
كل سجل في الـ Log ليه رقم متزايد اسمه LSN (Log Sequence Number). وكل صفحة على الديسك مكتوب فيها pageLSN: رقم آخر سجل اتطبق عليها. فلو سجل الـ Log رقمه أصغر من أو يساوي الـ pageLSN، يبقى التعديل ده موجود في الصفحة خلاص.
الـ Recovery بيمشي في 3 مراحل:
LSN 100: CHECKPOINT LSN 110: T1 UPDATE A LSN 120: T2 UPDATE B LSN 130: T1 COMMIT LSN 140: T2 UPDATE Cآخر حاجة قبل الـ Crash1⚡ Crashالذاكرة ضاعت- 3
1) ANALYSIS من الـ Checkpoint لآخر الـ LogT1 خلصت · T2 ماخلصتش - 4
2) REDO بيعيد LSN 110 و 120 و 140زي لحظة الـ Crash بالظبط - 5
3) UNDO بيلغي LSN 140 ثم 120 (بتوع T2)T2 اتلغت
دوس ▶ شغّل، أو امشي خطوة خطوة بالأسهم.
ليه ARIES بيعمل Redo لتعديلات T2 وبعدين يلغيها، بدل ما يعدّيها من الأول؟ لأن ده بيخلّي الـ Redo بسيط وغبي: “طبّق كل حاجة في الـ Log بالترتيب”. والـ Undo بعده بيشتغل على حالة معروفة ومتسقة بالظبط، وده بيبسّط حاجات زي الـ Locks على مستوى الصف والـ Recovery من Crash أثناء الـ Recovery.
بعد الـ Crash: Analysis تعرف مين خلص ومين لأ، و Redo يرجّع الداتابيز للحظة الـ Crash بالظبط، و Undo يلغي اللي ماخلصش. والـ Log هو المصدر الوحيد للحقيقة.
4. InnoDB ضد PostgreSQL
| InnoDB | PostgreSQL | |
|---|---|---|
| Redo | من الـ Redo Log، من آخر Checkpoint | من الـ WAL، من آخر Checkpoint |
| Undo | من الـ Undo Log: الترانزاكشنز اللي ماخلصتش بتترجع (ممكن في الخلفية بعد ما الداتابيز تفتح) | مفيش Undo: الترانزاكشنز اللي ماخلصتش مش متعلّمة Committed في pg_xact، فنسخها بتتعامل كـ Aborted ومحدش بيشوفها. والـ VACUUM بينضفها بعدين |
| الـ Torn Pages | Doublewrite Buffer | Full-page images في الـ WAL |
| مدة الـ Recovery | الـ Redo + Rollback الترانزاكشنز الكبيرة اللي ماخلصتش | الـ Redo بس |
ده نفس الفرق اللي شفناه في درس الـ Atomicity: PostgreSQL مش محتاج يرجّع حاجة، لأن الـ MVCC بتاعه بيخلّي “مش متعلّمة Committed” = “مش موجودة”.
وعشان كده تقليل الـ Recovery Time = Checkpoints أقرب (Redo أقل) + ترانزاكشنز أصغر (Undo أقل في InnoDB).
5. نفس الـ Log بيعمل حاجات تانية
الـ Log فيه كل تعديل حصل في الداتابيز بالترتيب. ودي حاجة قيمة جداً بره الـ Recovery:
- Physical Replication: ابعت الـ WAL لسيرفر تاني، وهو يعمل “Recovery مستمر” عليه (PostgreSQL Streaming Replication). الـ Standby في حالة Redo دايمة.
- Point-in-Time Recovery (PITR): خد Backup كامل كل يوم، واحتفظ بكل ملفات الـ WAL بعده. لو حد عمل
DELETEغلط الساعة 3:12، رجّع الـ Backup وطبّق الـ WAL لحد 3:11:59. في PostgreSQL بـrecovery_target_time، وفي MySQL بالـ Binary Log وmysqlbinlog. - Change Data Capture (CDC): أدوات زي Debezium بتقرا الـ WAL (Logical Decoding في PostgreSQL) أو الـ Binlog (MySQL) وتحوّل كل تعديل لـ Event في Kafka. وده هنستخدمه في درس الترانزاكشنز الموزعة.
الـ Log مش مجرد أداة للـ Recovery. هو التاريخ الكامل للداتابيز، ومنه بتتعمل الـ Replication والـ Backups لأي لحظة والـ CDC.
6. أسئلة الإنترفيو
فكّر في إجابتك الأول، وبعدين افتح السؤال.
01يعني إيه Steal و No-Force؟ وليه الداتابيز بتستخدمهم؟
Steal: صفحات عليها تعديلات ترانزاكشن لسه ماخلصتش ممكن تتكتب على الديسك، عشان الذاكرة محدودة. No-Force: صفحات الترانزاكشن مش لازم تتكتب وقت الـ COMMIT، عشان الكتابة العشوائية بطيئة. الاتنين أسرع اختيار، وتمنهم إن الـ Recovery محتاج Undo (بسبب Steal) و Redo (بسبب No-Force).
02اشرح مراحل ARIES.
Analysis: يقرا الـ Log من آخر Checkpoint ويعرف مين عمل COMMIT ومين ماخلصش وأنهي صفحات ممكن تكون Dirty. Redo: يعيد كل السجلات على الصفحات اللي pageLSN بتاعها أقدم، فيرجع للحظة الـ Crash بالظبط (Repeating History). Undo: يلغي تعديلات الترانزاكشنز اللي ماخلصتش من الأحدث للأقدم، ويسجل كل خطوة كـ CLR.
03ليه الـ Undo بيتسجل في الـ Log (CLRs)؟
عشان لو الداتابيز وقعت أثناء الـ Recovery نفسه، المرة الجاية تعرف إن الجزء ده اتلغى خلاص ومتلغيهوش تاني. الـ CLR بيشاور على السجل اللي بعده المفروض يتلغى، فالـ Undo بيكمل من حيث وقف.
04PostgreSQL محتاج Undo في الـ Recovery؟
لأ. الترانزاكشنز اللي ماخلصتش مش متعلّمة Committed في pg_xact، فنسخها الجديدة بتتعامل كأنها Aborted ومحدش بيشوفها، والـ VACUUM بينضفها بعدين. الـ Recovery في PostgreSQL هو Redo من الـ WAL بس.
05إزاي ترجّع الداتابيز للحظة قبل DELETE غلط حصل الساعة 3:12؟
Point-in-Time Recovery: ترجّع آخر Backup كامل قبل الوقت ده، وبعدين تطبّق الـ WAL (PostgreSQL، بـ recovery_target_time) أو الـ Binary Log (MySQL، بـ mysqlbinlog) لحد الثانية اللي قبل الـ DELETE. ده بيشتغل بس لو بتحتفظ بكل الـ Logs من آخر Backup.