У меня есть большое количество ограничений для открытых файлов в MySQL.
Также у меня низкий трафик и максимальные одновременные соединения около 30, и ни один запрос не имеет более 4 подключений.
Ответ 3
MySQL не должен открывать много файлов, если вы не установили смехотворно большое значение для параметра table_cache
(по умолчанию 64, максимальный - 512 КБ).
Вы можете уменьшить количество открытых файлов, выполнив команду FLUSH TABLES
.
В противном случае соответствующее значение table_cache
можно приблизительно оценить (в Linux), выполнив strace -c
для всех потоков MySQLd. Вы получаете что-то вроде:
# strace -f -c -p $( pidof mysqld )
Process 13598 attached with 22 threads
[ ...pause while it gathers information... ]
^C
Process 13598 detached
...
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
58.82 0.040000 51 780 io_getevents
29.41 0.020000 105 191 93 futex
11.76 0.008000 103 78 select
0.00 0.000000 0 72 stat
0.00 0.000000 0 20 lstat
0.00 0.000000 0 16 lseek
0.00 0.000000 0 16 read
0.00 0.000000 0 9 3 open
0.00 0.000000 0 5 close
0.00 0.000000 0 6 poll
...
------ ----------- ----------- --------- --------- ----------------
... и посмотреть, есть ли разумная разница в воздействии на вызовы open() и close(); это те вызовы, на которые влияет table_cache
, и влияющие на количество открытых файлов в любой заданной точке.
Если влияние open()
незначительно, то, во всяком случае, уменьшить table_cache
. Это в основном необходимо для медленных IOSS'ов, и их не так много.
Если вы работаете в Windows, вам придется попытаться использовать ProcMon от SysInternals или какой-то другой инструмент.
Когда у вас есть table_cache
для управляемых уровней, ваш запрос, который теперь открывает слишком много файлов, просто закроет и снова откроет многие из этих же файлов. Возможно, вы заметите влияние на выступления, которые, по всей вероятности, будут незначительными. Скорее всего, меньший кеш таблицы может быстрее получить результаты, так как выборка из современного, быстрого кеша IOSS может быть быстрее, чем поиск в действительно большом кеше.
Если вы хотите оптимизировать свой сервер, вы можете посмотреть эту статью. Вывод заключается в том, что по мере того, как кэши идут, больше не всегда лучше (это также относится к индексированию).
Проверка конкретного запроса в Linux
В Linux вы можете использовать strace (см. выше) и проверить, какие файлы открыты и как:
$ sudo strace -f -p $( pidof mysqld ) 2>&1 | grep 'open("'
Между тем из другого терминала я запускаю запрос и:
[pid 8894] open("./ecm/db.opt", O_RDONLY) = 39
[pid 8894] open("./ecm/prof2_people.frm", O_RDONLY) = 39
[pid 8894] open("./ecm/prof2_discip.frm", O_RDONLY) = 39
[pid 8894] open("./ecm/prof2_discip.ibd", O_RDONLY) = 19
[pid 8894] open("./ecm/prof2_discip.ibd", O_RDWR) = 19
[pid 8894] open("./ecm/prof2_people.ibd", O_RDONLY) = 20
[pid 8894] open("./ecm/prof2_people.ibd", O_RDWR) = 20
[pid 8894] open("/proc/sys/vm/overcommit_memory", O_RDONLY|O_CLOEXEC) = 39
... это файлы, которые использовали запрос (* обязательно запустите запрос на "холодный запуск" MySQL для предотвращения кеширования), и я вижу, что старший дескриптор файла был равен 39, point было более 40 открытых файлов.
Те же файлы можно проверить из /proc/ $PID/fd или из MySQL:
select * from performance_schema.file_instances where open_count > 1;
но счетчик MySQL немного короче, он не учитывает дескрипторы сокетов, файлы журналов и временные файлы.