mysql - InnoDB并发读写

标签 mysql locking innodb read-write

我想了解 InnoDB 如何处理多个并发读/写操作。 考虑以下场景: 您正在执行相当密集的批量写入。任何传入的读取请求都必须等待批量写入完成。在此期间,还会对表提出写请求。所以当批量写入完成时,有多个读请求和写请求待处理。 innodb 将按照什么顺序解决请求。在大多数情况下,我更愿意从表中获取最新的结果集。因此,等待写入请求将是一种方法,但这可能会导致读取请求匮乏。 所有写入请求都是非更新行请求。我认为更新请求需要行级锁,而插入请求需要表级锁。

您能解释一下这在 InnoDB 中是如何发生的吗? 谢谢

最佳答案

在 InnoDB 中,INSERT 不会获取表锁。 (MyISAM 是一个不同的故事。)

粗略地说,每次读取或写入 InnoDB 表只会锁定所需的行。如果一个查询的行与另一个查询的行之间不存在重叠,则无需等待。一些使其“大致”的问题:

  • 有些锁是“间隙”锁。想象一下在两个现有行之间插入一个新行。
  • 共享读锁(同一行)不会互相阻塞
  • 独占锁的作用有点像您所描述的。

“MVCC”允许多个事务“查看”同一行的不同版本。假设一个事务正在选择一行,而另一个事务正在更新它。在两个事务完成之前,该行实际上有两个版本。在两个事务COMMITedROLLBACKed之后,事情就会被清理。

所有这些行级锁定和检查的成本都很高,这可能毫无值(value)。如果有数十个连接正在运行,它们都会变慢。在旧版本中,4-8 个连接是实际限制。对于 5.7,大约可以处理 64。不过,InnoDB 每秒可以处理数千个事务,最终受到缓慢的磁盘 I/O 的限制。

“批量插入”——如果您真正的意思是 INSERT 到单个表中,那么最好创建包含 100-1000 个的单个 INSERT 语句行。这减少了通信、解析、优化和事务开销的开销。它还增加了读取冲突的风险,但加速(通常)超过了冲突延迟。

一定要在每个 InnoDB 语句之后检查错误。可能会发生死锁。一般来说,它们是通过ROLLBACK加上重新运行BEGIN...COMMIT来处理的。

关于mysql - InnoDB并发读写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30176326/

相关文章:

mysql - SQL - 按 "human"相关性排名或排序

mysql - 用于大型数据集的 sqlite 或 mysql

java - 比较 arraylist 值并更新 MySQL

mysql 比较同一个表中的列

MySQL 在字符串的开头/结尾处搜索和替换

php - 限制一个脚本一次使用表的行数

c# - 在多个线程之间共享一个 List<T>

c# - 为什么需要冗余锁对象?

mysql - 为什么 MIN() 查询比 ORDER BY X LIMIT 1 慢?

mysql - 如果不存在则插入行而不会出现死锁