MySQL SQL_NO_CACHE无效

时间:2012-05-10 15:18:51

标签: mysql node.js innodb

我有一个表(InnoDB)可以经常插入,更新和读取(通常以几毫秒的间隔)。我注意到有时INSERT / UPDATE后面的SELECT语句会得到过时的数据。我认为这是由于缓存,但在将SQL_NO_CACHE放在它之前并没有真正做任何事情。

如何确保SELECT始终等到上一次INSERT / UPDATE完成而不从缓存中获取数据?请注意,这些语句是从单独的请求执行的(不在相同的代码执行中)。

也许我误解了SQL_NO_CACHE实际上做了什么......

更新

@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

我尝试过没有运气的交易。

更多更新

我认为这实际上是INSERT的一个问题,而不是UPDATE。 SELECT语句总是尝试获取按时间排序的最新行。但由于INSERT不执行任何表级锁定,因此SELECT可能会获取旧数据。有没有办法在执行INSERT时强制表级锁定?

2 个答案:

答案 0 :(得分:1)

查询缓存不是问题。写入使缓存无效。

MySQL优先考虑写入并使用默认隔离级别(REPEATABLE READ),您的SELECT必须等待UPDATE完成。

如果为MyISAM启用CONCURRENT INSERTS,则可以区别对待INSERT,InnoDB也使用记录锁定,因此不必等待表末尾的插入。

这可能是一场竞争条件吗?你确定你的SELECT在UPDATE之后发生了吗?您是否从可能尚未传播更新的复制服务器进行读取?

如果问题在于并发INSERT,则需要在MyISAM上禁用CONCURRENT INSERT,或者在INSERT期间使用LOCK TABLES显式锁定表。对于InnoDB,解决方案是相同的,使用LOCK TABLES显式锁定INSERT上的表。

答案 1 :(得分:0)

A)
如果您根本不需要缓存(对于任何SELECT),请禁用查询 完全缓存。

B)
如果你想只在一个会话中使用它,你可以这样做 “set session query_cache_type = 0;”这将为此设置 特别会议。

在任何一种情况下都使用SQL_NO_CAHCE。