事务隔离级别
事务隔离级别
事务隔离是数据库的基础之一 加工。Isolation 是首字母缩略词 ACID 中的 I;隔离级别为 微调 performance 和 结果的可靠性、一致性和可重复性 多个事务正在进行更改并执行查询 同时。
InnoDB
提供所有四个事务隔离 SQL:1992 标准描述的级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READREPEATABLE READREPEATABLE READ 和 SERIALIZABLE 。默认的 的隔离级别为 REPEATABLE READREPEATABLE READ。InnoDB
用户可以更改单个会话的隔离级别,或者 对于使用 SET 的所有后续连接 TRANSACTION 语句。设置服务器的默认值 隔离级别,请使用 --transaction-isolation 选项 命令行或选项文件中。详细信息 有关隔离级别和级别设置语法,请参见第 15.3.7 节“ SET TRANSACTION 语句”。
InnoDB
支持每笔交易 此处使用不同的锁定策略描述的隔离级别。您可以 强制与默认 REPEATABLE READ 级别高度一致,因为 对 ACID 合规性很重要的关键数据进行操作。 或者,您可以使用 READ COMMITTED 甚至 READ UNCOMMITTED 放宽一致性规则,在 例如批量报告的情况,其中精确一致性和 可重复的结果不如最小化数量重要 的开销进行锁定。SERIALIZABLE 甚至强制执行 比 REPEATABLE 更严格的规则 READ,主要用于特殊情况、 例如,使用 XA 事务和 用于排查并发和死锁问题。
以下列表描述了 MySQL 如何支持不同的 交易级别。该列表从最常用的 level 设置为最少使用的级别。
-
REPEATABLE READ
这是 的默认隔离级别。同一事务中的一致性读取读取由 第一次阅读。这意味着,如果您发出多个 plain (非锁定)SELECT 语句,这些 SELECT 语句是 彼此之间也一致。参见第 17.7.2.3 节“一致的非锁定读取”。
InnoDB
对于锁定读取(SELECT 和 或 )、UPDATE 和 DELETE 语句,锁定 取决于语句是否使用带有 唯一搜索条件,或范围类型搜索条件。
FOR UPDATE
FOR SHARE
-
对于具有唯一搜索条件的唯一索引,仅锁定索引记录 找到的,而不是之前的差距。
InnoDB
-
对于其他搜索条件,锁定扫描的索引范围,使用间隙锁或下一键锁来阻止其他会话插入间隙 覆盖范围。有关间隙锁定的信息 和下一个键锁,请参见第 17.7.1 节“ InnoDB 锁定”。
InnoDB
不建议混合使用锁定语句 (UPDATE、INSERT、DELETE 或 )替换为非锁定 SELECT 语句,因为通常在这种情况下,您希望 SERIALIZABLE。这是 因为非锁定 SELECT 语句表示读取时数据库的状态 视图,该视图包含在 read 视图,并且在当前事务的 own 写入,而 locking 语句使用最新的 state 的数据库来使用锁定。一般来说,这两个 不同的表状态彼此不一致,并且 难以解析。
SELECT ... FORM ...
-
-
READ COMMITTED
每个一致性读取,即使在同一个事务中,也会设置 并读取自己的新快照。有关 consistent reads,请参见第 17.7.2.3 节“一致的非锁定读取”。
对于锁定读取(SELECT with or )、UPDATE 语句和 DELETE 语句,仅锁定索引 记录,而不是它们之前的间隙,因此允许 free 在锁定记录旁边插入新记录。间隙锁定 仅用于外键约束检查,而 重复键检查。
FOR UPDATE
FOR SHARE
InnoDB
由于禁用了间隙锁定,因此幻像行问题可能会 发生,因为其他会话可以将新行插入到间隙中。 有关幻像行的信息,请参见第 17.7.4 节“幻像行”。
隔离级别仅支持基于行的二进制日志记录。如果你 与 binlog_format=MIXED 一起使用时, Server 自动使用基于行的日志记录。
READ COMMITTED
READ COMMITTED
-
使用 has additional 影响:
READ COMMITTED
-
对于 UPDATE 或 DELETE 语句,仅对满足以下条件的行保持锁定 它会更新或删除。不匹配行的记录锁 在 MySQL 评估条件后释放。这大大降低了 死锁的可能性,但它们仍然可能发生。
InnoDB
WHERE
-
对于 UPDATE 语句,如果 行已锁定,执行 “半一致” 读取, 将最新提交的版本返回给 MySQL,以便 MySQL 可以确定该行是否与 UPDATE 的条件匹配。如果行 matches(必须更新),MySQL 会再次读取该行,并且 这次要么锁定它,要么 等待其上的锁定。
InnoDB
WHERE
InnoDB
请考虑以下示例,从下表开始:
CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB; INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2); COMMIT;
在这种情况下,表没有索引,因此搜索和 索引扫描使用隐藏的聚集索引作为记录 锁定而不是 比索引列。
-
-
聚集索引和二级索引
每个表都有一个名为 存储行数据的聚集索引。通常,集群 index 与主键同义。为了获得最佳效果 查询、插入和其他数据库操作的性能, 了解如何使用 用于优化常用查找和 DML 的聚集索引 操作。
InnoDB
InnoDB
-
在表上定义 时,将其用作聚集索引。一个 应为每个表定义主键。如果没有 逻辑唯一和非 null 列或一组列来使用 主键,添加自增列。自动递增 列值是唯一的,并自动添加新值 行。
PRIMARY KEY
InnoDB
-
如果您没有为 table 使用定义了所有键列的第一个索引 as 作为聚集索引。
PRIMARY KEY
InnoDB
UNIQUE
NOT NULL
-
如果表没有索引或具有合适的索引,则生成一个在合成列上命名的隐藏聚集索引,该索引 包含行 ID 值。行按行 ID 排序 那分配。行 ID 为 6 字节 字段,该字段在插入新行时单调增加。 因此,按行 ID 排序的行在物理上是有序的 的插入。
PRIMARY KEY
UNIQUE
InnoDB
GEN_CLUST_INDEX
InnoDB
聚集索引如何加快查询速度
通过聚集索引访问行的速度很快,因为 索引搜索直接指向包含该行的页面 数据。如果表很大,则聚集索引体系结构 与存储相比,通常可以节省磁盘 I/O 操作 使用不同页面存储行数据的组织 索引记录。
二级索引与聚集索引的关系
聚集索引以外的索引称为辅助索引 指标。在 中,每条记录中的 secondary index 包含该行的主键列,因为 以及为 Secondary Index(二级索引)指定的列。 使用此主键值进行搜索 对于聚集索引中的行。
InnoDB
InnoDB
如果主键很长,则二级索引使用更多 space,因此使用较短的主键是有利的。
假设一个会话使用这些执行 UPDATE 语句:# Session A START TRANSACTION; UPDATE t SET b = 5 WHERE b = 3;
还假设第二个会话通过执行这些 在第一次会议之后的发言:
# Session B UPDATE t SET b = 4 WHERE b = 2;
当 InnoDB 执行每个 UPDATE 时,它首先会获取一个 独占锁,然后确定是否 修改它。如果 InnoDB 没有 修改 Row,它会释放锁。否则,InnoDB 将保留锁定,直到 交易结束。这会影响交易 处理如下。
当使用默认隔离级别时,第一个 UPDATE 会获取 x-lock on 它读取且不释放任何一行:
REPEATABLE READ
<span style="background-color:#ffffff"><span style="color:#555555"><span style="background-color:#f8f8f8"><span style="color:#000000"><code class="language-none">x-lock(1,2); retain x-lock x-lock(2,3); update(2,3) to (2,5); retain x-lock x-lock(3,2); retain x-lock x-lock(4,3); update(4,3) to (4,5); retain x-lock x-lock(5,2); retain x-lock</code></span></span></span></span>
第二个 UPDATE 块为 一旦它尝试获取任何锁(因为第一次更新 在所有行上都保留了锁),并且在 第一个 UPDATE 提交或 回滚:
x-lock(1,2); block and wait for first UPDATE to commit or roll back
If 改用 第一个 UPDATE 获取 x-lock 读取的每一行,并释放行的 x-lock 它不会修改:
READ COMMITTED
<span style="background-color:#ffffff"><span style="color:#555555"><span style="background-color:#f8f8f8"><span style="color:#000000"><code class="language-none">x-lock(1,2); unlock(1,2) x-lock(2,3); update(2,3) to (2,5); retain x-lock x-lock(3,2); unlock(3,2) x-lock(4,3); update(4,3) to (4,5); retain x-lock x-lock(5,2); unlock(5,2)</code></span></span></span></span>
对于第二个 ,执行 “semi-consistent” 读取,返回最新的 committed 版本读取到 MySQL 中,以便 MySQL 可以确定该行是否与 UPDATE 的条件匹配:
UPDATE
InnoDB
WHERE
-
-
CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB; INSERT INTO t VALUES (1,2,3),(2,2,4); COMMIT; # Session A START TRANSACTION; UPDATE t SET b = 3 WHERE b = 2 AND c = 3; # Session B UPDATE t SET b = 4 WHERE b = 2 AND c = 4;
隔离级别可以是 在启动时设置或在运行时更改。在运行时,它可以是 为所有会话全局设置,或为每个会话单独设置。
READ COMMITTED
-
READ UNCOMMITTED
SELECT 语句是 以非锁定方式执行,但可能更早 版本。因此,使用此隔离 级别,则此类读取不一致。这也称为脏读。 否则,此隔离级别的工作方式类似于 READ COMMITTED。
-
SERIALIZABLE
这个级别类似于 REPEATABLE READ,但隐式 将所有普通 SELECT 语句转换为 SELECT ...FOR SHARE(如果禁用了自动提交)。如果启用了自动提交,则 SELECT 是它自己的 交易。因此,已知它是只读的,并且可以 如果作为一致(非锁定)读取执行,则被序列化 并且不需要为其他交易冻结。(强制普通 SELECT 在显示其他 事务修改了所选行,请禁用自动提交。
InnoDB
原文地址:https://blog.csdn.net/whs_8792/article/details/144383496
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!