SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 17.03.2008 17:02:37

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Торможение MyISAM при вставке/обновлении

Как-то даже не задумывался, блокируются ли таблицы MyISAM при вставке и обновлении данных, но я так понимаю, что всё же блокируются?

Обратил внимание, что селекты не могут достучаться до базы, глянул в процессы - там туча апдейтов валит. Апдейтов и инсертов бывает и по несколько штук в секунду, а среднее нормальное время выполнение селектов - 1.5-3 секунды. Вот как они там в это время доступом делятся - ума не приложу. Приоритет у апдейтов понижен. Подскажите пилюли от сей болезни.

Ещё как-то заметил торможение базы в арифметической прогрессии в зависимости от продолжительности работы. Через сутки после рестарта, запросы выполняются раза в 3-4 дольше, при чём такое наблюдается только на активной таблице. Никак не могу понять с чем это связано sad По выделению памяти в конфиге уже такие большие цифры поставил, что поднимать их совесть не позволяет smile Хелпните плз...

Отредактированно Neval (17.03.2008 17:03:09)


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#2 17.03.2008 18:07:16

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Блокируются. В MyISAM table-based locking. Как лечение можно преобразовать в INNODB. INSERT в конец таблицы можно ускорить с помощью concurrent_insert=1 http://dev.mysql.com/doc/refman/5.1/en/ … serts.html

Смотрите SHOW STATUS когда тормозит; важно какие именно кэши заполняются.

Неактивен

 

#3 17.03.2008 18:55:12

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

InnoDB не подходит из-за скорости выборок. В моём случае это самый важный аргумент.

Ок, спасибо за направление, буду пробовать.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#4 18.03.2008 00:49:47

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Торможение MyISAM при вставке/обновлении

Попробуйте использовать запросы на изменение данных с модификатором LOW_PRIORITY  - тогда запросы на выборку будут обладать более высоким приоритетом

Неактивен

 

#5 18.03.2008 10:08:42

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

Попробуйте использовать запросы на изменение данных с модификатором LOW_PRIORITY

У меня сервер стартует с этим параметром + ещё опцию в SQL выполняю при каждом коннекте.

Вот сейчас запросы выполняются примерно в 2.5 раза дольше, чем после старта сервера. Сервер работает всего 15 часов.

rgbeast написал:

Смотрите SHOW STATUS когда тормозит; важно какие именно кэши заполняются.

Глянул статус. Много переменных, много больших значений... Привожу некоторые, имхо, нужные. Разъясните где что плохо:

Created_tmp_files                    17
Created_tmp_tables                   7 

Handler_read_rnd_next           125
Handler_write                         251

Key_blocks_not_flushed          917
Key_blocks_unused           199599
Key_blocks_used              260955
Key_read_requests      153251297
Key_reads                        617834
Key_write_requests         5820343
Key_writes                      1477956

Open_files                              566
Open_tables                           471

Qcache_free_blocks                428
Qcache_free_memory   132655904
Qcache_hits                        13905
Qcache_inserts                    25489
Qcache_lowmem_prunes             0
Qcache_not_cached             49509
Qcache_queries_in_cache       1295
Qcache_total_blocks               3095
Questions                         1031795

Table_locks_immediate       669007
Table_locks_waited             359473

Threads_cached                          8
Threads_connected                    13
Threads_created                        34
Threads_running                        13

Также сразу приведу вырезку из конфига:
skip-locking
key_buffer_size =                   512M
max_allowed_packet =             16M
table_cache =                            2K
sort_buffer_size =                  256M
join_buffer_size =                  256M
net_buffer_length =                 16K
read_buffer_size =                   16M
read_rnd_buffer_size =             64M
myisam_sort_buffer_size =      512M
ft_min_word_len =                       2
tmp_table_size =                    128M
query_cache_size =                128M
query_cache_limit =                   4M
bulk_insert_buffer_size =          64M
myisam_max_sort_file_size =   10G
max_connection =                    512
thread_cache_size =                  16

Цифры ставил в основном из соображений красных значений при показе текущего состаяния базы через phpMyAdmin + сравнивал с my-large.ini.

