Tối ưu MariaDB trên VPS 2GB RAM hiệu quả

SSH vào VPS 2GB RAM và chạy htop, thấy MariaDB "ngốn" gần hết bộ nhớ rồi bị kernel kill vì OOM, đó là lỗi mà mình gặp khá nhiều lần khi hỗ trợ khách thuê VPS tại thueVPS. Nguyên nhân không phải MariaDB "xấu", mà là các giá trị mặc định trong file cấu hình được tính cho máy có nhiều RAM hơn. Bài này mình sẽ hướng dẫn bạn chỉnh MariaDB trên VPS 2GB RAM để dịch vụ chạy ổn định, hết bị treo vì thiếu bộ nhớ, mà vẫn đủ sức phục vụ website. Toàn bộ lệnh áp dụng cho Ubuntu 24.04 và Debian 12.
Tóm tắt nhanh
- Chỉnh
innodb_buffer_pool_size = 512M(khoảng 1/4 RAM) là mức an toàn nhất cho VPS 2GB RAM. - Bật swap tối thiểu 2GB để làm bộ đệm khi RAM đầy, tránh bị OOM killer tấn công tiến trình MariaDB.
- Giảm
max_connectionscòn 50 và đặtmax_connections_errorsđể chống cạn tài nguyên. - Đo trước và sau khi chỉnh bằng
mysqltunerhoặcpt-mysql-summaryđể biết hướng đi đúng.
Yêu cầu trước khi bắt đầu
- Một VPS chạy Ubuntu 24.04 hoặc Debian 12 với dung lượng RAM tối thiểu 2GB.
- Quyền
roothoặc user có quyềnsudo. - MariaDB đã được cài đặt và dịch vụ
mariadbđang chạy. - Bạn biết câu lệnh cơ bản:
systemctl,nanohoặcvim, vàmysql.
Vì sao MariaDB ngốn RAM?
MariaDB sử dụng InnoDB làm engine lưu trữ mặc định. InnoDB có một vùng nhớ gọi là buffer pool, dùng để cache dữ liệu và index, giúp truy vấn không phải đọc từ ổ cứng. Mặc định, MariaDB đặt buffer pool rất lớn, có thể lên tới 128MB hoặc nhiều hơn tùy bản cài, và cùng với các cache khác, tổng bộ nhớ chiếm dụng dễ vượt qua 1GB trên VPS 2GB RAM.
Khi website bắt đầu có traffic, MariaDB nạp dữ liệu vào buffer pool. Đến lúc RAM hết, kernel bật OOM killer và thường chọn tiến trình chiếm nhiều RAM nhất, chính là mariadbd, để kill. Hậu quả là website lỗi 502, không truy cập được. Đây là lý do vì sao việc tối ưu MariaDB trên VPS 2GB RAM không phải là tùy chọn mà là bắt buộc nếu bạn muốn dịch vụ chạy lâu dài.
Thực tế mình từng gặp một khách hàng chạy website WordPress trên VPS 2GB RAM, cứ mỗi 2-3 ngày là MariaDB bị kill một lần. Sau khi chỉnh buffer pool về 512M và bật swap thì gần như hiếm khi gặp lại lỗi này. Vấn đề không phải do thiếu RAM, mà do không ai điều chỉnh cấu hình cho phù hợp.
Bước 1 - Xác định cấu hình hiện tại
Trước khi sửa, bạn cần biết MariaDB đang dùng bao nhiêu bộ nhớ và config hiện tại thế nào. Chạy lệnh sau để xem các biến quan trọng:
mariadb -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" -e "SHOW VARIABLES LIKE 'max_connections';" -e "SHOW VARIABLES LIKE 'key_buffer_size';"
Nếu lệnh trên báo lỗi do chưa có user root có quyền login, dùng sudo mariadb rồi chạy từng lệnh SHOW VARIABLES bên trong. Kết quả trả về cho ta ba con số:
| Biến | Giá trị mặc định (thường gặp) | Nên đặt cho VPS 2GB RAM |
|---|---|---|
innodb_buffer_pool_size | 128M | 512M |
max_connections | 151 | 50 |
key_buffer_size | 8M | 16M |
Bạn thấy đấy, innodb_buffer_pool_size mặc định chỉ 128M, nhưng vì sao MariaDB vẫn chiếm hơn 1GB RAM? Vì còn nhiều cache khác: innodb_log_buffer_size, table_open_cache, thread_cache_size, và bộ nhớ cho mỗi connection. Chúng cộng lại thành con số khổng lồ.
Bước 2 - Chỉnh file cấu hình MariaDB
File cấu hình chính nằm tại /etc/mysql/mariadb.conf.d/50-server.cnf trên Ubuntu và Debian. Bạn có thể tạo riêng một file mới để dễ quản lý, ví dụ /etc/mysql/mariadb.conf.d/99-tune.cnf, cách này an toàn hơn vì không đụng vào file mặc định.
sudo nano /etc/mysql/mariadb.conf.d/99-tune.cnf
Dán nội dung sau vào file:
[mysqld]
# Vùng nhớ cache dữ liệu và index - chiếm ~1/4 RAM
innodb_buffer_pool_size = 512M
# Giới hạn số kết nối đồng thời, tránh kiệt RAM
max_connections = 50
# Cache cho MyISAM, vẫn dùng cho bảng hệ thống
key_buffer_size = 16M
# Giảm số bảng mở cùng lúc
table_open_cache = 400
# Bộ nhớ tạm cho mỗi connection, không nên quá lớn
sort_buffer_size = 1M
join_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
# Log buffer nhỏ lại để tiết kiệm RAM
innodb_log_buffer_size = 4M
# Tắt hoặc giảm thread cache
thread_cache_size = 16
# Chống lỗi quá nhiều kết nối hỏng
max_connect_errors = 100
Các giá trị 1M cho sort_buffer_size hay join_buffer_size nghe có vẻ nhỏ, nhưng với MySQL/MariaDB, các buffer này được cấp phát riêng cho từng connection. Nếu bạn có 50 connection cùng chạy một lúc, mỗi connection dùng 1M cho sort buffer, tổng cộng là 50M, cộng với những buffer khác nữa. Nâng lên 8M hay 16M cho các biến này trên VPS 2GB RAM là cách nhanh nhất để làm server tụt RAM.
Sau khi lưu file, khởi động lại MariaDB và kiểm tra trạng thái:
sudo systemctl restart mariadb
sudo systemctl status mariadb
Output mong đợi có dòng active (running). Nếu không thấy, dùng sudo journalctl -u mariadb -n 50 để đọc log.
Bước 3 - Bật swap để chống OOM
Trên VPS 2GB RAM, việc bật swap gần như bắt buộc nếu bạn muốn MariaDB không bị kill khi có đột biến traffic. Swap là phân vùng hoặc file trên ổ cứng được dùng làm RAM ảo. Kiểm tra xem swap đã được bật chưa:
free -h
Nếu dòng Swap hiển thị 0B, bạn cần tạo swap file. Lệnh sau tạo swap file 2GB:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Sau đó, chỉnh tham số vm.swappiness để hệ thống chỉ dùng swap khi cần thiết, tránh dùng swap sớm làm chậm dịch vụ:
sudo sysctl vm.swappiness=10
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
Giá trị swappiness=10 nghĩa là kernel chỉ đưa dữ liệu xuống swap khi RAM thực sự áp lực, giúp MariaDB giữ cache trong RAM lâu hơn. Bạn có thể kiểm tra lại bằng free -h, giờ sẽ thấy dòng Swap có dung lượng 2G.
Bước 4 - Kiểm tra và theo dõi hiệu năng
Sau khi chỉnh cấu hình, bạn nên theo dõi xem MariaDB hoạt động thế nào trong ít nhất 24-48 giờ. Một số lệnh hữu ích:
mariadb -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" -e "SHOW GLOBAL STATUS LIKE 'Max_used_connections';"
Lệnh này cho biết số kết nối hiện tại và số kết nối tối đa từng được sử dụng. Nếu Max_used_connections chạm ngưỡng 50, bạn cần tăng max_connections lên một chút, ví dụ 75, nhưng nhớ cân nhắc rằng mỗi connection tốn thêm RAM. Một cách khác là dùng công cụ mysqltuner để nhận gợi ý tự động:
sudo apt install mysqltuner -y
sudo mysqltuner --user root --pass 'mat-khau-cua-ban'
Lưu ý: mysqltuner chỉ đưa ra gợi ý, bạn phải tự đánh giá xem có phù hợp với VPS 2GB RAM hay không. Đôi khi nó gợi ý innodb_buffer_pool_size tăng lên 1G, nhưng với 2GB RAM thì đó là con số quá mạo hiểm nếu máy còn chạy Nginx, PHP-FPM và các dịch vụ khác.
Để theo dõi RAM thực tế mỗi tiến trình, dùng lệnh:
ps aux | grep mariadbd | grep -v grep
Cột %MEM cho biết phần trăm RAM tiến trình chiếm dụng. Sau khi chỉnh, mình thường thấy mariadbd dùng khoảng 25-30% RAM (tức 500-600MB), là con số hoàn toàn chấp nhận được.
Bước 5 - Tinh chỉnh cho WordPress và các ứng dụng phổ biến
Nếu VPS 2GB RAM của bạn chạy WordPress, cấu hình trên là đủ dùng. Tuy nhiên, WordPress có một số plugin kết nối database khá "phàm ăn", ví dụ WooCommerce hay các plugin báo cáo. Bạn nên kết hợp thêm một lớp cache (Redis hoặc Memcached) để giảm tải truy vấn xuống MariaDB. Mình đã viết bài hướng dẫn cài đặt Redis trên VPS Linux, bạn có thể đọc thêm để biết cách kết hợp.
Còn nếu bạn chạy ứng dụng viết bằng PHP thuần, hay một trang web nhỏ, thì cấu hình trên là quá thoải mái. Không cần thêm gì. Nhớ rằng, mục tiêu của tối ưu MariaDB trên VPS 2GB RAM không phải là vắt kiệt hiệu năng, mà là giữ cho dịch vụ ổn định trong ngân sách RAM hạn hẹp.
Xử lý lỗi thường gặp
Lỗi 1: MariaDB không khởi động được sau khi chỉnh config. Nguyên nhân thường là sai cú pháp trong file .cnf. Kiểm tra bằng lệnh:
sudo mariadbd --verbose --help 2>/dev/null | head -n 20
Nếu không có lỗi, hãy xem log:
sudo journalctl -u mariadb -n 50
Hầu hết trường hợp do bạn gõ nhầm tên biến hoặc thiếu dấu =. Sửa lại là chạy ngay.
Lỗi 2: "Too many connections" xuất hiện trong log. Điều này có nghĩa max_connections quá thấp hoặc website có nhiều kết nối database bị treo. Kiểm tra và tăng lên một chút:
mariadb -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" -e "SHOW GLOBAL STATUS LIKE 'Max_used_connections';"
Nếu Max_used_connections thường xuyên bằng hoặc gần bằng max_connections, bạn cần tăng giá trị này lên, hoặc tối ưu ứng dụng để dùng connection pool tốt hơn.
Câu hỏi thường gặp
Vì sao MariaDB bị kill (OOM) khi dùng VPS 2GB RAM?
Vì các giá trị mặc định của MariaDB cấp phát bộ nhớ quá lớn so với 2GB RAM, đặc biệt là các buffer tính theo từng connection. Khi website có nhiều truy cập đồng thời, RAM nhanh chóng cạn kiệt và kernel buộc phải kill tiến trình chiếm nhiều RAM nhất, thường là mariadbd.
innodb_buffer_pool_size nên đặt bao nhiêu cho VPS 2GB RAM?
Nên đặt khoảng 512M, tức 1/4 RAM. Nếu server chỉ chạy mỗi MariaDB không có gì khác, bạn có thể thử 768M, nhưng nếu chạy thêm Nginx, PHP-FPM hay Redis thì 512M là mức an toàn.
Có cần bật swap khi dùng MariaDB trên VPS 2GB RAM không?
Có. Swap ít nhất 2GB giúp MariaDB không bị kill khi có đột biến traffic hay một truy vấn nặng tạm thời. Tất nhiên, swap không thể thay thế RAM, nó chỉ là "phao cứu sinh" để tránh sập dịch vụ.
Làm sao biết server cần tăng RAM hay chỉ cần tối ưu?
Nếu bạn đã tối ưu theo hướng dẫn mà Max_used_connections vẫn thường xuyên chạm ngưỡng, hoặc CPU liên tục rất cao, hoặc website chậm dù buffer pool đã đủ, thì đã đến lúc cần thuê một VPS Linux có RAM cao hơn, ví dụ 4GB hoặc 8GB. Tối ưu giúp bạn dùng tốt những gì đang có, nhưng có một ngưỡng không thể qua.
Dùng MariaDB hay MySQL cho VPS RAM thấp?
MariaDB là lựa chọn tốt hơn cho VPS RAM thấp vì nó được tối ưu từ MySQL và có nhiều cải tiến về hiệu năng cũng như khả năng quản lý bộ nhớ. Ngoài ra, MariaDB là bản phát hành mặc định trên hầu hết distro Linux hiện nay.
Bài viết liên quan
- Tối ưu MySQL cho VPS ít RAM hiệu quả
- Cấu hình swap và tối ưu bộ nhớ cho VPS RAM thấp
- Cài đặt và tối ưu MariaDB trên VPS Ubuntu 24.04
- Chẩn đoán nghẽn CPU, RAM, I/O trên VPS Linux


