Зачастую при увеличении параметров 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 Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 1031546 1031546 processes Max open files 1024 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 1031546 1031546 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us
Нас интересует строка:
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 лимиты устанавливаются немного по другому, чем принято думать, а именно:
1. Выясним где находится 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
2. Создадим файл с описанием новых лимитов:
Мы выяснили, что unit файл это /lib/systemd/system/mysql.service, теперь нам нужно создать каталог /lib/systemd/system/mysql.service.d и в нем разместить файл limit.conf со следующим содержимым:
[Service] LimitNOFILE=10000
Выполним несколько команд для этого:
mkdir -p /lib/systemd/system/mysql.service.d echo "[Service]" > /lib/systemd/system/mysql.service.d/limit.conf echo "LimitNOFILE=10000" >> /lib/systemd/system/mysql.service.d/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
3. Проверим лимиты:
# 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)
Отлично, это то, что нам нужно.
На этом все, до скорых встреч. Если у Вас возникли вопросы или Вы хотите чтобы я помог Вам, то Вы всегда можете связаться со мной разными доступными способами.
Профессионально занимаюсь системным администрированием Linux -серверов и баз данных (MySQL, PostgreSQL) на протяжении последних 24 лет.
Блестяще.
Спасибо
Спасибо за разбор — помогло!
Спасибо, отлично пояснили, как проверить подхватился ли файл который создали.
спасибо, очень помогло!