Мы запустили сайт (Moodle), который в настоящее время пользователи находят медленным. Я думаю, что отследил проблему, создав MySQL временные таблицы на диске. Я наблюдаю переменную created_tmp_disk_tables
в администрировании сервера Mysql Workbench, и ее число увеличивается примерно на 50 таблиц / с. После дней использования created_tmp_disk_tables
> 100k. Кроме того, память, кажется, не освобождается. Использование продолжает расти, пока система не станет в значительной степени непригодной для использования, и мы должны перезапустить MySQL. Мне нужно перезапускать его почти каждый день, и он начинается с использования около 30-35% доступной памяти и заканчивает день с 80%.
У меня нет блобов в базе данных и нет контроля над запросами, поэтому я не могу попытаться оптимизировать их. Я также использовал Percona Confirguration Wizard для создания файла конфигурации, но my.ini также не решил мою проблему.
Вопросов
Что я должен изменить, чтобы MySQL не создавал временные таблицы на диске? Есть ли настройки, которые мне нужно изменить? Должен ли я бросить больше памяти на это?
Как я могу остановить MySQL от потребления моей памяти?
редактировать
Я включил slow_queries
журнал и обнаружил, что запрос SELECT GET_LOCK()
был зарегистрирован как медленный. Быстрый поиск показал, что я разрешил постоянные соединения в конфигурации PHP ( mysqli.allow_persistent = ON
). Я выключил это. Это уменьшило скорость, с которой MySQL потребляет память. Хотя он все еще создает временные таблицы.
Я также проверил, что key_buffer size
это достаточно большой. Я посмотрел на переменную key_writes
. Это должно быть ноль. Если нет, увеличьте. У key_buffer_size
меня есть ноль key_reads
и ноль, key_writes
поэтому я предполагаю, что key_buffer_size
он достаточно велик.
Я увеличил tmp_table_size
и max-heap-table-size
до 1024M, так как увеличение созданных_данных_данных может указывать на то, что таблицы не помещаются в памяти. Это не решило это.
Редактировать 2
Если вы видите много sort_merge_passes
в секунду в выходных данных SHOW GLOBAL STATUS, вы можете рассмотреть возможность увеличения sort_buffer_size
значения. У меня было 2 sort_merge_passes
в час, поэтому я считаю, что sort_buffer_size
достаточно большой.
Ссылка: Mysql Руководство по sort_buffer_size
Редактировать 3
Я изменил буферы сортировки и объединения в соответствии с предложением @RolandoMySQLDBA. Результат отображается в таблице ниже, но я думаю, что created_tmp_tables_on_disk
она все еще высока. Я перезапустил сервер mysql после того, как изменил значение и проверил значение created_tmp_tables_on_disk
через день (8 часов) и вычислил среднее значение. Любые другие предложения? Мне кажется, что что-то не подходит внутри какого-то контейнера, но я не могу понять, что это такое.
+---------------------+-------------+-------------+--------------------+
| Tmp_table_size, | Sort_buffer | Join_buffer | No of created |
| max_heap_table_size | | | tmp_tables on disk |
+---------------------+-------------+-------------+--------------------+
| 125M | 256K | 256K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 512K | 512K | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 1M | 1M | 100k/h |
+---------------------+-------------+-------------+--------------------+
| 125M | 4M | 4M | 100k/h |
+---------------------+-------------+-------------+--------------------+
Это моя конфигурация:
+-----------------------+-----------------------+
|DATABASE SERVER |WEB SERVER |
+-----------------------+-----------------------+
|Windows Server 2008 R2 |Windows Server 2008 R2 |
+-----------------------+-----------------------+
|MySQL 5.1.48 |IIS 7.5 |
+-----------------------+-----------------------+
|4 Core CPU |4 Core CPU |
+-----------------------+-----------------------+
|4GB RAM |8GB RAM |
+-----------------------+-----------------------+
Дополнительная информация
+--------------------+---------+
|PARAM |VALUE |
+--------------------+---------+
|Num of tables in Db |361 |
+--------------------+---------+
|Size of database |2.5G |
+--------------------+---------+
|Database engine |InnoDB |
+--------------------+---------+
|Read/write ratio |3.5 |
|(Innodb_data_read/ | |
|innodb_data_written)| |
+--------------------+---------+
|Avg table size |15k rows |
+--------------------+---------+
|Max table size |744k rows|
+--------------------+---------+
Эта настройка была дана мне, поэтому я ограничил контроль над ней. Веб-сервер использует очень мало ЦП и ОЗУ, поэтому я исключил эту машину как узкое место. Большинство настроек MySQL происходит из инструмента автоматической генерации конфигурации.
Я наблюдал за системой, используя PerfMon в течение нескольких представительных дней. Исходя из этого, я делаю вывод, что не ОС загружает диск.
My.ini
[client]
port=3306
[mysql]
default-character-set=utf8
[mysqld]
port=3306
basedir="C:/Program Files/MySQL/MySQL Server 5.1/"
datadir="D:/DBs/Data/"
default-character-set=utf8
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=125
query_cache_size=350M
table_cache=1520
tmp_table_size=125M
table-definition-cache= 1024
max-heap-table-size= 32M
thread_cache_size=38
MyISAM Specific options
myisam_max_sort_file_size=100G
myisam_sort_buffer_size=125M
key_buffer_size=55M
read_buffer_size=1024K
read_rnd_buffer_size=256K
sort_buffer_size=1024K
join_buffer_size=1024K
INNODB Specific options
innodb_data_home_dir="D:/DBs/"
innodb_additional_mem_pool_size=32M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=16M
innodb_buffer_pool_size=2G
innodb_log_file_size=407M
innodb_thread_concurrency=8
Ответы:
Глядя на
my.ini
меня, у меня есть два предложенияПРЕДЛОЖЕНИЕ № 1
Я бы поднял следующие настройки в вашем
my.ini
Это сделает несколько соединений и останется в памяти. Конечно, если a
JOIN
или aORDER BY
нужно больше4M
, он будет перенаправлять на диск в виде таблицы MyISAM.Если вы не можете войти как
root@localhost
, то перезапустите mysql сЕсли вы можете войти в систему как root @ localhost, вам не нужно перезапускать mysql, чтобы использовать эти настройки.
Просто запустите это в клиенте MySQL:
ПРЕДЛОЖЕНИЕ № 2
Поскольку ваши данные находятся на диске
D:
, у вас может быть дисковый ввод-вывод на дискеC:
.Пожалуйста, запустите этот запрос:
Поскольку я запускаю mysql на рабочем столе с настройками по умолчанию, мои временные таблицы записываются на диск
C:
. Если Drive D лучший диск , чем DriveC:
, возможно , вы можете отобразить временные таблицы на ДискеD:
, установив TMPDIR вmy.ini
следующим образом :Вам придется перезапустить mysql, поскольку tmpdir не является динамической переменной.
Попробуйте!
ОБНОВЛЕНИЕ 2013-11-29 10:09 EST
ПРЕДЛОЖЕНИЕ № 3
Учитывая тот факт, что MySQL работает в Windows, и вы не можете касаться запросов в основном пакете, у меня есть две идеи, которые нужно сделать вместе.
IDEA # 1: переместить базу данных на компьютер с Linux
Ты должен быть способен
IDEA # 2: перенастроить Moodle, чтобы он указывал на Linux-машину
Moodle был разработан для LAMP в первую очередь. Просто измените конфигурационные файлы так, чтобы они указывали на машину с Linux, а не на localhost.
Вот ссылка на старый документ Moodle 2.3 по настройке MySQL: http://docs.moodle.org/23/en/Install_Moodle#Create_an_empty_database
Я уверен, что последние документы также доступны.
Какой смысл переносить базу данных в Linux ???
Как это помогает ситуации с временными таблицами ???
Затем я бы предложил установить RAM-диск в качестве целевой папки для ваших временных таблиц.
Jan 04, 2013
: Есть ли движок MySQL или хитрость, чтобы избежать записи большого количества временных таблиц на диск?Dec 17, 2012
: Почему MySQL создает так много временных файлов MYD? (Актуальные инструкции)Nov 30, 2012
: Плохо ли создавать много временных таблиц mysql одновременно?Создание временной таблицы все еще будет происходить, но она будет записана в ОЗУ, а не на диск. сокращение дискового ввода-вывода.
ОБНОВЛЕНИЕ 2013-11-29 11:24 EST
ПРЕДЛОЖЕНИЕ № 4
Я бы предложил пересмотреть SUGGESTION # 2 с быстрым диском RAID-0 (32+ ГБ), настроив его как диск T: (T для Temp). После установки такого диска добавьте это в
my.ini
:MySQL перезапуск потребуется, используя
Кстати, я сказал RAID-0 специально, чтобы вы могли получить хорошую производительность записи по RAID-1, RAID-10. Настольный диск tmp - это не то, что я бы сделал избыточным.
Без оптимизации запросов, которые комментирует @RaymondNijland, вы никоим образом не можете уменьшить количество созданных временных таблиц.
SUGGESTION #3
иSUGGESTION #4
предложить ускорение создания временной таблицы и ввода-вывода временной таблицы в качестве единственной альтернативы.источник
Я отвечаю на свой вопрос здесь для полноты
Я выберу @RolandoMySQLDBA в качестве предпочтительного ответа, потому что он дал мне большинство советов, хотя на самом деле это не решило мою проблему.
Ниже приведены результаты моего расследования
Вывод
MySQL на Windows просто создает множество временных таблиц, и настройка MySQL путем изменения содержимого файлов конфигурации не помогла.
Детали
В таблице приведены параметры, которые я изменил в my.ini соответственно перед выполнением любых запросов. MySQL был перезапущен между каждым тестом.
Я использовал my.ini, найденный в исходном вопросе, в качестве шаблона, а затем изменил значение параметров один за другим в соответствии с таблицей ниже.
Я использовал JMeter для генерации 100 одновременных веб-запросов (которые представляли наше использование), повторенных 10 десять раз.
Test
Таким образом, каждый состоит из 1000 запросов. Это привело к последующим вызовам базы данных. Это показало, что MySQL будет создавать много временных таблиц независимо от того, какие параметры конфигурации мы изменили.* Среднее из трех запусков
На изображениях ниже показан объем памяти и ЦП, который необходим серверу базы данных для различных конфигураций. Черные линии указывают минимальное и максимальное значения, а синие полосы указывают начальное и конечное значения. Максимальная память была
4096M
как указано в вопросе.источник