LINUX.ORG.RU

MySQL UPDATE лочит таблицу

 


0

3

есть myisam таблица, около 10 полей и 50 тыщь записей.

Делаю

UPDATE table SET int_field=555 WHERE primary_id=123

Таблица лочится на 5-30 сек. Следующие любые обновления с любыми id происходят меньше чем за 10 мс. Заметил от чего время апдейта прыгает - оно прыгает от времени последних ЛЮБЫХ обновлений в таблице. Если 10 мин прошло, то обновление около 2 сек занимает. 30 мин последнее обновление - 5-10 сек, сутки - 30 сек.

Из за чего такое может быть?

★★

есть myisam таблица
[…]
Таблица лочится на 5-30 сек.

Переделать эту таблицу в InnoDB — пробовали?

Из за чего такое может быть?

Много причин может быть.

Вы не указали какие именно данные хранятся в этой таблице.

Для начала, можно попробовать «оттюнить» саму mysql.

50 тысяч записей — это очень мало, и таких задержек быть не должно. Распишите подробнее про структуру таблицы. Нет ли там каких-либо полей с какими-нибудь много-мегабайтными-блобами в каждой записи? Или может сервер очень нагружен чем-то другим?

И хорошо-бы посмотреть на «пример строки». Вдруг для этого будет удобнее использовать более другу базу, вроде какого-нибудь монгодб…

anonymous
()
Ответ на: комментарий от visual

добавь Limit 1, посмотри что будет

Ничего нового, т.к. это primary

ex3me ★★
() автор топика
Ответ на: комментарий от anonymous

Переделать эту таблицу в InnoDB — пробовали?

Еще нет, это один из крайних случаев.

50 тысяч записей — это очень мало, и таких задержек быть не должно. Распишите подробнее про структуру таблицы. Нет ли там каких-либо полей с какими-нибудь много-мегабайтными-блобами в каждой записи? Или может сервер очень нагружен чем-то другим?


  `album_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `album_ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `artist_id` int(11) NOT NULL DEFAULT '0',
  `album_image` tinyint(1) NOT NULL DEFAULT '1',
  `album_name` varchar(256) CHARACTER SET utf8 NOT NULL,
  `genre_id` int(11) NOT NULL,
  `album_url` varchar(256) CHARACTER SET utf8 NOT NULL,
  `album_year` int(1) NOT NULL DEFAULT '0',
  `album_stat` tinyint(1) NOT NULL DEFAULT '0',
  `album_count` int(1) NOT NULL DEFAULT '0',
  `album_size` int(11) NOT NULL DEFAULT '0',
  `album_filesize` int(11) NOT NULL DEFAULT '0',
  `album_sort` int(11) NOT NULL DEFAULT '0',
  `album_other` varchar(32) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`album_id`),
  KEY `album_sort` (`album_sort`),
  KEY `artist_id` (`artist_id`),
  KEY `genre_id` (`genre_id`),
  FULLTEXT KEY `album_name` (`album_name`)

Да, сервер нагружен, В секунду выполняться может до 150 запросов, но эти запросы самые простые и выполняются менее чем за 5мс, да и запросы на 50% из кеша мускуля идут.. Да и это вроде как не должно никак повлиять... я так думаю:)

ex3me ★★
() автор топика
Последнее исправление: ex3me (всего исправлений: 1)
Ответ на: комментарий от gruy

Индексы имеются?

Индексов на 3мб всего накапало

ex3me ★★
() автор топика
Ответ на: комментарий от ex3me

Да, сервер нагружен, В секунду выполняться может до 150 запросов, но эти запросы самые простые и выполняются менее чем за 5мс, да и запросы на 50% из кеша мускуля идут.. Да и это вроде как не должно никак повлиять... я так думаю:)

Капитан очевидность говорит, что надо использовать InnoDB и мускуль если возможно посвежее.

anonymous
()
Ответ на: комментарий от ex3me

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

Vit ★★★★★
()
Ответ на: комментарий от ex3me

Попробуй убить все индексы кроме праймари и проверить вставки через период времени. Потом вернешь их.

BaBL ★★★★★
()
Ответ на: комментарий от ex3me

В конфиге мускуля key_buffer должен быть больше, чем сумморный объем индексов на все таблицы. Это именно для MyISAM.

Если помещается - посмотрите что с диском (хотя бы %wa в top). У вас небольшая нагрузка, мало данных, индексы правильные. Сам мускуль тупить не должен, если вы его конечно не на амазоновском микроинстансе гоняете.

Vit ★★★★★
()
Ответ на: комментарий от Vit

Дело не в индексах. Провел следующий эксперимент:

1. Создал копию таблицы в этой же базе.
2. Сделал замеры апдейта на обоих. (время различалось)
3. Сделал замеры апдейта на обоих через 12 часов опять 

Копия таблицы к которой не делают обращения: апдейтится очень быстро, без задержек,но всё же иногда проскакивает 0.5 сек. Откуда берется такое большое время ? После первого апдейта все остальные апдейты делаются за меннее 5мс.

Таблица к которой постоянно делаются обращения: Апдейтится через время с задержкам как я и писал. До полуминуты иногда.

Вывод - к таблице к которой обращаются, есть какой то кешь, который вероятно накапливается со временем, а в момент апдейта непонятно почему он может вычищаться до полуминуты.

Вопрос как это пофиксить?:)

ex3me ★★
() автор топика
Ответ на: комментарий от ex3me

Нету там кеша на запись, если delayed insert/update не используете. Посмотрите что с памятью и с диском.

Если не хотите думать, у вас путь только один - конвертить таблицы в innodb и переделывать полнотекстный поиск.

Vit ★★★★★
()
Ответ на: комментарий от Vit

если delayed insert/update не используете

Не использую

Посмотрите что с памятью и с диском.

А какая разница, если в такой же копии таблицы (к которой не делаются запросы) работает всё быстро. Память свободная есть, диск системный кроме как под мускул больше не используется. Да и опять же, 50% из кеша запросы идут. Апдейты идут в час еденицы, тоесть запись на диск минимальная. А когда начинает идти много апдейтов, то тормозит только первый, все остальное работает в приделах нормы

ex3me ★★
() автор топика

юзайте уже postgresql

quest ★★★★
()
Ответ на: комментарий от Vit

Проблема решена!

Значение query_cache_size = 1 000 000 000 (с копейками)

Из за этого, во время апдейта, часть кеша которая связана с затрагиваемой таблицей удалялась. Такое удаление (большое), хоть и из памяти, но становилось очень трудным.

Вот результат:

mysql> update album set album_filesize=111333046 where album_id=5156;
Query OK, 1 row affected (18.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SET GLOBAL query_cache_size = 0;
Query OK, 0 rows affected (0.35 sec)

mysql> update album set album_filesize=111333041 where album_id=5156;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Но в итоге значение поставил 100000 (все-же не миллиард:) ) - достаточно быстро отрабатывает, не более 0.02 сек

ex3me ★★
() автор топика
Ответ на: комментарий от ex3me

О как. Гиг это точно перебор. Обычно туда до 64 мегов ставят.

Вообще, вроде раньше к мускулю прилагались дефолтные конфиги для разного количества памяти. Вот лучше оттуда взять за основу, а потом крутить аккуратно.

Vit ★★★★★
()
Ответ на: комментарий от Vit

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

Так и было всё. Походу админу надоело править каждый раз, он и херакнул 1024М.

ex3me ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.