通过操作系统调度不需要的延迟UPDATE ?



我们遇到了一个非常奇怪的问题,不连接的并发PHP进程访问同一个表(使用表锁)。

不涉及复制,我们正在用PHP 5.6.40的mysql接口做一个单体(我知道,升级是时候了,我们正在努力)。

假设字段名的初始值"value">

PHP-Process 1: modify table

LOCK TABLE xyz WRITE;
UPDATE xyz SET value = 1;
UNLOCK TABLE xyz;

PHP-Process 2:取决于表中的值(例如检查访问权限)

SELECT value from xyz;

现在,如果我们设法使进程2停止并等待锁被释放,在本地开发环境(XAMPP, MariaDB 10.1.x)上,一切都很好,它将获得值1;

但是,在我们的生产服务器(DebianLinux, MySQL 5.6.x)上,值在查询结果中具体化似乎需要等待一段时间。

  • 立即SELECT语句输出0
  • 睡眠(1),然后SELECT传递1

我们总是假设a) LOCK/UNLOCK将刷新表或b)手动Flush Tables xyz WITH READ LOCK也将刷新缓存,强制写入磁盘,并且通常会确保每个其他进程的每个后续查询都将产生预期的结果。

我们已经尝试过了:

  • FLUSH TABLES如上所述-没有结果
  • 在执行SELECT语句之前显式地获取LOCK - no result
  • 只是等待一些时间-产生了我们正在寻找的结果,但这是一个肮脏,不可靠的解决方案。

你们觉得怎么样?原因是什么?我在想:查询缓存没有及时更新,底层操作系统的分页没有及时将内容写回磁盘/没有验证表数据的内存页。

你知道有什么方法可以绝对保证数据的连续一致性吗?

在不同的MariadB版本中默认有不同的事务隔离模式。

如果您期望得到相同的结果,则您已经设置了相同的模式。在不同的MySQL版本上测试它似乎也很奇怪。

https://mariadb.com/kb/en/mariadb-transactions-and-isolation-levels-for-sql-server-users/

你的第二个进程开始事务可能远远早于提交实际发出。如果你不想挖掘事务隔离,可以尝试在select之前执行rollback(但正确的解决方案是确定你的应用需要的隔离)。

Rollback; -- may give error, but it is okay.
SELECT value from xyz;

相关内容

  • 没有找到相关文章

最新更新