EQVPS

วิธีติดตั้ง MySQL บน VPS: ผู้ใช้ การเข้าถึงระยะไกลอย่างปลอดภัย ใช้ RAM น้อยลง และการสำรองข้อมูล

ติดตั้ง MySQL 8.0 บน VPS Ubuntu 24.04 สร้างฐานข้อมูลและผู้ใช้สำหรับแอป เชื่อมต่อจากคอมพิวเตอร์ของคุณโดยไม่ต้องเปิดพอร์ต 3306 ลดหน่วยความจำตอนว่างจาก 383 MB เหลือ 165 MB และสำรองข้อมูลทุกคืนด้วยสคริปต์ที่ล้มเหลวให้เห็นชัดเมื่อมีปัญหา

การติดตั้ง 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

คำถามที่พบบ่อย

MySQL หรือ MariaDB?

ทั้งสองอยู่ในคลังแพ็กเกจของ Ubuntu 24.04 เอง mysql-server ติดตั้ง MySQL 8.0 ส่วน mariadb-server ติดตั้ง MariaDB 10.11 แอปส่วนใหญ่ที่ต้องการ "MySQL" ใช้ได้กับทั้งสองตัว ให้ใช้ตามที่เอกสารของแอประบุ และถ้าไม่สำคัญก็เลือก MySQL 8.0 คู่มือนี้ใช้ MySQL

รหัสผ่าน root ของ MySQL คืออะไร?

ไม่มี บน Ubuntu บัญชี root ของ MySQL ใช้การยืนยันตัวตนผ่าน socket คำสั่ง sudo mysql จะพาคุณเข้าเป็น root และไม่มีใครล็อกอินเป็น root ผ่านเครือข่ายได้ ปล่อยไว้แบบนี้ แล้วสร้างผู้ใช้แยกสำหรับแต่ละแอป

ควรเปิดพอร์ต 3306 สู่อินเทอร์เน็ตไหม?

ไม่ควร พอร์ตฐานข้อมูลที่เปิดไว้จะถูกสแกนและถูกลองเดารหัสผ่านตลอดเวลา จากคอมพิวเตอร์ของคุณให้เชื่อมต่อผ่าน SSH tunnel ถ้าเซิร์ฟเวอร์อื่นต้องเชื่อมต่อโดยตรง ให้อนุญาตเฉพาะ IP ของเซิร์ฟเวอร์นั้น ทั้งใน MySQL และในไฟร์วอลล์

MySQL ต้องใช้ RAM เท่าไร?

หลังติดตั้งเสร็จ MySQL 8.0 ใช้ 383 MB บนเซิร์ฟเวอร์ทดสอบของเรา โดยยังไม่มีฐานข้อมูลของตัวเอง เมื่อปิด Performance Schema และตั้ง buffer pool ขนาดพอประมาณ ก็ลดเหลือ 165 MB แพ็กเกจ Micro 2 GB รัน MySQL กับแอปได้สบาย และหลังปรับแบบนี้ 1 GB ก็พอสำหรับเว็บไซต์เล็ก ๆ

จำเป็นต้องรัน mysql_secure_installation ไหม?

บน Ubuntu 24.04 งานส่วนใหญ่ของมันเสร็จไปแล้ว การติดตั้งใหม่ของเราไม่มีผู้ใช้นิรนามและไม่มีฐานข้อมูลทดสอบ และ root ล็อกอินได้ผ่าน socket ภายในเครื่องเท่านั้น ให้รันถ้าคุณต้องการส่วนตรวจความแข็งแรงของรหัสผ่านที่มันมีให้ ไม่อย่างนั้นข้ามไปได้

ความคิดเห็น

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

แสดงความคิดเห็น

ความคิดเห็นจะถูกตรวจสอบก่อนแสดง