Как увеличить максимальное число открытых файлов для MySQL
Взято [1].
Содержание
Проблема
Зачастую при увеличении параметров max_connections или table_open_cache в более высокие значения они не могут быть установлены из-за ограничение ОС. При старте MySQL в логе error.log мы видим предупреждения:
2018-04-27T01:01:18.027751Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 32310) 2018-04-27T01:01:18.027846Z 0 [Warning] Changed limits: max_connections: 214 (requested 300) 2018-04-27T01:01:18.027853Z 0 [Warning] Changed limits: table_open_cache: 400 (requested 16000)
Которые говорят, что наши параметры не могут быть установлены.
Но как это исправить?
Читаем ниже.
Исходные данные
ОС: Ubuntu 16.04.4 LTS
БД: Oracle MySQL 5.7.22
Задача: Решить проблему с невозможностью установки параметров max_connections=300 и table_open_cache=16000
При старте MySQL в логе error.log мы можем увидеть предупреждения вида:
2018-04-27T01:01:18.027751Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 32310) 2018-04-27T01:01:18.027846Z 0 [Warning] Changed limits: max_connections: 214 (requested 300) 2018-04-27T01:01:18.027853Z 0 [Warning] Changed limits: table_open_cache: 400 (requested 16000)
При этом в файле конфигурации /etc/mysql/mysql.conf.d/mysqld.cnf у нас установлено:
max_connections = 300 table_open_cache = 16000
Но MySQL не может установить эти значение и они понижаются до разрешенных, а именно max_connections всего до 214 разрешенных соединений, а table_open_cache до 400.
Если посмотреть настройки MySQL, то можем увидеть такую картину:
# mysql -u root -p mysql> show global variables like '%max_connections%'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 300 | +-----------------+-------+ 1 row in set (0,00 sec) mysql> show global variables like '%open_files_limit%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | open_files_limit | 1024 | +------------------+-------+ 1 row in set (0,00 sec) mysql> show global variables like '%table_open_cache'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | table_open_cache | 400 | +------------------+-------+ 1 row in set (0,00 sec)
Вроде как max_connections и установлен 300, но остальные настройки явно не те, что нам нужны.
Корень проблемы кроется в ограничении ОС на количество открываемых файловых дескрипторов для процесса mysqld, посмотреть ограничение мы можем так:
# cat /proc/$(pgrep mysqld)/limits | grep open Max open files 1024 4096 files
В ней мы видим, что максимально разрешено открывать не более 1024 файловых дескрипторов.
Именно из-за этого при старте mysqld не может установить запрошенные нами опции max_connections, table_open_cache.
Решение
Давайте увеличим лимит файловых дескрипторов для mysqld на 10000.
Для начала нужно выяснить систему инициализации в нашем Linux дистрибутиве, выполняем:
strings /sbin/init | awk 'match($0, /(upstart|systemd|sysvinit)/) { print toupper(substr($0, RSTART, RLENGTH));exit; }'
Команда выдала SYSTEMD.
Для systemd лимиты устанавливаются немного по другому, чем принято думать, а именно:
Выясним где находится unit файл для запуска MySQL:
# systemctl status mysql ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Пт 2018-04-27 06:01:36 +05; 6h ago Main PID: 6370 (mysqld) Tasks: 82 Memory: 88.2G CPU: 1d 19h 2min 53.203s CGroup: /system.slice/mysql.service └─6370 /usr/sbin/mysqld
Создадим файл с описанием новых лимитов:
Мы выяснили, что unit файл это /lib/systemd/system/mysql.service, теперь нам нужно создать каталог /lib/systemd/system/mysql.service.d и в нем разместить файл limit.conf со следующим содержимым:
[Service] LimitNOFILE=10000
Выполним несколько команд для этого:
mysql_systemd_dir="/lib/systemd/system/mysql.service.d" mkdir -p ${mysql_systemd_dir} echo "[Service]" >${mysql_systemd_dir}/limit.conf echo "LimitNOFILE=10000" >>${mysql_systemd_dir}/limit.conf systemctl daemon-reload
Теперь проверим будет ли наша конфигурация подхвачена:
# systemctl status mysql ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Drop-In: /lib/systemd/system/mysql.service.d └─limit.conf Active: active (running) since Пт 2018-04-27 06:01:36 +05; 6h ago Main PID: 6370 (mysqld) Tasks: 82 Memory: 88.2G CPU: 1d 19h 2min 53.203s CGroup: /system.slice/mysql.service └─6370 /usr/sbin/mysqld
Отлично, теперь нам нужно перезапустить MySQL:
systemctl restart mysql
Проверим лимиты:
# cat /proc/$(pgrep mysqld)/limits Limit Soft Limit Hard Limit Units .. Max open files 10000 10000 files ...
Проверим настройки MySQL:
# mysql -u root -p mysql> show global variables like '%max_connections%'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_connections | 300 | +-----------------+-------+ 1 row in set (0,00 sec) mysql> show global variables like '%open_files_limit%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | open_files_limit | 10000 | +------------------+-------+ 1 row in set (0,00 sec) mysql> show global variables like '%table_open_cache'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | table_open_cache | 16000 | +------------------+-------+ 1 row in set (0,00 sec)
Отлично, это то, что нам нужно.