繁体   English   中英

MySQL MyISAM / InnoDB更新不是两个连接之间的原子更新(强制写入?)

[英]MySQL MyISAM/InnoDB updates are not atomic across two connections (force write?)

更新:我们尝试将数据库简单地转换为InnoDB,但是我们仍然遇到相同的问题。 autocommit已开启。 是否可能需要一些其他语句来确保更改可以被另一个连接看到?

更新2:我们通过将表设置为InnoDB 并将全局事务隔离级别设置为SERIALIZABLE来使事情正常运行,但是这明显降低了事情的速度。 同样,并非所有人都完全相信这已经解决了问题,因为减速可能只是给了竞争条件足够的时间以适当的顺序执行。 无论如何,我们将继续进行调查。


我在MySQL中遇到一个问题,该问题是无法立即从另一个连接(恰好是SOLR更新查询)看到从一个连接进行的写操作。

就像这样:

  1. 用户在Web应用程序中进行更改。
  2. 我们记下当前的修订号r1。
  3. MySQL表(MyISAM)包含更改和下一个修订版r2。 [在代码的这一点上,更改应该已经写入数据库,如果再次从同一连接中查询它,我们将看到它。]
  4. 我们通过HTTP向Solr发出信号,以使用修订版r1进行自我更新。
  5. Solr(通过不同的连接)向MySQL查询更改> r1,但未获取在步骤3中刚刚写入的更改。

这是预期的/正常的行为吗? 我在文档中找不到任何暗示更新不是跨连接原子的内容。 请记住,在发出第二个连接更新信号的那一点上,更改应该已经写入数据库中。

如果这是正常行为,则必须采用某种方法强制MySQL将其连接写/刷新回磁盘以强制原子操作,并保证其他连接将看到更改。 但是,同样,对于MyISAM表,我找不到任何提及。

我还应该补充一点,如果我在第3步和第4步之间明确放置了短暂的延迟(1-2秒),则一切正常。

以下是我们正在运行的MySQL版本:

mysql-server-5.1.66-2.el6_3.x86_64
php-mysql-5.3.3-14.el6_3.x86_64
mysql-libs-5.1.66-2.el6_3.x86_64
mysql-5.1.66-2.el6_3.x86_64

MyISAM不会刷新到磁盘,它会写入文件系统缓冲区,并且操作系统最终会负责写入磁盘。

但是无论如何,即使另一个查询,即使在另一个会话中,也应该能够立即读取MyISAM数据,即使该查询是从文件系统缓冲区中读取的也是如此。 该部分对于mysqld进程应该是透明的。

MyISAM中也没有事务隔离,因此不存在未提交的更改。 无论事务隔离模式如何,任何会话都应该能够读取针对MyISAM表的所有完成的更改。

因此,如果您使用MyISAM表,那么您描述的步骤(第5步看不到r2的更改)将永远不会发生。 因此,我想您会误解操作的顺序,而您实际上是在尝试读取尚未进行的更改。

无论如何,这是有争议的,因为您确实应该使用InnoDB。 然后,事务隔离确实很重要。 您可能希望事务隔离为READ-COMMITTED ,它不会像SERIALIZABLE那样阻止并发,但是它确实允许事务查看任何数据的最新版本。 也就是说,如果您提交更改,并且Solr使用的是READ-COMMITTED,那么Solr应该立即看到更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM