X
Change of support channel during COVID-19

ในการใช้งาน MySQL บนเครื่องเดี่ยวทั่วไปนั้น หลีกเลี่ยงไม่ได้ที่จะพบปัญหา database เสียหาย เช่นกรณีไฟดับ ฮาร์ดดิสก์เสีย หรือระบบหยุดทำงานแบบผิดปกติ ฯลฯ

วันนี้เราจะมาดูวิธีการ receovery MySQL ในกรณีข้างต้นกัน

กรณีของ MyISAM การ recovery ทำได้โดยใช้คำสั่งเดียว

# mysqlcheck -r --all-databases 
# [อาจต้องใส่ -u root -p ด้วย]

 

แต่แน่นอนว่า ไม่มีการรับประกัน integrity ของข้อมูลใดๆ ทั้งสิ้น เนื่องจาก MyISAM storage engine ไม่สามารถทำเรื่องดังกล่าวได้

MySQL สมัยใหม่มักใช้ InnoDB เป็น storage engine มาตรฐาน ซึ่งมีข้อดีเหนือกว่า MyISAM อยู่มากมาย แต่การ recovery จะใช้ขั้นตอนมากกว่าเดิมนิดหน่อย

Step ที่ถูกต้องของการทำ innodb-force-recovery

1. copy mysql directory ไปไว้ที่ปลอดภัยก่อน และ stop mysql หากยังรันอยู่

# /etc/init.d/mysql stop
# cp -pR /var/lib/mysql /var/lib/mysql-bak

 

2. recovery โดยการไล่ level ขึ้นไป จาก 1-6 โดยใส่ค่าเพิ่มเติมลงไปใน my.cnf ดังนี้

# cat /etc/my.cnf
[mysqld]
innodb_force_recovery = 1

 

3. start mysql และสังเกตผลจากข้อความที่ขึ้นมา หากยังมี error อยู่ ให้ stop mysql และเพิ่มค่า innodb_force_recovery ขึ้นทีละ 1 จนกว่าจะ start mysql ได้โดยไม่มี error

[ตัวอย่างกรณี error …]

# /etc/init.d/mysql start
...
InnoDB: Assertion failure in thread 47204348393792 in file trx0purge.c line 840
InnoDB: Failing assertion: purge_sys->purge_trx_no <= purge_sys->rseg->last_trx_no
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.

 

4. ณ​ level ที่ start mysql ได้สำเร็จโดยไม่พบ error ให้ทำการ dump db ที่มีปัญหาออกมา เพื่อ backup

# mysqldump database_name > database_name.sql #single database
# mysqldump –all-databases > all_db.sql #all databases

 

5. drop database ที่มีปัญหา ซึ่งเราได้ dump ออกมาเรียบร้อยนั้นทิ้ง

mysql> drop database XXXXX;

 
6. stop mysql แล้ว comment บรรทัด innodb_force_recovery ใน /etc/my.cnf ทิ้ง จากนั้น start mysql กลับขึ้นมาในโหมดปกติ

7. restore dump db ทั้งหมดกลับเข้าไป

# mysql database_name < database_name.sql

 
หมายเหตุ – ระหว่าง recovery จะไม่สามารถเขียนลง db ได้

ผู้สนใจสามารถอ่านเพิ่มเติมเกี่ยวกับความแตกต่างของ Level ต่างๆ ในการ recovery ได้จาก MySQL InnoDB Recovery Doc