MySQL 8: อัปเกรดจาก 5.7 และขึ้นรุ่น MariaDB อย่างปลอดภัย

วางแผนอัปเกรดเป็น MySQL 8 จากรุ่น 5.7 ตรวจด้วย util.checkForServerUpgrade ทดสอบบนเครื่องใหม่ มีแผนย้อนกลับ และหลักการเดียวกันสำหรับ MariaDB 10.x

โดย ทีมงาน THAI DATA CLOUD อัปเดต อ่าน 13 นาที

แชร์FacebookXLINELinkedIn
MySQL 8 — MySQL 8: อัปเกรดจาก 5.7 และขึ้นรุ่น MariaDB อย่างปลอดภัย
MySQL 8: อัปเกรดจาก 5.7 และขึ้นรุ่น MariaDB อย่างปลอดภัย

คำตอบสั้น ๆ: วางแผนอัปเกรดเป็น MySQL 8 จากรุ่น 5.7 ตรวจด้วย util.checkForServerUpgrade ทดสอบบนเครื่องใหม่ มีแผนย้อนกลับ และหลักการเดียวกันสำหรับ MariaDB 10.x

คู่มือนี้อธิบาย MySQL 8 ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย

การอัปเกรดเป็น MySQL 8 จากรุ่น 5.7 ไม่ใช่การอัปเดตแพ็กเกจธรรมดา เพราะมีการเปลี่ยนแปลงที่ทำให้แอปเดิมเชื่อมต่อไม่ได้หรือทำให้เซิร์ฟเวอร์ไม่ยอมเริ่มทำงาน เช่นปลั๊กอินยืนยันตัวตนเริ่มต้นตัวใหม่ ชุดอักขระเริ่มต้นที่เปลี่ยนเป็น utf8mb4 และตัวเลือกที่ถูกถอดออก ที่สำคัญที่สุดคือการอัปเกรดแบบ in-place ย้อนกลับไม่ได้ MySQL 5.7 หมดการสนับสนุนไปตั้งแต่ปี 2023 และ MySQL 8.0 หมดการสนับสนุนในเดือนเมษายน 2026 ปลายทางระยะยาวจึงควรเป็น MySQL 8.4 LTS

คู่มือนี้ใช้แนวทางที่ปลอดภัยที่สุดบนคลาวด์ คือสร้าง Cloud Server เครื่องใหม่ ย้ายข้อมูลไปทดสอบจนมั่นใจ แล้วจึงสลับแอป โดยเครื่องเดิมยังอยู่ครบเป็นแผนย้อนกลับ ท้ายคู่มือมีหลักการเดียวกันสำหรับผู้ที่ใช้ MariaDB 10.x

ลำดับการอัปเกรดเป็น MySQL 8 ตั้งแต่สำรองข้อมูล ตรวจด้วย Upgrade Checker ย้ายไปเครื่องใหม่ ทดสอบ สลับระบบ และเก็บเครื่องเดิมไว้ย้อนกลับ
เครื่องเดิมไม่ถูกแตะต้องจนกว่าเครื่องใหม่จะผ่านการทดสอบ จึงย้อนกลับได้เสมอ

สิ่งที่ต้องเตรียม

  • รุ่นปัจจุบันของเซิร์ฟเวอร์ ตรวจด้วย SELECT VERSION(); และไฟล์คอนฟิกที่ใช้อยู่
  • Cloud Server เครื่องใหม่ที่ใช้ Ubuntu 24.04 สเปกใกล้เคียงหรือสูงกว่าเครื่องเดิม และพื้นที่ดิสก์เผื่อไฟล์ dump
  • MySQL Shell (คำสั่ง mysqlsh) รุ่น 8.4 ขึ้นไป ติดตั้งจาก MySQL APT Repository ของ Oracle
  • ข้อมูลสำรองที่กู้คืนได้จริง ดู คู่มือ mysqldump
  • รายชื่อแอปทั้งหมดที่เชื่อมต่อฐานข้อมูล พร้อมรุ่นของภาษาและไดรเวอร์ เช่น PHP 7.4 ขึ้นไปจึงรองรับ caching_sha2_password

Oracle ไม่รองรับการข้ามซีรีส์ LTS เส้นทางที่ถูกต้องคือ 5.7 ไป 8.0 แล้วจึงไป 8.4 และระวังว่าการอัปเกรด Ubuntu 18.04 เป็น 20.04 ด้วย do-release-upgrade จะอัปเกรด MySQL 5.7 เป็น 8.0 ไปพร้อมกันโดยอัตโนมัติ ต้องทำตามคู่มือนี้ให้เสร็จก่อน

ขั้นตอนที่ 1: สำรวจระบบเดิมและสำรองข้อมูล

