XAMPP MySQL ดับเองเพราะ Aria log เสีย: ซ่อมโดยไม่ลบข้อมูล
ข้อความ delete all aria_log files ใน log ฟังเหมือนให้ลบทิ้งดื้อ ๆ แล้วหวังว่าทุกอย่างจะกลับมา ซึ่งเสี่ยงถ้ายังไม่ได้สำรอง ที่ถูกคือสำรองทั้งก้อน ย้ายไฟล์ที่เสียออก แล้วซ่อมตารางระบบที่ได้รับผลกระทบจริง
สรุปใน 1 นาที
- อาการ/ปัญหา
- XAMPP MySQL สตาร์ตไม่ขึ้นหลังไฟดับ และ panel ขึ้นแดง
- ใครควรอ่าน
- คนใช้ XAMPP ที่ MariaDB ดับเองและกลัวข้อมูลหาย
- ทางแก้แบบสั้น
- สาเหตุคือ Aria log ของตารางระบบเสีย ไม่ใช่ข้อมูล InnoDB ให้สำรองทั้งก้อนก่อน ย้ายไฟล์ที่เสียออก แล้วซ่อมด้วย aria_chk โดยไม่ลบฐานข้อมูล
พอดีเครื่อง Windows ที่ผมใช้ XAMPP เล่นเว็บในเครื่อง ไฟดับตอน MySQL ยังรันอยู่ พอเปิดเครื่องใหม่แล้วกด Start MySQL ใน control panel ขึ้นแดงว่า "MySQL shutdown unexpectedly" กดซ้ำกี่ครั้งก็เหมือนเดิม ข้อมูลในฐานข้อมูลของโปรเจกต์ในเครื่องผมสำคัญกว่าตัว MySQL เอง เลยตั้งใจว่าจะไม่ลบอะไรทิ้งจนกว่าจะรู้ว่าอะไรเสีย บทความนี้เรียงตามที่ทำจริง ตั้งแต่อ่าน log จนซ่อมเสร็จ ทั้งกระบวนการใช้เวลาไม่กี่นาที เส้นทางของคำสั่งเป็นของ XAMPP ที่ลงตามค่าปกติ ถ้าคุณลงไว้ที่อื่นต้องปรับเอง

