2012-05-10 1 views
1

У меня есть таблица (InnoDB), которая вставлена, обновляется и читается часто (обычно в пачке в несколько миллисекунд). Я заметил, что иногда оператор SELECT, следующий за INSERT/UPDATE, получает устаревшие данные. Я предполагаю, что это связано с кешем, но после того, как он положил SQL_NO_CACHE, он ничего не делает.MySQL SQL_NO_CACHE не работает

Как вы убедитесь, что SELECT всегда ждет, пока предыдущий INSERT/UPDATE не закончит и не получит данные из кеша? Обратите внимание, что эти операторы выполняются из отдельных запросов (не в рамках одного и того же исполнения кода).

Может быть, я недоразумение, что на самом деле делает SQL_NO_CACHE ...

UPDATE:

@Uday, то INSERT, SELECT и UPDATE заявление выглядит следующим образом:

INSERT myTable (id, startTime) VALUES(1234, 123456)

UPDATE myTable SET startTime = 123456 WHERE id = 1234

SELECT SQL_NO_CACHE * FROM myTable ORDER BY startTime

Я пробовал использовать транзакции без везения.

Больше UPDATE:

Я думаю, что это на самом деле проблема с INSERT, UPDATE не. Оператор SELECT всегда пытается получить последнюю строку, отсортированную по времени. Но поскольку INSERT не выполняет блокировку на уровне таблицы, возможно, что SELECT получит старые данные. Есть ли способ заставить блокировку на уровне таблицы при выполнении INSERT?

+0

Вы должны опубликовать образцы SELECT и UPDATEs .... – Uday

+1

Что [уровень изоляции] (http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html) - это вы с помощью? Это может произойти, если вы используете 'READ UNCOMMITTED' или 'dirty reads'. –

+0

@MarcusAdams Независимо от уровня изоляции по умолчанию для InnoDB, не уверен, что это отвечает на ваши вопросы. – pixelfreak

ответ

1

Кэш запросов не является проблемой. Записывает недействительность кеша.

MySQL дает приоритет записи и с уровнем изоляции по умолчанию (REPEATABLE READ), ваш SELECT должен будет дождаться завершения UPDATE.

INSERT можно обрабатывать по-разному, если у вас есть CONCURRENT INSERTS для MyISAM, также InnoDB использует блокировку записи, поэтому ему не нужно ждать вставок в конце таблицы.

Это может быть состояние гонки? Вы уверены, что ваш SELECT появился после UPDATE? Вы читаете с реплицированного сервера, где, возможно, обновление еще не было распространено?

Если проблема связана с одновременным INSERT, вы должны отключить CONCURRENT INSERT на MyISAM или явно заблокировать таблицу с помощью LOCK TABLES во время INSERT. Решение такое же для InnoDB, явно заблокируйте таблицу INSERT с помощью LOCK TABLES.

+0

@pixelfreak, я только что обновил свой ответ о INSERT. Вам нужно либо отключить эту функцию с помощью MyISAM, либо явно заблокировать таблицу с помощью LOCK TABLES. –

+0

Marcus, я использую InnoDB, а не MyISAM – pixelfreak

+0

@pixelfreak, InnoDB использует блокировку записей, поэтому SELECT не блокируются вставками в конце таблицы. Решение такое же. Используйте LOCK TABLES для явной блокировки таблицы при вставке. Извините, я обновлял свой ответ, когда я тоже был, и, хотя вы сказали, что ваш UPDATE был проблемой, а не INSERT. :) –

0

A)
Если вам вообще не нужно кэшировать (для любого SELECT), полностью отключите кэш .

B)
Если вы хотите, чтобы это только для одной сессии, вы можете сделать это, как «сеансового query_cache_type = 0;» который установит это для этого сеанса .

использовать SQL_NO_CAHCE дополнительно в любом случае.

+0

1) Добавьте еще один столбец, например, «update», по умолчанию как 0 2) Сделайте его 1, добавив обновление itslef. В SELECT дополнительно используйте условие WHERE update = 1. – Uday

Смежные вопросы