Tối ưu MariaDB cho VPS RAM thấp trên Ubuntu 24.04

Bạn vừa mua một VPS Ubuntu 24.04 và bắt đầu cài MariaDB, nhưng vps 2gb ram nhanh chóng bị ngập swap sau vài giờ chạy. Đây là vấn đề phổ biến. Mặc định MariaDB dùng cấu hình "server" hướng đến workload lớn, không phù hợp môi trường hạn chế bộ nhớ. Bài này hướng dẫn chi tiết cách tối ưu MariaDB cho VPS chỉ có 1-4GB RAM, giúp database chạy ổn định, không bị OOM kill, tăng tốc độ truy vấn.
Yêu cầu trước khi bắt đầu
- Một VPS chạy Ubuntu 24.04 LTS đã cài MariaDB (bài này dùng phiên bản MariaDB 10.11 - bản LTS hiện tại)
- Quyền root hoặc user sudo
- Xác định RAM thực tế của VPS bằng lệnh
free -h, ghi nhớ kết quả để tính toán sau - Hiểu rõ: mọi chỉnh sửa đều có đánh đổi. Tối ưu cho RAM thấp có thể giảm performance cho workload write-heavy.
Vì sao MariaDB ngốn RAM và khi nào cần tối ưu
MariaDB dùng RAM để cache dữ liệu (InnoDB buffer pool), cache query, và duy trì kết nối (thread cache). File cấu hình mặc định thường nằm trong gói mariadb-server và được chỉnh cho VPS 8-16GB RAM, dẫn đến VPS nhỏ hơn bị quá tải. Bạn cần tối ưu khi:
- Thấy MariaDB dùng swap nhiều (
swapon --showthấy swap occupied >0 và tăng dần) - Hệ thống ghi nhận OOM killer hoặc MariaDB tự restart
htophiển thị memory của mysqld tiến tới 80-90% RAM vật lý
Bước 1 - Tìm và sao lưu file cấu hình hiện tại
/etc/mysql/mariadb.conf.d/50-server.cnf là file chính. Kiểm tra và sao lưu ngay:
sudo cp /etc/mysql/mariadb.conf.d/50-server.cnf /etc/mysql/mariadb.conf.d/50-server.cnf.bak
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Dùng sudo nano vì dòng sau cần được thêm/sửa trong [mysqld] section. Nếu chưa có section này, thêm dòng [mysqld] ở đầu file.
Bước 2 - Tính toán và cấu hình InnoDB buffer pool - tham số quan trọng nhất
InnoDB buffer pool chiếm phần lớn RAM. Công thức: tối đa 50-60% RAM vật lý nếu VPS chuyên chạy database, hoặc 30-40% nếu VPS chạy thêm app khác (PHP, Nginx). Ví dụ:
- VPS 1GB RAM (chạy web + MariaDB): buffer pool = 256M-384M
- VPS 2GB RAM (chuyên database nhỏ): buffer pool = 512M-768M
- VPS 4GB RAM (workload WordPress vừa): buffer pool = 1G-1.5G
Thêm vào file cấu hình (dưới [mysqld]), thay thế giá trị mặc định:
# InnoDB
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
Giải thích: innodb_flush_log_at_trx_commit = 2 giảm số lần ghi log (an toàn hơn cho VPS không gặp crash liên tục, mất dữ liệu tối đa 1-2 giây). O_DIRECT bỏ qua page cache OS, giảm RAM tiêu thụ thêm.
Verify: Khởi động lại MariaDB sudo systemctl restart mariadb, chạy SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; trong MariaDB để kiểm tra. Giá trị trả về phải khớp 268435456 (tức 256M).
Bước 3 - Giới hạn query cache và thread cache
Query cache không còn hiệu quả với workload hiện đại. Tắt nó để tiết kiệm RAM:
# Query cache
query_cache_type = 0
query_cache_size = 0
Thread cache kiểm soát số thread MySQL giữ sẵn cho kết nối mới. Với số site ít, set thấp:
# Thread
thread_cache_size = 8
thread_stack = 192K
table_open_cache = 400
max_connections = 30
max_connections = 30 giới hạn số kết nối đồng thời. Nếu VPS chỉ chạy 1-2 site nhỏ, 20 cũng đủ. Cảnh báo: nếu site có traffic spike, bạn sẽ thấy lỗi "Too many connections", hãy tăng dần khi cần.
Verify: Dùng SHOW VARIABLES LIKE '%thread%'; và SHOW VARIABLES LIKE 'max_connections'; trong MariaDB để xác nhận.
Bước 4 - Tối ưu join buffer và sort buffer
Hai buffer này được cấp phát mỗi lần thực hiện join/sort, nên set nhỏ để tránh bùng nổ RAM. Giá trị mặc định thường quá lớn:
# Join & Sort
join_buffer_size = 128K
sort_buffer_size = 256K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
tmp_table_size = 64M
max_heap_table_size = 64M
tmp_table_size và max_heap_table_size giới hạn bảng tạm nội bộ. Nếu truy vấn phức tạp → tăng lên 128M.
Lưu ý: join_buffer_size set mỗi kết nối. Nếu 30 connections đồng thời, mỗi connection dùng 2 join buffers, tổng = 30 * 2 * 128KB = 7.5MB, cực kỳ ít. Cần tăng lên 1M-2M nếu database có query JOIN phức tạp.
Bước 5 - Tối ưu ghi log và bảo vệ swap
Swap là chậm. Tránh MariaDB dùng swap bằng cách cấu hình memlock và swappiness:
Trong file cấu hình MariaDB:
# Memlock
memlock = 1
Trên hệ thống (tạm thời cho session hiện tại):
sudo sysctl vm.swappiness=1
lâu dài: Thêm dòng vm.swappiness=1 vào /etc/sysctl.conf. Lưu ý: memlock yêu cầu MariaDB chạy dưới user mysql có quyền, kiểm tra bằng systemctl status mariadb xem có lỗi "Failed to set memory lock" không. Nếu lỗi, comment dòng memlock lại.
Verify: cat /proc/sys/vm/swappiness phải trả về 1. Kiểm tra swap usage với swapon --show sau vài giờ hoạt động.
Bước 6 - Cấu hình hệ điều hành hỗ trợ MariaDB trên VPS RAM thấp
Giới hạn file descriptor và tối ưu I/O scheduler cho NVMe:
# Trong /etc/security/limits.conf hoặc /etc/systemd/system/mariadb.service.d/override.conf
# Dùng systemd
sudo mkdir -p /etc/systemd/system/mariadb.service.d
sudo nano /etc/systemd/system/mariadb.service.d/limits.conf
Thêm vào:
[Service]
LimitNOFILE=65536
LimitNPROC=1024
Reload systemd và restart MariaDB:
sudo systemctl daemon-reload
sudo systemctl restart mariadb
I/O Scheduler cho ổ NVMe thường là none, không cần chỉnh. Kiểm tra bằng cat /sys/block/nvme0n1/queue/scheduler.
Xử lý lỗi thường gặp
MariaDB không khởi động sau khi chỉnh config
Kiểm tra lỗi cú pháp: sudo mysqld --verbose --help 2>&1 | grep -A1 "Unknown variable". Hoặc xem log sudo journalctl -u mariadb --no-pager | tail -30. Lỗi phổ biến: sai section, thiếu dấu =, sai giá trị (vd 256G thay vì 256M).
Lỗi "Too many connections"
Nâng max_connections lên 50 hoặc 100. Kiểm tra kết nối hiện tại: SHOW PROCESSLIST;, nếu có nhiều kết nối từ WordPress không đóng, thêm plugin query cache object (Redis) để giảm số kết nối database.
MariaDB bị kill (OOM) dù đã cấu hình
Nguyên nhân: ứng dụng PHP/Nginx dùng quá nhiều RAM. Kiểm tra dmesg -T | tail -10 hoặc journalctl -k -g "oom". Giải pháp: giảm buffer pool thêm 50% (chấp nhận chậm hơn), hoặc thuê gói VPS cao hơn. Nếu workload WordPress, hãy cân nhắc tăng tốc WordPress bằng LiteSpeed để giảm tải database.
Câu hỏi thường gặp
MariaDB dùng 600MB RAM trên VPS 1GB là bình thường?
Không. Với cấu hình tối ưu như trên, MariaDB chỉ nên dùng 200-350MB cho workload nhẹ (1-2 site WordPress nhỏ). Nếu vượt quá, kiểm tra lại Innodb buffer pool và tắt query cache.
Có cần tắt InnoDB để tiết kiệm RAM?
Không khuyến nghị. Hầu hết WordPress, Laravel, Django dùng InnoDB làm engine mặc định. Tắt Innodb chỉ phù hợp nếu bạn dùng MyISAM thuần túy và chấp nhận không có transaction.
Thay vì tối ưu, có nên mua thêm RAM?
Có, nếu workload thực sự cần. Thuê VPS Linux 4GB RAM có thể là giải pháp tốt hơn là ép MariaDB chạy với cấu hình quá thấp. Tuy nhiên, với VPS 2GB-4GB, tối ưu thường đủ dùng.
Cấu hình trên có áp dụng cho MySQL 8 không?
Có, gần như tương tự. MariaDB 10.11 tương thích cấu hình với MySQL 8. Chỉ khác file config /etc/mysql/mysql.conf.d/mysqld.cnf và tham số innodb_buffer_pool_chunk_size nếu MySQL 8.0.28+.
Làm sao biết query nào đang ngốn RAM?
Vào MariaDB, chạy SHOW FULL PROCESSLIST; để xem query đang chạy. Dùng EXPLAIN trước query để phân tích index. Cài mysqltuner.pl hoặc tuning-primer.sh để nhận gợi ý.
Bài viết liên quan
- Cài đặt LEMP stack Nginx MariaDB PHP 8.3 trên Ubuntu 24.04
- Tối ưu PHP-FPM cho WordPress trên VPS Ubuntu
- Tối ưu Nginx cho traffic cao worker gzip buffer cache
- Tối ưu Linux và NVMe cho workload I/O cao trên VPS
- Hướng dẫn cài đặt Redis cache cho ứng dụng web trên VPS


