【问题标题】:MySQL/InnoDB and long-running queriesMySQL/InnoDB 和长时间运行的查询
【发布时间】:2014-01-28 14:55:27
【问题描述】:

在使用 myisam 引擎时运行查询时,由于它不是事务性的,长查询(据我了解)不会影响来自其他查询的数据。

在 InnoDB 中,它警告的一件事是避免长查询。当 InnoDB 快照时,它是对所有内容进行快照吗?

我问这个问题的原因是:无论出于何种原因,查询都需要比正常时间更长的时间并最终回滚。同时,还有 200 个其他用户已更新或将行插入到数据库中。当长查询回滚时,它是否还会删除其他用户所做的更新/插入?或者涉及其他用户的行是否安全,除非他们与回滚的行交叉?

【问题讨论】:

    标签: mysql sql innodb


    【解决方案1】:

    首先,我认为阅读 multi-version concurrency control (MVCC) 作为此答案的背景会很有用。

    InnoDB 实现了 MVCC,这意味着它可以对常规的SELECT 使用非锁定读取。这不需要创建“快照”,实际上 InnoDB 没有任何将快照作为对象的真正概念。相反,数据库中的每条记录都跟踪自己的版本号,并维护一个指向“撤消日志”记录(可能存在也可能不存在)的“滚动指针”,该记录将行修改为之前的版本。如果需要旧版本的记录,则读取当前版本并遵循这些滚动指针并应用撤消记录,直到生成足够旧版本的记录。

    通常系统会不断清理这些撤消日志并重新使用它们占用的空间。

    任何长时间运行的事务(注意,不一定是单个查询)存在时,都必须保留(而不是清除)撤消日志,以便充分重新创建所有记录的足够旧版本以满足该交易。在一个非常繁忙的系统中,这些撤消日志会很快累积并消耗千兆字节的空间。此外,如果特定的单个记录被非常频繁地修改,则将该记录恢复到足够旧的版本以满足查询可能需要很多撤消日志应用程序(数千个)。

    这就是“长时间运行的查询”成本高昂且不受欢迎的原因。它们会增加将撤消日志保存在系统表空间中的磁盘空间消耗,并且由于撤消日志记录应用程序在读取时恢复行版本,它们的性能会很差。

    一些数据库实现了可以使用的最大撤消日志空间量,一旦达到该限制,它们就会开始丢弃旧的撤消日志记录并使正在运行的事务无效。这会向用户生成“快照太旧”错误消息。 InnoDB 没有这个限制,允许无限累积。

    【讨论】:

      【解决方案2】:

      您的查询是否影响并发与查询类型无关。有许多读取查询不会影响 MyISAM 或 InnoDB 中的并发性(除了性能问题)。

      插入(使用 InnoDB 插入到索引的末尾,或者使用 MyISAM 插入到表的末尾)也不会影响并发性。

      然而,一旦你有一个更新查询,行就会在 InnoDB 中被锁定,而在 MyISAM 中,整个表都会被写锁定。当您尝试更新具有写锁的记录(或表)时,您必须等到锁被释放才能继续。在 MyISAM 中,更新在读取之前提供,因此您必须等到更新处理完毕。

      MyISAM 的性能更高,因为表锁比记录锁快(尽管记录锁很快)。但是,当您开始进行大量更新时,通常首选 InnoDB,因为不同的用户通常不太可能争夺相同的记录。因此,借助 InnoDB,由于记录级锁定(而不是表锁定),许多用户可以并行工作而不会相互影响太多。

      更不用说使用 InnoDB 获得的完全符合 ACID 的好处、外键约束的实施以及聚集索引的速度。

      快照(日志条目)保留足够长的时间以完成当前事务,如果它们被回滚或提交,它们将被丢弃。事务运行的时间越长,发生其他更新的可能性就越大,这会增加回滚所需的日志条目数。

      不会因为锁定而出现“交叉”。当同一记录发生写争用时,一个用户必须等到另一个用户提交或回滚。

      您可以阅读有关The InnoDB Transaction Model and Locking 的更多信息。

      【讨论】:

      • 快照本身没有物理表现,只有已更新的行的旧版本。长时间运行的事务禁止对这些旧行进行垃圾收集。 IE。如果任何未完成的事务仍需要“查看”数据库处于该事务开始时的状态(并且该事务是可重复读取的),则无法清除完成其数据状态视图所需的旧行版本。假设更新继续发生,事务越长,回滚段中积累的数据就越多。
      • 我更新了我的答案。如果还有什么不准确的地方请告诉我。
      • 是的,看起来更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 2018-04-20
      相关资源
      最近更新 更多