อาการ: panel แดง แต่ log ใน panel บอกไม่พอ
log ที่เปิดจากปุ่ม Logs ใน control panel สั้นมาก เห็นแค่ว่า shutdown unexpectedly ไม่บอกว่าเพราะอะไร ผมเลยไม่เสียเวลากับมัน ไปเปิดไฟล์ log ของ MariaDB ตรง ๆ แทน
อ่าน mysql_error.log ตัวจริง
ไฟล์ที่ต้องเปิดคือ mysql_error.log ในโฟลเดอร์ data ของ MySQL ซึ่งยาวกว่าและมีรายละเอียด
# ดูท้ายไฟล์ log ที่แท้จริง (ไม่ใช่ log ใน panel)
Get-Content C:\xampp\mysql\data\mysql_error.log -Tail 40
# กรองเฉพาะสองบรรทัดที่บอกสาเหตุ
Select-String -Path C:\xampp\mysql\data\mysql_error.log -Pattern 'Aria recovery failed|Could not open mysql.plugin'
ผมเจอสองบรรทัดสำคัญ บรรทัดแรกบอกว่า Aria recovery failed และให้ลบไฟล์ aria_log.######## ทั้งหมด บรรทัดที่สองคือ Could not open mysql.plugin table ความหมายคือตารางระบบในฐาน mysql เปิดไม่ได้ ที่ต้องระวังคือบรรทัดแรก มันฟังดูเหมือนให้ลบดื้อ ๆ ซึ่งเสี่ยงถ้ายังไม่สำรอง
แยก Aria ออกจาก InnoDB ก่อนทำอะไร
ในรุ่นที่ผมใช้ ตารางระบบของ MariaDB (ฐาน mysql) เป็นเอนจิน Aria ไม่ใช่ InnoDB ส่วน log ของ Aria เสียตอนไฟดับ ข้อมูลของผู้ใช้ที่เป็น InnoDB ไม่ได้เสีย และผมตรวจจริงหลังซ่อมแล้วว่า mysqlcheck --check ไม่มี error สักตัว สองเอนจินนี้ใช้ log คนละชุด ถ้า log บอกเรื่อง InnoDB redo log ให้ไปอ่าน บทความ InnoDB redo recovery เพราะอาการและวิธีแก้ต่างกันเลย
วิธีดูด้วยตาว่าไฟล์ไหนเป็นของเอนจินไหน ดูจากนามสกุลในโฟลเดอร์ data ได้เลย ตารางของ Aria มีไฟล์ .MAI (ดัชนี) กับ .MAD (ข้อมูล) ส่วน InnoDB เก็บข้อมูลไว้ใน ibdata1 และไฟล์ .ibd ต่อตาราง ฐาน mysql ที่เป็นปัญหาเลยเต็มไปด้วย .MAI และ .MAD
# ตารางระบบของ Aria: ดูจากนามสกุล .MAI / .MAD
Get-ChildItem C:\xampp\mysql\data\mysql -Filter *.MAI | Select-Object -First 8 Name, Length
# ไฟล์ log ของ Aria ที่เป็นตัวปัญหา อยู่ที่ราก data
Get-ChildItem C:\xampp\mysql\data -Filter 'aria_log*' | Select-Object Name, Length, LastWriteTime
พอซ่อมจนขึ้นแล้ว ถ้าอยากยืนยันอีกชั้นว่าตารางระบบเป็น Aria และตารางของโปรเจกต์เป็น InnoDB ถามจาก information_schema ได้ตรง ๆ
-- ตารางระบบ: คาดว่าจะเห็นเอนจิน Aria
SELECT table_name, engine
FROM information_schema.tables
WHERE table_schema = 'mysql'
ORDER BY engine, table_name
LIMIT 10;
-- นับตารางของฐานผู้ใช้ตามเอนจิน (ค่านี้ต้องเป็นของ InnoDB เป็นหลัก)
SELECT engine, COUNT(*) AS tables
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys')
GROUP BY engine;
ข้อควรรู้คือ คำสั่ง SQL สองชุดนี้ใช้ได้หลัง MariaDB ขึ้นแล้วเท่านั้น ระหว่างที่มันยังสตาร์ตไม่ขึ้น ต้องพึ่งการดูนามสกุลไฟล์กับอ่าน log อย่างเดียว ซึ่งก็พอแล้วสำหรับตัดสินใจว่าเป็นเรื่อง Aria หรือไม่ ผมใช้เกณฑ์ง่าย ๆ ว่า ถ้าชื่อที่ log พูดถึงเป็น aria_log หรือ mysql.* เป็นเรื่องของ Aria แต่ถ้า log พูดถึง ib_logfile หรือ InnoDB redo ต้องไปอีกทางหนึ่งที่เล่าไว้ในบทความ redo recovery ข้างบน
ข้อความ delete all aria_log files พูดถึงไฟล์ aria_log เท่านั้น ไฟล์ ibdata1 และ ib_logfile* เป็นของ InnoDB ไม่เกี่ยวกับเคสนี้เลย ถ้าลบสองตัวนี้จะทำลายข้อมูล InnoDB ของฐานผู้ใช้ทั้งหมด เป็นความผิดพลาดที่ย้อนไม่ได้ถ้าไม่มีสำรอง
สำรอง data ทั้งก้อนก่อนแตะ
ก่อนย้ายหรือแก้อะไร ผมเช็กว่าไม่มี mysqld.exe ค้างอยู่ใน Task Manager แล้ว copy โฟลเดอร์ data ทั้งก้อนไปเป็น data_backup_<timestamp> ในเคสนี้ขนาด 762 MB
# 0) ต้องไม่มี mysqld ค้างอยู่ ถ้ามีผลลัพธ์ ให้หยุดก่อน
Get-Process mysqld -ErrorAction SilentlyContinue
# 1) สำรองทั้งโฟลเดอร์ data (ห้ามทำตอน mysqld ยังรัน)
$ts = Get-Date -Format 'yyyyMMdd_HHmm'
Copy-Item C:\xampp\mysql\data "C:\xampp\mysql\data_backup_$ts" -Recurse
(Get-ChildItem "C:\xampp\mysql\data_backup_$ts" -Recurse | Measure-Object Length -Sum).Sum / 1MB