mysql -u root -p -e "SELECT VERSION(); SELECT user, host, plugin FROM mysql.user;"
mysqldump -u root -p --databases appdb shopdb --single-transaction --routines --triggers --events > /backup/apps-57.sql

dump ชุดนี้คือหลักประกันสุดท้าย เก็บไว้นอกเครื่องด้วย สังเกตคอลัมน์ plugin ของผู้ใช้ทุกคนซึ่งน่าจะเป็น mysql_native_password ทั้งหมด และจดค่า character_set_server, collation_server และ sql_mode ของเครื่องเดิมไว้ เพื่อใช้ตั้งบนเครื่องใหม่ให้พฤติกรรมเหมือนเดิม

ขั้นตอนที่ 2: ตรวจความเข้ากันได้กับ MySQL 8 ด้วย Upgrade Checker

MySQL Shell มีเครื่องมือ util.checkForServerUpgrade ที่ตรวจเซิร์ฟเวอร์ 5.7 ว่ามีอะไรจะพังเมื่อขึ้นรุ่นใหม่ ผู้ใช้ที่รันต้องมีสิทธิ์ PROCESS และ SELECT

mysqlsh -- util checkForServerUpgrade root@localhost:3306 --target-version=8.0.43 --config-path=/etc/mysql/mysql.conf.d/mysqld.cnf
หน้าจอ MySQL Shell ตรวจเซิร์ฟเวอร์ 5.7 ก่อนอัปเกรดเป็น MySQL 8 พบคอลัมน์ชื่อชนคำสงวนและตัวแปรที่ถูกถอดออก
Errors ต้องเป็น 0 ก่อนอัปเกรด ส่วน Warnings ควรแก้ให้ครบในขั้นตอนที่ 3

ท้ายรายงานมีสรุปสามบรรทัด Errors ต้องแก้ก่อนอัปเกรดทุกข้อ Warnings ควรแก้แต่ไม่บล็อกการอัปเกรด Notices เป็นข้อมูลประกอบ ใส่ --config-path ด้วยเสมอ เพราะเครื่องมือจะตรวจตัวเลือกในไฟล์คอนฟิกที่ถูกถอดออกในรุ่นใหม่ได้ด้วย

ขั้นตอนที่ 3: แก้สิ่งที่เปลี่ยนไปใน MySQL 8

ตารางเปรียบเทียบ MySQL 5.7 กับ MySQL 8.0 และ 8.4 ทั้งปลั๊กอินยืนยันตัวตน ชุดอักขระ Query Cache และการย้อนกลับ
สองแถวแรกคือสาเหตุที่แอปเชื่อมต่อไม่ได้หรือภาษาไทยเพี้ยนหลังอัปเกรดบ่อยที่สุด
  • คำสงวนใหม่ เช่น RANK, ROWS, GROUPS และ WINDOW ถ้ามีคอลัมน์ชื่อเหล่านี้ ให้ครอบชื่อด้วยเครื่องหมาย backtick ทุก Query เช่น SELECT `rank` FROM products; หรือเปลี่ยนชื่อคอลัมน์
  • ตัวเลือกที่ถูกถอดออก ลบ query_cache_type และ query_cache_size ออกจากคอนฟิก และเอา NO_AUTO_CREATE_USER ออกจาก sql_mode ถ้าจะไปต่อ 8.4 ต้องลบ default_authentication_plugin และเปลี่ยน expire_logs_days เป็น binlog_expire_logs_seconds ด้วย
  • คำสั่งที่เลิกใช้ สคริปต์ที่ใช้ GRANT ... IDENTIFIED BY สร้างผู้ใช้จะล้มเหลว ต้องเปลี่ยนเป็น CREATE USER ก่อนแล้วค่อย GRANT
  • ชุดอักขระ ตารางใหม่จะใช้ utf8mb4_0900_ai_ci ถ้าตารางเดิมใช้ collation อื่น ให้ตั้ง collation_server บนเครื่องใหม่ให้ตรงกับของเดิม หรือแปลงทั้งระบบตาม คู่มือแปลงเป็น utf8mb4

รัน Upgrade Checker ซ้ำจน Errors เป็น 0 ก่อนไปขั้นตอนถัดไป

ขั้นตอนที่ 4: เตรียมเครื่องใหม่และย้ายข้อมูลด้วย MySQL Shell

บนเครื่องใหม่ ติดตั้ง MySQL 8.0 แล้วตรวจรุ่นที่ได้ด้วย apt policy mysql-server ใส่ค่า collation_server และ sql_mode ที่จดไว้ลงคอนฟิก จากนั้น dump จากเครื่องเดิมด้วย MySQL Shell ซึ่งรวมบัญชีผู้ใช้มาให้และทำงานหลายเธรด

