Ми запускаємо сайт (Moodle), який користувачі наразі знаходять повільно. Я думаю, що я простежив проблему в MySQL, створюючи тимчасові таблиці на диску. Я спостерігаю за змінною created_tmp_disk_tables
в адміністрації сервера Mysql Workbench, і кількість збільшується приблизно з 50 таблиць / с. Після використання днів, created_tmp_disk_tables
становить> 100k. Також, схоже, пам'ять не звільняється. Використання постійно збільшується, поки система не стане майже непридатною, і нам доведеться перезапустити MySQL. Мені потрібно знову запускати його майже щодня, і це починається з використання приблизно 30-35% доступної пам'яті і закінчує день на 80%.
У мене немає баб у базі даних і ніякого контролю над запитами, тому я не можу намагатися їх оптимізувати. Я також використовував майстер конфігурації Percona для створення файлу конфігурації, але мій.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
до 1024М, оскільки збільшення create_tmp_disk_tables може вказувати на те, що таблиці не можуть вміститися в пам'яті. Це не вирішило.
Редагувати 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