InnoDB 并发读写

InnoDB Concurrent Read-Write

我想了解 InnoDB 如何同时处理多个 reads/write 操作。 考虑以下情况: 您正在执行相当密集的批量写入。任何将进入的读取请求都必须等到批写入完成。在此期间,table 上也有写入请求。所以到时候,批量写入完成,有多个读取请求和写入请求挂起。 innodb 将以什么顺序解决请求。在大多数情况下,我更愿意从 table 获取最新的结果集。因此,等待写请求将是一种方式,但这可能会导致读请求饥饿。 所有写请求都是非更新行请求。我认为更新请求需要行级锁,而插入请求需要 table 级锁。

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

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

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

在 InnoDB 中,INSERTs 获取 table 锁。 (MyISAM 是另一回事。)

粗略地说,每次读取或写入 InnoDB table 将只锁定所需的行。如果一个查询的行与另一个查询的行之间没有重叠,则没有等待。使其成为 "roughly" 的一些问题:

  • 有些锁是 "gap" 锁。考虑 INSERTing 两个现有行之间的新行。
  • 共享读锁(在同一行)不会互相阻塞
  • 独占锁的行为有点像您描述的那样。

"MVCC" 允许多个事务 "see" 不同版本的 相同 行。假设一笔交易是 SELECTing 一行,而另一笔交易是 UPDATEing 行。在两个事务都完成之前,该行实际上有两个版本。两笔交易都为 COMMITedROLLBACKed.

后,事情得到清理

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

"Batch Inserts" -- 如果你真的想把 INSERT 变成一个 table,那么最好创建一个 INSERT 包含 100- 1000 行。这减少了通信、解析、优化和事务开销的开销。它还增加了与读取冲突的风险,但加速(通常)超过了冲突延迟。

一定要在每个 InnoDB 语句之后检查错误。可能会发生死锁。通常,它们由 ROLLBACK 加上重新运行 BEGIN...COMMIT.

来处理