Есть ли способ выполнить низкоуровневые обновления в MySQL при использовании InnoDB?
Я запускаю приложение с очень высокой нагрузкой, где могут быть буквально тысячи пользователей, пытающихся одновременно обновлять одни и те же записи данных. Это в основном статистическая информация, основанная на сеансах, большая часть которой может быть проигнорирована, если есть время ожидания, связанное с запросом. Я хотел бы иметь возможность проверить, заблокирована ли какая-либо таблица/строка, и если это так просто не передать запрос на обновление на сервер. Возможно ли это?
Вы пытались установить low_priority_updates=1
в файл my.cnf? Это должно дать приоритет выбора запросов, если обновление или вставка в противном случае заблокировали бы таблицу.
Таким образом, ваше пользовательское приложение не ждет завершения обновления и не заботится о том, если оно не завершено, возможно, это будет подходящий контекст для использования менеджера фоновой обработки, такого как Gearman?
Если вы скажете, что с запросом существует ограничение по времени, вы можете использовать хранимую процедуру для пропуска определенных обновлений
Что-то вроде этого:
DELIMITER $$
DROP PROCEDURE IF EXISTS `updateStats` $$
CREATE PROCEDURE updateStats ()
BEGIN
DECLARE _B smallint(1) DEFAULT 0;
DECLARE _SECONDS INT DEFAULT 1;
-- http://dev.mysql.com/doc/refman/5.0/en/lock-tables-and-transactions.html
SELECT GET_LOCK('myLabel1',_SECONDS) INTO _B;
IF _B = 1 THEN
UPDATE table SET ........;
SLEEP(_SECONDS);
SELECT RELEASE_LOCK('myLabel1') INTO _B;
END IF;
END
Это гарантирует, что если у вас есть блокировка, которая длится _SECONDS, вы убедитесь, что никакая другая процедура не запускает тот же код в этом временном кадре. Сон необходим, чтобы держать блокировку в течение 1 секунды (как если бы SP прекращался раньше, блокировка отпускается)
Вы также можете добавить else
node в if, чтобы его хранимая процедура не могла обновиться, чтобы выполнить собственный код, например, добавить в очередь.
Предположим, что вы хотите записать в живую таблицу только в интервале 1 секунду, чтобы не загружать ее слишком сильно, возможно, у вас на ней много индексов. На else node вы можете обновить вторую таблицу, которая действует как очередь, и очередь будет опущена в IF true node, когда вы также сделаете обновление.