InnoDB并发读写

时间:2015-05-11 19:42:59

标签: mysql locking innodb read-write

我想了解InnoDB如何处理多个同时读/写操作。 考虑以下情况: 您正在执行非常激烈的批量写入。任何进入的读取请求都必须等到批量写入完成。在此期间,还要求在表格上写入请求。所以到那时,批量写入完成,有多个读取请求和写入请求待定。 innodb以什么顺序解决请求。在大多数情况下,我更喜欢从表中获取最新的结果集。因此等待写入请求将是方式,但这可能导致读取请求饥饿。 所有写入请求都是非更新行请求。更新请求我认为获取行级锁定,而插入请求需要表级锁定。

您能解释一下InnoDB会如何发生这种情况吗? 感谢

2 个答案:

答案 0 :(得分:2)

在InnoDB中,INSERTs执行而不是进行表锁定。 (MyISAM是另一回事。)

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

  • 有些锁是“间隙”锁。可以想象INSERTing两个现有行之间的新行。
  • 共享读锁(在同一行)不会相互阻塞
  • eXclusive锁定的行为与您描述的有些相似。

“MVCC”允许多个事务“看到”相同行的不同版本。假设一个事务我是SELECTing一行,而另一个是UPDATEing它。在两个事务完成之前,该行实际上有两个版本。在事务COMMITedROLLBACKed之后,事情会被清理。

所有这些行级锁定和检查都很昂贵,这可能一文不值。如果你有几十个连接冲击,他们都将放慢速度。在旧版本中,4-8个连接是实际限制。对于5.7,可以处理大约64。尽管如此,InnoDB每秒可以处理数千个事务,最终受到慢速磁盘I / O的限制。

“批量插入” - 如果您确实将INSERT表示为单个表,则最好创建包含100-1000行的单个INSERT语句。这减少了通信,解析,优化和事务开销的开销。它还会增加与读取冲突的风险,但加速(通常)会超过碰撞延迟。

确保在每个InnoDB语句后检查错误。可能会发生死锁。通常,它们由ROLLBACK处理,并重新运行BEGIN...COMMIT

答案 1 :(得分:0)

这在很大程度上取决于您是否在事务中进行更新。您还可以设置隔离级别以在需要时获得更多吞吐量。这是一个很好的解释:https://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html

如果您的数据适合,您可以将隔离级别设置得更低。 我希望这会有所帮助。