На моей текущей работе возникла проблема с текущим сервером, на котором находится высоконагруженый сервис. Выгорело половина сервера, а значит процессор стал 8-ми ядерным из 16-ти и mysql, которая требовательна к ресурсу, перестала тянуть нагрузку. Было принято решение переехать на новый сервис. Переезд прошел удачно и я решил так же обновиться с mysql 5.5 до mysql 5.6 версии и тут я столкнулся со следующей проблемой…
Во первых апдейт я для начала провел на локальной машине, чтобы исследовать возможные проблемы и разницу в конфигурации. Я сразу же столкнулся с единственной ошибкой
Unknown system variable ‘table_cache‘
Быстро нагуглив, тчо ее название сменилось на table_open_cache я подправил конфиг. Все зарабтало, тесты прошли все. Далее я обновился на сервере и повозился с оптимизацией.
Для проведения нагрузочное тестирвоания на mysql я использовал утилиту sysbench.
Для начала подготавливается таблица на 500000 записей. Предварительно надо создать базу с именем sbtest.
1 2 3 |
sysbench --mysql-table-engine=innodb --oltp-table-size=500000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp prepare |
Потом выполняется тестирование
1 2 3 |
sysbench --num-threads=8 --max-requests=1000 --oltp-table-size=500000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp run |
Начиная с версии sysbench 0.5 надо указывать полный путь к oltp.lua. У меня на локалке это выглядит так
1 2 3 |
sysbench --num-threads=8 --max-requests=3000 --oltp-table-size=500000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=/usr/share/doc/sysbench/tests/db/oltp.lua run |
Далее я решил прогнать свою конфигурацию через mysqltuner и tuner-primer.sh утилиты. Советую устанавливать их не из репозиториев, а с офф. сайтов.
И тут я очень удивился, обе утилиты советовали увеличить лимит table_open_cache > 400. Однако в своем конфиге я имел такие значения.
open_files_limit = 30000
table_open_cache = 15000
table_open_cache_instances = 16
Я начал пробовать менять конфиг, перезагружать mysql, гуглить решение почему конфиг может не читаться и все бестолку. Тогда я нагуглил данный ответ
http://stackoverflow.com/questions/19705738/mysql-table-cache-refuses-to-change-value/28936292
Сейчас там уже написан мой ответ с решеним, до этого была только идея поискать локальные переопределния table_open_cache. Я их поискал
1 2 3 4 5 6 7 8 9 10 11 12 |
find / -type f -name *.cnf* /etc/mysql/debian.cnf /etc/mysql/conf.d/mysqld_safe_syslog.cnf /etc/mysql/conf.d/my5.6.cnf /etc/mysql/my.cnf /etc/texmf/fmt.d/50cyrtexinfo.cnf /etc/ssl/openssl.cnf /usr/share/doc/mysql-server-5.6/examples/my-default.cnf /root/.my.cnf /var/lib/mysql/auto.cnf |
И не нашел ничего такого. Сначала я пошел по ложному пути и пробовал изменить настройку innodb_open_files. Но как выяснилось – эта настройка высчитывается автоматически в зависимости от table_open_cache. Тогда я начал просто изучать всю конфигурацию mysql через mysqladmin variables и команды show status like %something%.
1 2 3 4 5 |
show global status like 'open_tables' ; | Open_tables | 400 | |
Ничего не меняется.
1 2 3 4 5 6 |
SHOW VARIABLES LIKE '%open%file%'; | innodb_open_files | 400 | | open_files_limit | 1024 | |
А вот это уже интереснее. Я же поставил open_files_limit = 30000. И тут меня осенило, что нет проблемы с конфигурацией mysql, а это проблема с операционной системой.
Быстро нагуглив debian open files limit я обнаружил, что мой системный soft limit стоит как раз на 1024!
Далее я выполнил настройку в файле
1 2 3 |
/etc/security/limits.conf |
И установил там такие лимиты
1 2 3 4 5 6 |
* hard nofile 500000 * soft nofile 500000 root hard nofile 500000 root soft nofile 500000 |
И чтобы не перезагружать сервер изменил настройку “на живом”.
1 2 3 |
ulimit -n 500000 |
Можно проверить так
1 2 3 4 |
ulimit -Sn # soft limit ulimit -Hn # hard limit |
После выполнения mysql restart конфигурация считалась и table_open_cache стал равен тому значению, которое я установил.
1 2 3 4 5 6 7 |
| innodb_open_files | 15000 | | open_files_limit | 500000 | | table_definition_cache | 2000 | | table_open_cache | 15000 | | table_open_cache_instances | 16 |