Понимаю, могут быть кривые идексы с запросами, но торможение-то по идее не должно быть вот так, в зависимости от продолжительности работы сервера :\


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#6 18.03.2008 11:07:15

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Плохо вот это:
Table_locks_immediate       669007
Table_locks_waited             359473
Около трети апдейтов не получают lock сразу.

Еще интересно
show status like '%select%';

show status like 'com%';

Вроде у Вас кэши незаполнены. Попробуйте загрузить индексы в кэш напрямую для каждой таблицы LOAD INDEX INTO CACHE mytable; как написано в статье (это уменьшит фрагментацию):
http://sqlinfo.ru/articles/info/3.html

Неактивен

 

#7 18.03.2008 11:43:12

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

Да, по состоянии базы в phpMyAdmin я видел красные цифры в описании аля "Около трети апдейтов не получают lock сразу", но не знаю с чем это может быть связано. Если порассуждать, стандартный запрос, используемый в проекте занимает 1.5-3 секунды, а значит и для апдейта нужно дожаться его выполнения, как я понимаю?

Вот результат show status like 'com%':
Com_select                            2
Com_set_option                     4
Com_show_charsets               1
Com_show_collations              1
Com_show_databases             1
Com_show_grants                  1
Com_show_status                   1
Com_show_variables              3
Compression                      OFF

Все остальные значения равны нулю.

show status like '%select%':
Select_full_join                        0
Select_full_range_join              0
Select_range                           0
Select_range_check                 0
Select_scan                             7

Попробуйте загрузить индексы в кэш напрямую для каждой таблицы LOAD INDEX INTO CACHE mytable; как написано в статье

У меня по данной статье ещё ранее возник вопрос, вот как раз самое время его задать)))
Этот индекс нужно загружать постоянно при каждом коннекте? Если да, то не будет ли это излишне загружать базу, при наличии 50 одновременных коннектов?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#8 18.03.2008 11:48:21

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Вы привели статистику сразу после перезагрузки сервера. Приведите ее после того, как сервер поработает какое-то время.

Загружать ключи один раз после каждой перезагрузки mysql-сервера. Можно написать sql-скрипт и вписать его в my.cnf init-file=/путь/к/файлу.sql

Неактивен

 

#9 18.03.2008 11:54:46

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

rgbeast написал:

INSERT в конец таблицы можно ускорить с помощью concurrent_insert=1

Всегда и было concurrent_insert=1.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#10 18.03.2008 11:59:54

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

rgbeast написал:

Вы привели статистику сразу после перезагрузки сервера. Приведите ее после того, как сервер поработает какое-то время.

Я тоже так сначала подумал, ибо цифры маленькие, но это действительно после 16ти часов работы. Хотя сравнил с только-что запущенным сервером, все значения (com% и %select%) те же.

rgbeast написал:

Загружать ключи один раз после каждой перезагрузки mysql-сервера. Можно написать sql-скрипт и вписать его в my.cnf init-file=/путь/к/файлу.sql

Спасибо, сейчас сделаю.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#11 18.03.2008 12:16:44

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Выполните:
SHOW GLOBAL STATUS LIKE '%select%';
SHOW GLOBAL STATUS LIKE 'com%';

Предыдущий запрос давал статистику сессии

Неактивен

 

#12 18.03.2008 12:24:57

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

ммм, дейсвительно... Ок, вечерком тогда отпишусь, когда тормоза начнутся smile

А такой вопрос.. а можно ли создать репликацию (синхронизацию) баз в пределах одного физического сервера?
Я так понимаю, в моём случае репликация поможет, но сервер пока только один)))


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#13 18.03.2008 12:45:14

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

варианты
1. запустить два mysqld на одной машине на разных портах и настроить репликацию - учитывайте, что она не будет синхронной, UPDATE слейва будет запаздывать и, кроме того, все UPDATE будут выполняться на обоих серверах

2. перепроектировать приложение, чтобы SELECT не делался из той таблицы, в которую идет UPDATE (опять же не будет полной актуальности), например для SELECT можно использовать MEMORY-таблицу

Неактивен

 

#14 18.03.2008 12:56:04

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

