Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Сегодня выявил некоторую особенность блокировки. Чищу таблицу логов удаляя по 1000000 (миллион) записей, при этом сайт, работающий с той же БД периодически выдаёт ошибку "mysqli::mysqli(): (08004/1040): Too many connections", пока чисткой не занимался, ни разу такого сообщения никто не видел, но в момент чистки сообщение появляется очень часто.
При просмотре процессов в это же время вижу всего-лишь 2-3 десятка подключений.
1. Хотелось бы понимать зависимость и связь такого поведения, моя логика никак не может этого связать.
2. Ну и собссна как побороть? Уменьшить количество удаляемых записей за раз? Или какие-то конфиги подправить?
ЗЫ При чистке этой таблицы в неё так же активно идёт и запись в это же время.
ЗЫЫ Работаем с XtraDB Cluster через haproxy.
Неактивен
Что дают в этот момент команды:
Неактивен
Вторая команда выдаёт число, превышающее 100 млн и которое постоянно растёт, т.е. я так понимаю это количество отработанных подключений за время работы сервера.
Первая команда выдаёт 214. С такими цифрами я понимаю, что второе число теоритически не может быть меньше или равно первого
ЗЫ Команды запускал в обычном режиме, без описанной выше проблемы. Давайте разберёмся со второй командой и тогда можно будет мучать сервер
Неактивен
Прошу прощения, имел в виду
Неактивен
Дошли руки поэкспериментировать на продакшн сервере
Обе команды выдают 214. Что же получается, при удалении записей из таблицы она блокировалась вся целиком? Вставки в эту таблицу висели до тех пор, пока удаление не закончилось.
Неактивен
А какое удаление? Если удаляемые записи нельзя идентифицировать по первичному ключу, то блокируется вся таблица.
Неактивен
DELETE FROM `table` WHERE `timestamp`< 'YYYY-MM-DD'
PK в таблице имеется, индекс на `timestamp` тоже, само поле имеет тип TIMESTAMP.
Неактивен
Это применение индекса с нестрогим сравнением и не на первичном ключе, поэтому блокируется вся таблица. Вся таблица не будет блокироваться, если запрос будет вида WHERE id in (1,2,3,4). Кстати, не проблема его разбить на два: SELECT id и DELETE по id.
Неактивен
Хм, а ведь при выборке из InnoDB таблиц сначала определяется значение PK, а уже потом ищется запись по этому PK. При удалении такой подход, получается, не используется?
В моём случае записей сотни тысяч, не редко и 1-3 миллиона, вариант с дополнительной выборкой PK тут наверн не совсем подойдёт... Значит, остаётся вариант с уменьшением лимита записей, чтобы таблица блокировалась не на долго.
Неактивен
При удалении точно так же, но при блокировке не так. Это сделано для того, чтобы операция блокировки не была долгой - заблокировать миллион записей - очень большая потеря производительности (точнее не заблокировать, а создать новую версию для каждой из миллиона записей).
Неактивен
Не совсем понял суть последнего сообщения))) Я вижу такое поведение: при удалении записей у меня другие подключения при попытке записать в эту таблицу ждут, пока записи не удалятся.
Вот, нашли в мануале, что инсерты ждут только потому, что движок не знает какой PK им присвоить
http://dev.mysql.com/doc/refman/5.5/en/ … locks.html
DELETE FROM ... WHERE ... sets an exclusive next-key lock on every record the search encounters.
Отсюда вопрос, а если использовать не WHERE `id` IN (X,Y), а WHERE `id`<=X, фокус прокатит? Или надо проверять?
Неактивен
DELETE будет ставить xlock на каждую строку, которую он потрогает, на вторичном
ключе, по которому делается поиск, и на первичном ключе.
Конкретную проблему поможет полечить, разумеется, LIMIT 10000 и повторение до
победного конца
Неактивен
paulus написал:
DELETE будет ставить xlock на каждую строку, которую он потрогает, на вторичном
ключе, по которому делается поиск, и на первичном ключе.
Правильно, на каждую удаляемую строку, но инсерты тут при чём? Они ж в очередь все становятся и ждут когда же этот магазин уже откроет свои двери)))
Неактивен
Иногда Innodb считает, что лочить все записи, которые будут удаляться нецелесообразно и легче залочить всю таблицу. В мануале это не найдешь - нужно тестировать.
Неактивен
Страниц: 1