Cấu hình Tường lửa (UFW) để bảo vệ DuckDB
DuckDB chạy như một server độc lập thường lắng nghe trên cổng mặc định 8080. Để ngăn chặn truy cập trái phép từ internet, ta chỉ cho phép IP của máy chủ ứng dụng hoặc IP quản trị viên truy cập vào cổng này.
Mục tiêu: Kích hoạt UFW, chặn tất cả kết nối vào (deny all incoming) và chỉ mở cổng 8080 cho một dải IP cụ thể.
Trước khi thực thi, thay thế 192.168.1.100 bằng địa chỉ IP thực tế của máy khách được phép truy cập.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 192.168.1.100 to any port 8080 proto tcp
sudo ufw enable
Kết quả mong đợi: UFW được kích hoạt (status active). Các kết nối từ IP lạ vào cổng 8080 sẽ bị từ chối ngay lập tức, chỉ IP 192.168.1.100 mới có thể handshake thành công.
Để verify, chạy lệnh sudo ufw status verbose. Bạn sẽ thấy dòng cho phép cụ thể cho cổng 8080 từ IP đã định.
Giám sát tài nguyên và hiệu năng hệ thống
Sử dụng các công cụ giám sát cơ bản
DuckDB là database in-memory, việc tiêu thụ RAM và CPU thường tăng đột biến khi xử lý truy vấn lớn. Cần theo dõi liên tục để phát hiện rò rỉ bộ nhớ hoặc quá tải CPU.
Ta sử dụng htop để xem tiến trình, vmstat để theo dõi bộ nhớ ảo, và free -h để kiểm tra dung lượng RAM còn lại.
htop
Trong htop, tìm tiến trình duckdb. Quan sát cột MEM% (tỷ lệ bộ nhớ) và %CPU. Nếu MEM% tăng liên tục không giảm sau khi query xong, có dấu hiệu rò rỉ bộ nhớ.
Để kiểm tra trạng thái bộ nhớ ảo và swap, sử dụng vmstat với khoảng thời gian cập nhật 1 giây.
vmstat 1 5
Kết quả mong đợi: Các cột si (swap in) và so (swap out) bằng 0. Nếu hai cột này tăng cao, hệ thống đang bị OOM (Out of Memory) và DuckDB sẽ chạy rất chậm hoặc treo.
Kiểm tra nhanh dung lượng RAM đang dùng và còn lại.
free -h
Kết quả mong đợi: Cột available phải lớn hơn 0. Nếu available = 0, cần can thiệp ngay lập tức.
Giám sát qua Log Systemd
Vì DuckDB đang chạy dưới dạng service systemd, ta có thể lọc log riêng của nó để phát hiện cảnh báo sớm.
sudo journalctl -u duckdb-server -f
Kết quả mong đợi: Dòng log cập nhật theo thời gian thực. Tìm kiếm các từ khóa như ERROR, WARNING, segfault hoặc OOM killer.
Phân tích log lỗi và xử lý sự cố
Xử lý khi Service bị treo (Hang)
Khi DuckDB bị treo, thường do truy vấn quá lớn gây deadlock hoặc cạn kiệt bộ nhớ. Không nên tắt máy ngay lập tức.
Bước 1: Xác nhận tiến trình bị treo bằng cách kiểm tra trạng thái CPU.
ps aux | grep duckdb
Nếu CPU ở mức 100% liên tục trong 5 phút và không có phản hồi, tiến hành tắt service một cách an toàn trước.
sudo systemctl stop duckdb-server
Kết quả mong đợi: Service dừng lại. Nếu lệnh stop không phản hồi sau 10 giây, buộc phải kill tiến trình.
sudo pkill -9 -f duckdb
Bước 2: Khởi động lại service và kiểm tra log để tìm nguyên nhân.
sudo systemctl start duckdb-server
sudo journalctl -u duckdb-server --since "5 minutes ago"
Kết quả mong đợi: Service hoạt động lại. Log sẽ hiển thị nguyên nhân treo (ví dụ: "Connection timeout" hoặc "Memory allocation failed").
Xử lý lỗi "Database is locked"
Lỗi này xảy ra khi có quá nhiều client đồng thời ghi dữ liệu vào cùng một file, hoặc DuckDB chưa kịp release lock.
Kiểm tra file lock trong thư mục dữ liệu.
ls -l /var/lib/duckdb/*.lock
Nếu file lock tồn tại nhưng service đã dừng, có thể xóa file lock này (chỉ khi chắc chắn không có tiến trình nào đang chạy).
sudo rm /var/lib/duckdb/*.lock
Sau đó khởi động lại service.
sudo systemctl restart duckdb-server
Kết quả mong đợi: Database mở khóa thành công và chấp nhận kết nối mới.
Tối ưu hóa truy vấn và xử lý OOM
Sử dụng EXPLAIN để phân tích truy vấn
Khi truy vấn chạy chậm, sử dụng lệnh EXPLAIN để xem DuckDB lên kế hoạch thực thi như thế nào. Điều này giúp tìm ra các bước tốn kém tài nguyên (như Full Table Scan).
EXPLAIN SELECT * FROM large_table WHERE status = 'active';
Kết quả mong đợi: Một cây kế hoạch (Plan Tree) hiển thị các toán tử. Tìm các toán tử như SeqScan (quét toàn bộ bảng) trên bảng lớn. Nếu thấy, cần tạo chỉ mục (Index) hoặc lọc dữ liệu tốt hơn.
Giới hạn bộ nhớ (Memory Limit) để tránh OOM
Để ngăn DuckDB tiêu thụ hết RAM và làm sập hệ điều hành, ta cần giới hạn bộ nhớ tối đa mà DuckDB được sử dụng thông qua biến môi trường trong file config của systemd.
Chỉnh sửa file unit của systemd để thêm biến môi trường DUCKDB_MEMORY_LIMIT.
sudo nano /etc/systemd/system/duckdb-server.service
Trong file, thêm dòng sau vào phần [Service]:
Environment="DUCKDB_MEMORY_LIMIT=2G"
Lưu ý: Thay 2G bằng mức phù hợp với RAM máy chủ (thường là 70-80% tổng RAM).
Sau khi lưu, reload systemd và restart service.
sudo systemctl daemon-reload
sudo systemctl restart duckdb-server
Kết quả mong đợi: Khi DuckDB cố gắng dùng hơn 2GB RAM, nó sẽ tự động chuyển sang dùng disk (spill to disk) hoặc báo lỗi thay vì làm sập OS.
Xử lý sự cố OOM Killer
Nếu hệ thống vẫn bị OOM Killer giết tiến trình DuckDB dù đã set limit, kiểm tra log của Kernel (dmesg).
dmesg | grep -i "killed process"
Nếu thấy dòng "Out of memory: Killed process ... duckdb", nghĩa là limit trong config chưa được áp dụng hoặc RAM vật lý quá ít.
Giải pháp: Tăng swap file của Ubuntu hoặc giảm DUCKDB_MEMORY_LIMIT xuống thấp hơn.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Để lưu swap vĩnh viễn, thêm dòng /swapfile none swap sw 0 0 vào file /etc/fstab.
Kết quả mong đợi: Hệ thống có thêm 4GB bộ nhớ ảo. DuckDB có thể spill ra file swap thay vì bị kill ngay lập tức.
Điều hướng series:
Mục lục: Series: Triển khai Database Serverless với DuckDB và Ubuntu 24.04
« Phần 5: Tự động hóa sao lưu, khôi phục và mở rộng dữ liệu