Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Áp dụng limits cho dịch vụ db
Hiện trạng
Gần đây, tôi có xử lý một case db như sau: Tài nguyên hệ thống còn dư nhưng không hiểu sao mysqld lại báo Cannot create new thread (errno 11) if you are not out of available memory, you can consult the manual for a possible OS-dependent bug.
Mysql kêu rằng không tạo thêm thread để xử lý request và nó đồ đoán hệ thống cạn tài nguyên về memory hoặc có lỗi về OS. Khi cấu hình mysql tôi cũng đã lưu ý trường hợp này nên không khỏi băn khoăn tại sao thông báo trên lại xuất hiện. Cơ bản cách làm của tôi là đặt giới hạn tài nguyên cho mysql user trong /etc/security/limits.d/95-mysql.conf
95 là priority thôi, trong trường hợp limits.d có nhiều file conf thì cần có priority để đọc lần lượt và ghi đè các config trùng lặp.
Nội dung file này như sau:
mysql soft nproc 16000
mysql hard nproc 32000
mysql soft nofile 16000
mysql hard nofile 32000
Tôi thử kiểm tra các gía trị limits trực tiếp trên process đang hoạt động.
cat /proc/`pidof mysqld`/limits | egrep '(processes|files)'
Gía trị nhận được thấp hơn rất nhiều. Nhưng khi su - mysql và kiểm tra ulimit thì thấy gía trị limit lại khớp với config file trong limits.d
Nguyên nhân
Tôi nhớ mongod họ cũng khuyến cáo phải chỉnh limits và tôi cũng chỉnh trong limits.d thì thấy chạy rất ổn, không có vấn đề gì. Nghĩ bụng hay là file init script hai thằng này khác nhau. Mở đại một con mongod đang chạy, xem init script của nó:
daemon --user "$MONGO_USER" "$NUMACTL $mongod $OPTIONS >/dev/null 2>&1"
Chú ý có dòng --user như vậy process mongod sẽ chạy dưới quyền mongod user. Kiểm tra tiếp bằng ps. Không có gì lạ
ps -elf | grep mongod
1 S mongod 70413 1 24 80 0 - 224765092 poll_s Jun04 ? 10-10:09:59 /usr/bin/mongod -f /etc/mongod.conf
Giờ thử mở một con mysqld, xem init script của nó:
$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1
chà không có --user, như vậy process này chạy khởi động bằng root sau đó sẽ spawn một main process mysqld để xử lý mysql request, kỹ thuật này được dùng khá nhiều trên các dịch vụ khác nhau. Lý do tạo một process riêng có quyền khác root để xử lý request nhằm đảm bảo tính an toàn. Tránh trường hợp process bị compromise mà mất luôn quyền root. Như vậy thực tế process mysqld sẽ kế thừa limits của user root.
Kiểm tra bằng ps
ps -elf | grep mysqld
4 S root 14739 1 0 80 0 - 2866 wait 10:58 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/appvnhn-web2.pid
4 S mysql 15433 14739 4 80 0 - 2644951 poll_s 10:58 ? 00:00:51 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysqld/mysql_error.log --pid-file=/var/lib/mysql/test.pid --socket=/var/lib/mysql/mysql.sock
mysqld chạy dưới quyền mysql user nhưng được sinh ra từ process root
Giải pháp
Giải pháp kiểu on-the-fly
Apply ngay limits mới mà không cần restart service
echo -n "Max processes=16000:32000" > /proc/`pidof mysqld`/limits
echo -n "Max open files=16000:32000" > /proc/`pidof mysqld`/limits
Giải pháp một lần và mãi mãi
Sửa trong file config: Thay mysql user bằng root user
root soft nproc 16000
root hard nproc 32000
root soft nofile 16000
root hard nofile 32000
Tham khảo:
https://www.percona.com/blog/2013/02/04/cant_create_thread_errno_11/