# บนเครื่องเดิม
mysqlsh root@localhost:3306 --js -e 'util.dumpInstance("/backup/dump-57", {threads: 4})'

# คัดลอกไปเครื่องใหม่ แล้วโหลดบนเครื่องใหม่
mysql -u root -p -e "SET PERSIST local_infile = ON;"
mysqlsh root@localhost:3306 --js -e 'util.loadDump("/backup/dump-57", {threads: 4, loadUsers: true, excludeUsers: ["root"]})'
mysql -u root -p -e "SET PERSIST local_infile = OFF;"

ถ้าติดตั้ง mysqlsh บนเครื่องเดิมไม่ได้เพราะระบบปฏิบัติการเก่าเกินไป ให้รันคำสั่ง dump จากเครื่องใหม่โดยเชื่อมต่อไปที่ IP ภายในของเครื่องเดิมแทน ไฟล์ dump จะถูกเขียนลงเครื่องที่รันคำสั่ง ส่วน loadDump ต้องเปิด local_infile บนเครื่องปลายทางชั่วคราว ปิดกลับทันทีเมื่อเสร็จ ระหว่างโหลด เซิร์ฟเวอร์ใหม่จะแปลงโครงสร้างเป็นแบบของรุ่นใหม่ให้เอง

ขั้นตอนที่ 5: ทดสอบแอปกับเครื่องใหม่

ชี้แอปชุดทดสอบไปที่ MySQL 8 บนเครื่องใหม่ แล้วไล่ทดสอบงานหลักทุกหน้า ดู log ของแอปหาข้อความ authentication method unknown to the client, Illegal mix of collations และ is not in GROUP BY clause ซึ่งเป็นปัญหาสามอันดับแรกหลังอัปเกรด เทียบจำนวนแถวของตารางสำคัญระหว่างสองเครื่องด้วย SELECT COUNT(*) และวัดเวลาของ Query ที่ใช้บ่อย เพราะ Optimizer ของรุ่นใหม่อาจเลือกแผนต่างจากเดิม

ขั้นตอนที่ 6: สลับระบบจริงและเตรียมแผนย้อนกลับ

ฐานข้อมูลขนาดเล็กใช้วิธีปิดการเขียนแล้ว dump และโหลดรอบสุดท้ายในช่วงปิดปรับปรุง ฐานข้อมูลใหญ่ที่หยุดนานไม่ได้ ให้ตั้งเครื่องใหม่เป็น Replica ของเครื่องเดิมตาม คู่มือ Master-Replica แล้วสลับเมื่อข้อมูลตามทัน

# บนเครื่องเดิม ก่อน dump รอบสุดท้าย
mysql -u root -p -e "SET GLOBAL super_read_only = ON;"

หลังสลับ ให้เก็บเครื่องเดิมไว้แบบอ่านอย่างเดียวอย่างน้อยหนึ่งถึงสองสัปดาห์ ถ้าต้องย้อนกลับ แค่ชี้แอปกลับไปเครื่องเดิมและปิด super_read_only แต่ข้อมูลที่เขียนลงเครื่องใหม่หลังสลับจะไม่ตามกลับไปด้วย ต้องตัดสินใจย้อนกลับให้เร็ว เมื่อระบบบน MySQL 8.0 นิ่งแล้ว การขยับต่อไป 8.4 LTS ทำแบบ in-place ได้ โดยเพิ่ม repository ของ 8.4 แล้วอัปเกรดแพ็กเกจ เซิร์ฟเวอร์จะอัปเกรดตัวเองตอนเริ่มทำงาน แต่ต้องรัน Upgrade Checker เป้าหมาย 8.4 และทำ snapshot ก่อนเสมอ

รายการตรวจความพร้อมก่อนสลับแอปไปใช้ MySQL 8 บนเครื่องใหม่ พร้อมแผนย้อนกลับไปเครื่องเดิม
ถ้ายังมีข้อสีแดง อย่าเพิ่งสลับ ข้อสีเหลืองต้องมีคนรับผิดชอบชัดเจน

ขั้นตอนที่ 7: หลักการเดียวกันสำหรับ MariaDB 10.x

MariaDB ไม่ใช่ MySQL 8 และไม่มี caching_sha2_password การย้ายระหว่างสองผลิตภัณฑ์จึงเป็นการย้ายข้ามระบบ ไม่ใช่การอัปเกรด ถ้าคุณใช้ MariaDB อยู่แล้ว ให้อัปเกรดไปรุ่น LTS ที่ยังได้รับการสนับสนุน และอ่านหน้า Upgrading from MariaDB X to Y ของทุกคู่รุ่นที่ข้าม วิธีที่ปลอดภัยยังคงเป็นเครื่องใหม่กับ mariadb-dump แต่ถ้าจำเป็นต้องอัปเกรดบนเครื่องเดิม ให้ทำ snapshot ก่อนแล้วใช้ repository ทางการ

curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-11.4"
sudo apt update
sudo apt install mariadb-server
sudo mariadb-upgrade

mariadb-upgrade ปรับตารางระบบให้ตรงกับรุ่นใหม่ รันซ้ำได้อย่างปลอดภัย ถ้าทำไปแล้วจะแจ้งว่าอัปเกรดแล้ว

ปัญหาที่พบบ่อยเกี่ยวกับการอัปเกรด MySQL 8

แอปขึ้น authentication method unknown to the client หลังย้าย ต้องทำอย่างไร?

ไดรเวอร์ของแอปเก่าเกินกว่าจะรองรับ caching_sha2_password ทางแก้ที่ถูกคืออัปเดตไดรเวอร์หรือรุ่นภาษา ระหว่างรอ ให้ตั้งเฉพาะผู้ใช้นั้นเป็นปลั๊กอินเดิมด้วย ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'รหัสผ่าน'; ซึ่งใช้ได้บน 8.0 ส่วน 8.4 ต้องเปิด mysql_native_password=ON ในคอนฟิกก่อน และปลั๊กอินนี้ถูกถอดออกใน 9.0 จึงเป็นทางออกชั่วคราวเท่านั้น

MySQL 8 ไม่ยอมเริ่มทำงานและ log ขึ้น unknown variable เกิดจากอะไร?

ไฟล์คอนฟิกยังมีตัวเลือกที่ถูกถอดออก เช่น query_cache_size หรือ sql_mode ที่มี NO_AUTO_CREATE_USER ดูชื่อตัวเลือกใน /var/log/mysql/error.log ลบออกแล้วเริ่มบริการใหม่ ป้องกันได้ตั้งแต่ต้นด้วยการรัน Upgrade Checker พร้อม --config-path

Query เดิมขึ้น Illegal mix of collations หลังย้าย แก้อย่างไร?

ตารางเก่าใช้ collation เดิม เช่น utf8mb4_general_ci แต่ตารางหรือการเชื่อมต่อใหม่ใช้ utf8mb4_0900_ai_ci เมื่อเทียบคอลัมน์ข้ามกันจึงผิดพลาด ตั้ง collation_server บนเครื่องใหม่ให้ตรงกับของเดิม หรือแปลงทุกตารางให้ใช้ collation เดียวกันในช่วงปิดปรับปรุง

อัปเกรดแบบ in-place ไปแล้ว ย้อนกลับไป 5.7 ได้ไหม?

ไม่ได้ รุ่น 8.0 เปลี่ยนรูปแบบ data dictionary ของไฟล์ข้อมูลและไม่รองรับการ downgrade แบบ in-place ทางเดียวคือกู้จากข้อมูลสำรองหรือ snapshot ที่ทำไว้ก่อนอัปเกรด นี่คือเหตุผลที่คู่มือนี้แนะนำให้ย้ายไปเครื่องใหม่และเก็บเครื่องเดิมไว้

ถ้าต้องการให้ช่วยวางแผนหรือทำการอัปเกรดฐานข้อมูลที่ใช้งานจริง ติดต่อทีมงาน THAI DATA CLOUD หรือดูเครื่องปลายทางที่ Cloud Server อ่านรายละเอียดจาก เส้นทางการอัปเกรด MySQL, Upgrade Checker Utility และ การอัปเกรด MariaDB

สรุปขั้นตอน MySQL 8

ทบทวน MySQL 8 ทั้งหมดตามลำดับ ก่อนนำไปใช้กับระบบจริง

  1. สำรวจระบบเดิมและสำรองข้อมูล
  2. ตรวจความเข้ากันได้กับ MySQL 8 ด้วย Upgrade Checker
  3. แก้สิ่งที่เปลี่ยนไปใน MySQL 8
  4. เตรียมเครื่องใหม่และย้ายข้อมูลด้วย MySQL Shell
  5. ทดสอบแอปกับเครื่องใหม่
  6. สลับระบบจริงและเตรียมแผนย้อนกลับ
  7. หลักการเดียวกันสำหรับ MariaDB 10.x

เมื่อทำครบทุกข้อแล้ว MySQL 8 จะพร้อมใช้งาน หากผลลัพธ์ไม่เป็นไปตามที่คาด ให้ย้อนกลับไปดูหัวข้อปัญหาที่พบบ่อยด้านบน ซึ่งรวบรวมกรณีที่พบจริงจากการใช้งาน MySQL 8 ไว้แล้ว

อ่านเพิ่มเติมเกี่ยวกับ MySQL 8

แชร์FacebookXLINELinkedIn

มีคำถามเรื่องบริการ? ติดต่อทีมงาน