А первый вариант присутствует в ситуации с репликацией на двух серверах?

Второй вариант интересный. Я так понимаю, это должна быть копия таблицы, в которую идут апдейты... Но таблица не маленькая, сейчас в ней уже 4.2М записей общим объёмом на 350Мб данных. На сколько реально хранить столько данных постоянно в памяти? К тому же, это далеко не лимит сей таблицы.

Актуальность 2х минут - не критична, 15 минут - это уже критично.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#15 18.03.2008 13:08:11

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Репликация - это фактически тиражирование апдейтов от мастера на слейвы. Апдейты выполняются сначала на мастере, а затем реплицируются на слейвы, задержка сама по себе не большая (миллисекунды), но учитывая Вашу ситуацию апдейты могут и на слейве выстроиться в очередь.

Посмотрите, можете ли Вы себе позволить просто раз в 10 минут пересоздавать MEMORY-таблицу.
DROP TABLE mem_tbl;
CREATE TABLE mem_tbl ENGINE=MEMORY SELECT * from tbl;

Посмотрите сколько памяти съест (память все-таки недорогая, можно докупить несколько гигов).

Насколько инфа в таблице новая? Можно ли часть инфы, ставшей архивом и не подлежащей изменению вынести в отдельную таблицу?

Неактивен

 

#16 18.03.2008 13:10:12

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

Сейчас присутствует торможение на 70% примерно, вот статусы:

Select_full_join 0
Select_full_range_join 0
Select_range 207
Select_range_check 0
Select_scan 229

=====

Com_insert_select 0
Com_change_db 254
Com_select 583
Com_set_option 313
Com_show_binlog_events 0
Com_show_binlogs 15
Com_show_charsets 27
Com_show_collations 27
Com_show_databases 27
Com_show_grants 11
Com_show_open_tables 1
Com_show_tables 16
Com_show_variables 94
Com_update 4596

Вижу много апдейстов по последнему значений. Что ещё здесь критично?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#17 18.03.2008 13:21:09

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Может и нормально, а может запросы SELECT слишком убойные. Еще попробуйте OPTIMIZE TABLE имя_таблицы
Innodb точно не поможет? Соотношение UPDATE/SELECT явно не в пользу SELECT.

http://dev.mysql.com/doc/refman/5.1/en/ … lect_range

Select_range
The number of joins that used ranges on the first table. This is normally not a critical issue even if the value is quite large.

Select_scan
The number of joins that did a full scan of the first table.

Неактивен

 

#18 18.03.2008 13:26:04

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

rgbeast написал:

Посмотрите, можете ли Вы себе позволить просто раз в 10 минут пересоздавать MEMORY-таблицу.
DROP TABLE mem_tbl;
CREATE TABLE mem_tbl ENGINE=MEMORY SELECT * from tbl;

Примерно через 5 секунд получаю ответ: #1114 - The table 'mem_tbl' is full. Чё-нибудь увеличить в конфиге?

rgbeast написал:

Насколько инфа в таблице новая? Можно ли часть инфы, ставшей архивом и не подлежащей изменению вынести в отдельную таблицу?

Скажем там, архивной инфы нет, вся актуальная и запрашиваемая, но вот поля апдейтов задумываюсь вынести в отдельную таблицу.
Сейчас за один апдейтовый запрос изменяется несколько десятков записей по некоторым условиям. Но если апдейтить эти поля в другой таблице, то это добавит очень много селектов на текущую, чтобы выявить ПК каждой нужной записи.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#19 18.03.2008 13:35:31

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

rgbeast написал:

Может и нормально, а может запросы SELECT слишком убойные.

Селекты не кислые, джоины 6-8 таблиц с группировками. Да и с индексами ещё не полностью определился. Я просто не могу понять почему скорость базы замедляется в арифметической прогрессии.

rgbeast написал:

Еще попробуйте OPTIMIZE TABLE имя_таблицы

Раз в сутки делаем smile

rgbeast написал:

Innodb точно не поможет? Соотношение UPDATE/SELECT явно не в пользу SELECT.

