当使用 myisam 引擎运行查询时,因为它不是事务性的,所以长查询(据我所知)不会影响其他查询的数据。
在 InnoDB 中,它警告的事情之一是避免长查询。 InnoDB快照时,是不是把所有东西都快照了?
我问这个问题的原因是:无论出于何种原因,查询都会比正常情况花费更长的时间并最终回滚。与此同时,其他 200 个用户已更新或向数据库中插入行。当长查询回滚时,它是否也会删除其他用户所做的更新/插入?或者涉及其他用户的行是否安全,除非它们与回滚的行交叉?
首先,我认为作为阅读背景知识会很有用多版本并发控制(MVCC)作为这个答案的背景。
InnoDB实现了MVCC,这意味着它可以使用非锁定读取来进行常规读取SELECT
。这不需要创建“快照”,事实上 InnoDB 没有任何将快照作为对象的真正概念。相反,数据库中的每条记录都会跟踪其自己的版本号,并维护指向“撤消日志”记录(可能仍存在或可能不存在)的“滚动指针”,该记录将该行修改为其先前版本。如果需要记录的较旧版本,则读取当前版本,并跟踪那些滚动指针并应用撤消记录,直到产生足够旧的记录版本。
通常,系统会不断清理这些撤消日志并重新使用它们占用的空间。
任何时间任何长时间运行交易(注意,不一定是单个查询)存在,必须保留(而不是清除)撤消日志,以便充分重新创建所有记录的足够旧的版本以满足该事务。在非常繁忙的系统中,这些撤消日志会很快累积并消耗千兆字节的空间。此外,如果特定的单个记录被非常频繁地修改,则将该记录恢复到足够旧的版本以满足查询可能需要很多撤消日志应用程序(数千次)。
这就是“长时间运行的查询”成本高昂且不受欢迎的原因。它们会增加用于将撤消日志保留在系统表空间中的磁盘空间消耗,并且由于撤消日志记录应用程序在读取时恢复行版本,因此它们的性能会很差。
某些数据库实现了可消耗的最大撤消日志空间量,一旦达到该限制,它们就会开始丢弃较旧的撤消日志记录并使正在运行的事务无效。这会向用户生成“快照太旧”的错误消息。 InnoDB没有这样的限制,并且允许无限期地累积。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)