فسادُ الجدول عرَضٌ في الغالب الأعمّ: انقطاعُ تيّار، أو قرصٌ امتلأ، أو عتادٌ يتلف. أصلح الجدول ثمّ اعرف أيَّ ذلك كان — وإلّا تكرّر الأسبوع القادم.
MyISAM
mysqlcheck --check --auto-repair --databases shop
# or, for one table
mysql -e "REPAIR TABLE shop.sessions"
ليس في MyISAM استعادةٌ بعد الانهيار، فإطفاءٌ غير نظيف يترك الجداول مُعلَّمةً منهارة. وREPAIR يصلحها في ثوانٍ عادةً، وقد يُسقط الصفوف التالفة.
وInnoDB مختلف
الأمر REPAIR TABLE لا يعمل على InnoDB، والفسادُ فيه خطير — فالمحرّك يستعيد نفسه عند الإقلاع عادةً. وإن أبلغ InnoDB عن فسادٍ فالاستعادةُ من نسخةٍ احتياطية هي الطريق الآمن لا محاولةُ إصلاح.
mysql -e "CHECK TABLE shop.orders"
sudo tail -100 /var/log/mysql/error.log
وإن رفض الخادم الإقلاع بسببه
# my.cnf - TEMPORARY, to get the data out
innodb_force_recovery = 1
- ابدأ من 1 ولا ترفع إلّا إن لم يُقلع — فما فوق المستوى 4 قد يُتلف البيانات.
- انسخ كلّ شيءٍ حالَ إقلاعه —
mysqldump --all-databases > rescue.sql - احذف الإعداد، وأعد بناء دليل البيانات — ثمّ استورد النسخة.
وفوق innodb_force_recovery = 3 يعمل المحرّك في وضعٍ منقوص قد تزيد فيه الكتابةُ الأمرَ سوءًا. خذ النسخة واخرج؛ ولا تُشغّل موقعًا عليه.
ثمّ اعثر على السبب
sudo dmesg -T | grep -iE 'i/o error|ata|nvme'
df -h
sudo smartctl -H /dev/sda
وانتقل بعيدًا عن MyISAM
SELECT table_name, engine FROM information_schema.tables
WHERE table_schema = 'shop' AND engine <> 'InnoDB';
ALTER TABLE shop.sessions ENGINE=InnoDB;
في InnoDB استعادةٌ بعد الانهيار، وقفلٌ على مستوى الصفّ، ومعاملاتٌ حقيقيّة. ولا وجه لأن يكون جدولٌ جديد بـ MyISAM، والتحويلُ يزيل هذا الصنف من المشكلات كلَّه.