Сложно сказать о соотношении. Большое количество планируется и того и другого, можно сказать, что 50/50. Да и сами селекты, как я писал выше, не простые.

Сейчас имеем
Select_range 269 
Select_scan 579


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#20 18.03.2008 13:37:55

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Примерно через 5 секунд получаю ответ: #1114 - The table 'mem_tbl' is full. Чё-нибудь увеличить в конфиге?

max_heap_table_size=1G

Сейчас за один апдейтовый запрос изменяется несколько десятков записей по некоторым условиям. Но если апдейтить эти поля в другой таблице, то это добавит очень много селектов на текущую, чтобы выявить ПК каждой нужной записи.

Может быть и лучше из-за разделения SELECT/UPDATE.

Оптимизация дело творческое

Неактивен

 

#21 18.03.2008 14:00:01

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

Добавил в конфиг
max_heap_table_size=1G

Теперь имею (на многих запросах) ответ:

#5 - Out of memory (Needed 67108836 bytes)

ну и есессно байты в каждом запросе свои.

Отсюда вопрос. Цифры из моего конфига я приводил, какие из них есть смысл уменьшить?


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#22 18.03.2008 14:11:04

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

key_buffer используется только половина, можно уменьшить до 70% (правда попробуйте сначала загрузить все индексы с помощью LOAD KEY INTO CACHE)

query_cache вероятно можно отключить совсем, так как запросы уникальные, а таблицы меняются, попробуйте

Установите tmp_table_size = 8M - mysql юзает память для временных таблиц, если таблица влезает в min(max_heap_table_size, tmp_table_size). По умолчанию heap - 16M, tmp_table - 32M. Вы увеличили heap, следовательно лимит временных таблиц вырос с 16 до 32 мегов. Вероятно временные таблицы не спасают Ваши запросы все равно.

http://dev.mysql.com/doc/refman/5.1/en/ … table_size


Обратите внимание, что некоторые буфферы выделяются для каждого подключения, поэтому цифры ниже указаны несколько щедро (64M может хватить)
sort_buffer_size =                  256M
join_buffer_size =                  256M
myisam_sort_buffer_size =      512M

Неактивен

 

#23 18.03.2008 14:31:28

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

rgbeast написал:

правда попробуйте сначала загрузить все индексы с помощью LOAD KEY INTO CACHE

В том-то и дело, что если загрузить индексы, то начинается ругаться на отсутствие памяти)))
Сейчас проделаю всё остальное.


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

#24 18.03.2008 14:37:46

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Торможение MyISAM при вставке/обновлении

Кстати, буфер в конфиге, в том числе сессионный не приводит к выделению памяти, пока она не потребуется. Скажем myisam_sort_buffer_size =      512M может ни к чему не приводить, но потом найдется запрос, который догадается как использовать этот буффер и он его использует с результатом No memory.

Если память узкое место, проще всего купить еще 2-4 гига. Время программиста дорого, проще купить железо.

Неактивен

 

#25 18.03.2008 14:42:24

Neval
Гуру
Откуда: Киев
Зарегистрирован: 11.03.2008
Сообщений: 449

Re: Торможение MyISAM при вставке/обновлении

Всё-таки после применения LOAD KEY INTO CACHE, некоторые запросы не выполняются из-за нехватки памяти sad

Сейчас в конфиге имею такие записи:
skip-locking
key_buffer_size = 384M
max_allowed_packet = 16M
max_heap_table_size = 1G
table_cache = 2K
sort_buffer_size = 64M
join_buffer_size = 64M
net_buffer_length = 16K
read_buffer_size = 16M
read_rnd_buffer_size = 64M
myisam_sort_buffer_size = 64M
ft_min_word_len = 2
tmp_table_size = 8M
bulk_insert_buffer_size = 64M
myisam_max_sort_file_size = 10G
max_connection = 512
thread_cache_size = 16

Так, в общем, из данной дискуссии можно сделать выводы, что всё же апдейты нужно перенаправить на другую таблицу.


ЗЫ Сейчас на сервере установлено 4Гб памяти.

Отредактированно Neval (18.03.2008 14:43:57)


Человек без чувства юмора - не серьёзный человек wink

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson