【问题标题】:InnoDB Concurrent Read-WriteInnoDB 并发读写
【发布时间】:2015-05-12 05:48:24
【问题描述】:

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

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

【问题讨论】:

    标签: mysql locking innodb read-write


    【解决方案1】:

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

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

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

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

    所有这些行级锁定和检查成本高昂可能一文不值。如果您有几十个连接突然消失,它们都会变慢。在旧版本中,4-8 个连接是一个实际限制。对于 5.7,可以处理大约 64 个。尽管如此,InnoDB 每秒可以处理数千个事务,但最终会受到磁盘 I/O 缓慢的限制。

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

    确保在每个 InnoDB 语句之后检查错误。可能会发生死锁。一般由ROLLBACK 处理,再加上重新运行BEGIN...COMMIT

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-18
        • 1970-01-01
        相关资源
        最近更新 更多