การติดตั้ง MySQL ใช้แค่คำสั่งเดียว งานส่วนใหญ่มาทีหลัง: ผู้ใช้สำหรับแอป วิธีเข้าถึงฐานข้อมูลจากคอมพิวเตอร์ของคุณโดยไม่ต้องเปิดพอร์ต 3306 สู่อินเทอร์เน็ต การตั้งค่าหน่วยความจำสำหรับเซิร์ฟเวอร์ขนาดเล็ก และการสำรองข้อมูลที่ทำงานเองโดยไม่ต้องมีคุณ คู่มือนี้ครอบคลุมทั้งสี่เรื่องบน Ubuntu 24.04 ทุกขั้นตอนรันบนอิมเมจ Ubuntu 24.04 ของเรา และตัวเลขด้านล่างมาจากเซิร์ฟเวอร์นั้น
รันคำสั่งด้วยผู้ใช้ที่มี sudo คู่มือตั้งค่า Ubuntu จะสร้างให้
1. ติดตั้ง
sudo apt update
sudo apt install -y mysql-server
mysql --version
บนเซิร์ฟเวอร์ของเรา การติดตั้งใช้เวลา 51 วินาที และได้ MySQL 8.0.46 มันเริ่มทำงานทันที เริ่มใหม่ทุกครั้งที่บูต และรอรับเฉพาะบนตัวเซิร์ฟเวอร์เอง คือ 127.0.0.1:3306 สำหรับการเชื่อมต่อปกติ และ 127.0.0.1:33060 สำหรับโปรโตคอล X รุ่นใหม่ของ MySQL ตอนนี้ยังไม่มีอะไรเข้าถึงได้จากภายนอก
2. สร้างฐานข้อมูลและผู้ใช้
บน Ubuntu บัญชี root ของ MySQL ใช้การยืนยันตัวตนผ่าน socket ดังนั้น sudo mysql จึงพาคุณเข้าโดยไม่ต้องใช้รหัสผ่าน สร้างฐานข้อมูลและผู้ใช้สำหรับแอปของคุณ:
sudo mysql
CREATE DATABASE app CHARACTER SET utf8mb4;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'localhost';
EXIT;
ทดสอบแบบเดียวกับที่แอปจะเชื่อมต่อ:
mysql -u app -p app -e "SELECT CURRENT_USER();"
ควรแสดง app@localhost ถ้ารหัสผ่านผิดจะได้ ERROR 1045 (28000): Access denied for user 'app'@'localhost' ผู้ใช้นี้ทำได้ทุกอย่างภายใน app และทำอะไรนอกนั้นไม่ได้เลย
3. เชื่อมต่อจากคอมพิวเตอร์ของคุณ: SSH tunnel
ถ้าจะใช้ไคลเอนต์บนเดสก์ท็อป เช่น DBeaver, MySQL Workbench หรือบรรทัดคำสั่ง mysql บนเครื่องของคุณ อย่าเปิดพอร์ตใด ๆ ให้ส่งต่อพอร์ตผ่าน SSH:
ssh -L 3307:127.0.0.1:3306 deploy@YOUR.SERVER.IP
ในแพ็กเกจ NAT ให้เพิ่ม -p และพอร์ต SSH ส่วนตัวจากแดชบอร์ด ระหว่างที่หน้าต่างนั้นเปิดอยู่ ให้ชี้ไคลเอนต์ไปที่โฮสต์ 127.0.0.1 พอร์ต 3307 ผู้ใช้ app ฝั่งเครื่องเราใช้ 3307 เพื่อไม่ให้ชนกับ MySQL ที่อาจรันอยู่บนคอมพิวเตอร์ของคุณ ในการทดสอบของเรา เซิร์ฟเวอร์ตอบผ่าน tunnel ทันที ขณะที่การเชื่อมต่อตรงไปยังที่อยู่ของมันที่พอร์ต 3306 ถูกปฏิเสธ
4. เปิดให้เซิร์ฟเวอร์อื่นหนึ่งเครื่องเข้าถึงโดยตรง
บางครั้งแอปรันอยู่บนเซิร์ฟเวอร์ที่สองและต้องเชื่อมต่อโดยตรง กรณีนี้ฐานข้อมูลต้องอยู่บนแพ็กเกจที่มี IPv4 ของตัวเอง เพราะแพ็กเกจ NAT ส่งต่อแค่พอร์ต SSH ของคุณ มีการเปลี่ยนแปลงสามอย่าง ทั้งหมดจำกัดไว้ที่ที่อยู่ของเซิร์ฟเวอร์แอป (ในที่นี้คือ 203.0.113.20):
sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp
CREATE USER 'app'@'203.0.113.20' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'203.0.113.20';
ถ้ายังไม่ได้เปิด ufw ให้อนุญาต SSH ก่อน (sudo ufw allow OpenSSH) แล้วจึงรัน sudo ufw enable รายละเอียดอยู่ในคู่มือ ufw
เราตรวจกุญแจทั้งสองดอกแยกกัน เมื่อมีกฎไฟร์วอลล์แต่ไม่มีผู้ใช้ MySQL ที่ตรงกัน เซิร์ฟเวอร์ปฏิเสธด้วย error 1130: Host '…' is not allowed to connect to this MySQL server เมื่อเพิ่มผู้ใช้แล้ว การเชื่อมต่อผ่านได้ เมื่อเอากฎไฟร์วอลล์ออก การเชื่อมต่อก็แค่หมดเวลา ที่อยู่อื่นทุกแห่งบนอินเทอร์เน็ตจะเจอการหมดเวลาแบบเดียวกัน
5. ใช้ RAM น้อยลง
ตอนว่างและยังไม่มีข้อมูลของตัวเอง MySQL 8.0 ใช้ 383 MB บนเซิร์ฟเวอร์ของเรา ส่วนใหญ่มาจาก Performance Schema ซึ่งเป็นฟีเจอร์วินิจฉัยที่จองหน่วยความจำไว้ล่วงหน้า บน VPS ขนาดเล็กให้ปิดมัน แล้วกำหนดขนาดแคชหลักเอง:
sudo tee /etc/mysql/mysql.conf.d/zz-small-vps.cnf >/dev/null <<'EOF'
[mysqld]
performance_schema = OFF
innodb_buffer_pool_size = 256M
max_connections = 50
EOF
sudo systemctl restart mysql
ps -o rss= -C mysqld
หลังรีสตาร์ต มันใช้ 165 MB buffer pool ใช้แคชข้อมูลและดัชนีของคุณ และ 256 MB เหมาะกับเซิร์ฟเวอร์ 2 GB ที่รันแอปด้วย ให้เพิ่มขนาดถ้าฐานข้อมูลเป็นงานหลักของเซิร์ฟเวอร์และใหญ่เกินแคชแล้ว max_connections = 50 เหลือเฟือสำหรับแอปเดียวที่ใช้ connection pool คุณจะเสียสถิติของ performance_schema ไป ถ้าวันหนึ่งต้องเจาะดูคิวรีที่ช้าอย่างละเอียด ค่อยเปิดกลับ
6. สำรองข้อมูลทุกคืน
mysqldump --single-transaction ทำสำเนาตาราง InnoDB ที่สอดคล้องกันโดยไม่ล็อกแอป ใส่ไว้ในสคริปต์เล็ก ๆ:
sudo tee /usr/local/bin/mysql-backup >/dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077
mkdir -p /var/backups/mysql
mysqldump --single-transaction --routines --triggers app | gzip > /var/backups/mysql/app-$(date +%F).sql.gz
find /var/backups/mysql -name 'app-*.sql.gz' -mtime +14 -delete
EOF
sudo chmod 755 /usr/local/bin/mysql-backup
echo '0 3 * * * root /usr/local/bin/mysql-backup' | sudo tee /etc/cron.d/mysql-backup
sudo /usr/local/bin/mysql-backup && sudo ls -l /var/backups/mysql
แต่ละบรรทัดมีเหตุผล:
umask 077ทำให้ไฟล์ dump อ่านได้เฉพาะ root (-rw-------) เพราะมีข้อมูลทั้งหมดของคุณpipefailทำให้ทั้งสคริปต์ล้มเหลวถ้าmysqldumpล้มเหลว ถ้าไม่มีบรรทัดนี้gzipจะเขียนไฟล์บีบอัดเปล่าขนาดจิ๋วแล้วรายงานว่าสำเร็จ เราจงใจทำให้คำสั่งพัง และสคริปต์ก็จบด้วยรหัส 2 อย่างที่ควรเป็นfind … -mtime +14 -deleteเก็บสำเนาไว้สองสัปดาห์- สคริปต์รันเป็น root ดังนั้น
mysqldumpจึงล็อกอินผ่าน socket และไม่ต้องเก็บรหัสผ่านไว้ในไฟล์ใด
ข้อมูลสำรองที่ไม่เคยกู้คืนยังนับไม่ได้ ให้กู้คืนลงฐานข้อมูลชั่วคราวแล้วดูข้อมูล:
sudo mysql -e "CREATE DATABASE app_restore"
gunzip -c /var/backups/mysql/app-2026-10-25.sql.gz | sudo mysql app_restore
sudo mysql -e "SHOW TABLES FROM app_restore"
sudo mysql -e "DROP DATABASE app_restore"
ในการทดสอบของเรา ตารางที่กู้คืนมีแถวเหมือนต้นฉบับทุกแถว สำเนาบนดิสก์เดียวกันช่วยอะไรไม่ได้ถ้าเซิร์ฟเวอร์หายไป จึงควรย้ายไปไว้เครื่องอื่นเป็นครั้งคราวด้วย scp หรือ restic ส่วน Managed Backups จะเพิ่มจุดกู้คืนรายวันของทั้งเซิร์ฟเวอร์ให้อีกชั้น
เลือกแพ็กเกจไหน
Micro (2 vCPU, 2 GB, 25 GB, $5/เดือน) รองรับ MySQL ที่ปรับแบบข้างต้นพร้อมเว็บแอปหนึ่งตัว ถ้าตัวฐานข้อมูลเองโตเกินไม่กี่กิกะไบต์ Small ที่มี 4 GB และ 35 GB ราคา $8/เดือน จะให้คุณจัด buffer pool ได้ 1 GB หรือมากกว่า ทั้งสองเป็นแพ็กเกจ NAT และ SSH tunnel ในขั้นตอนที่ 3 ใช้ได้ ขั้นตอนที่ 4 ต้องมี IPv4 ของตัวเอง: Micro-IP ราคา $10/เดือน
ชอบ PostgreSQL มากกว่า? คู่มือ PostgreSQL ใช้แนวทางเดียวกัน แพ็กเกจทั้งหมดอยู่ที่ VPS และชำระเงินด้วย USDT, USDC หรือ ETH บนเครือข่าย Base, Ethereum หรือ Polygon
ความคิดเห็น
ยังไม่มีความคิดเห็น เป็นคนแรกสิ