กฎข้อแรกคือห้าม copy โฟลเดอร์ data ตอนที่ mysqld ยังรันอยู่ ไฟล์จะอยู่ในสถานะที่ไม่สอดคล้องกัน และสำรองที่ได้อาจใช้ไม่ได้
ซ่อมด้วย aria_chk 5 ขั้น
เรียงตามที่ผมทำจริงครับ
- ย้าย
aria_log.00000001และaria_log_controlออกจากโฟลเดอร์ data ไปไว้ในโฟลเดอร์สำรอง ย้าย ไม่ใช่ลบ - เข้าโฟลเดอร์ data แล้วรัน
aria_chk -o -fกับไฟล์.MAIของฐาน mysql - สตาร์ต MariaDB แบบมือด้วย
--standaloneให้รันเบื้องหลัง รอบรรทัด ready for connections ใน log - รัน
mysqlcheck --repairกับฐาน mysql แล้ว--checkทั้งหมด - สั่ง
mysqladmin shutdownเพื่อให้ XAMPP panel เป็นคนสตาร์ตตามปกติ
คำสั่งจริงของขั้นย้าย ซ่อม และสตาร์ตมีดังนี้ ผมรันจากโฟลเดอร์ C:\xampp\mysql
cd C:\xampp\mysql
# ย้าย log ที่เสียออก (ย้ายไปไว้ในโฟลเดอร์สำรอง ใช้ -Force เพราะมีสำเนาอยู่แล้ว)
Move-Item data\aria_log.00000001 "data_backup_$ts\" -Force
Move-Item data\aria_log_control "data_backup_$ts\" -Force
# ซ่อมตารางระบบแบบ safe-recover (ต้อง -o ไม่ใช่ -r)
cd data
..\bin\aria_chk.exe -o -f mysql\*.MAI
cd ..
# สตาร์ตแบบมือ ให้รันเบื้องหลัง แล้วรอ ready for connections
Start-Process .\bin\mysqld.exe -ArgumentList '--defaults-file=bin\my.ini','--standalone' -WindowStyle Hidden
do { Start-Sleep 2 } until (Select-String -Path data\mysql_error.log -Pattern 'ready for connections' -Quiet)
ทำไมต้อง -o ไม่ใช่ -r ตามที่เห็นในเคสนี้ -r ล้มกับตาราง columns_priv และ help_topic ผมเลยเปลี่ยนมาใช้ -o (safe-recover) ซึ่งผ่าน ส่วนสาเหตุเชิงลึกว่าเกี่ยวกับขนาด sort buffer ของ Aria หรือไม่ ผมยังไม่ได้ตรวจเอกสารของ MariaDB เลยไม่ขอยืนยันเป็นกฎทั่วไป
ตรวจให้ครบ แล้วคืนให้ panel
พอ MariaDB ขึ้นแล้ว ผมไม่ได้ปล่อยไว้ทันที ซ่อมตารางระบบอีกรอบด้วย mysqlcheck แล้วตรวจทุกฐานข้อมูลให้ครบ
# ถ้าตั้งรหัส root ไว้ ให้เติม -p ทุกบรรทัด
.\bin\mysqlcheck.exe -u root --repair --databases mysql
.\bin\mysqlcheck.exe -u root --all-databases --check
# ปิด mysqld ที่เราเปิดเอง เพื่อให้ XAMPP panel เป็นคนสตาร์ตตามปกติ
.\bin\mysqladmin.exe -u root shutdown
ผลคือไม่มี error สักบรรทัด ทั้งฐาน mysql และฐานของผู้ใช้ ขั้นสุดท้ายที่สั่ง shutdown สำคัญ เพราะถ้าปล่อย mysqld รันอยู่นอก panel ตัว panel จะสับสนว่าใครเปิดมัน แล้วกด Start ซ้ำอาจชนกันได้ ผมเลยปิดให้ แล้วกด Start จาก panel ตามปกติ โฟลเดอร์ data_backup_<timestamp> ลบทิ้งได้หลังใช้งานปกติสักระยะ
ลบ aria_log แล้วหวังให้ดีเอง
เร็วและอาจได้ผลเหมือนกัน แต่ถ้าไม่มีสำรอง และตารางระบบมีปัญหาลึกกว่านั้น ไม่มีทางกลับเลย
สำรอง ย้าย ซ่อม แล้วตรวจ
ช้ากว่าไม่กี่นาที แต่ทุกขั้นย้อนกลับได้ และจบด้วยหลักฐานว่า mysqlcheck ไม่มี error ไม่ใช่แค่ panel เขียว
กันไม่ให้เกิดซ้ำ
สาเหตุของเรื่องนี้คือไฟดับหรือปิดเครื่องไม่เรียบร้อยตอน MySQL ยังรัน วิธีกันที่ตรงที่สุดคือกด Stop MySQL ใน XAMPP panel ก่อนปิดเครื่องหรือถอดปลั๊กทุกครั้ง ถ้าเครื่องไฟดับบ่อยควรพิจารณา UPS เป็นความรู้ทั่วไปที่เสริมได้ คือสำรองโฟลเดอร์ data ทั้งก้อนเป็นระยะ ตอนที่ MySQL หยุดอยู่ ซึ่งไม่ใช่ส่วนของเคสนี้ แต่ทำให้ครั้งหน้ามีทางกลับที่ใหม่กว่านี้
สรุป
อาการ MySQL ดับเองใน XAMPP หลังไฟดับ ไม่ได้แปลว่าข้อมูลเสีย ให้เปิด mysql_error.log ตัวจริงก่อน ถ้าเห็น Aria recovery failed กับ Could not open mysql.plugin table แปลว่าเป็นตารางระบบ ไม่ใช่ InnoDB สำรองก่อน ย้ายไฟล์ aria_log ออก ซ่อมด้วย aria_chk -o -f ตรวจด้วย mysqlcheck แล้วคืนให้ panel เป็นคนสตาร์ต ส่วนจะข้ามสำรองเพราะเครื่องนี้ไม่มีอะไรสำคัญ ก็ตามแต่ความเสี่ยงที่รับได้ แต่ผมไม่ข้ามครับ
ผมยังไม่ได้ลองว่า XAMPP รุ่นอื่นใช้ขั้นตอนเดียวกันได้ไหม และไม่ได้จับเวลาแต่ละคำสั่ง ถ้าคุณเจอเคสที่ต่างจากนี้ เดี๋ยวกลับมาแก้เพิ่มให้ภายหลังครับ
อยากให้เราทำให้ไหม?
ให้เราช่วยติดตั้ง ตั้งค่า ย้ายระบบ หรือแก้ปัญหาเซิร์ฟเวอร์ เพื่อให้คุณมีเวลาไปทำงานที่สำคัญกว่า
เคยเจองานแบบนี้ไหม? ติดตรงไหน?
มาแลกวิธีกันต่อในบอร์ด LinuxThai



ความคิดเห็น 0
ยังไม่มีความคิดเห็น — เป็นคนแรกเลย