学校网站建设内容设计,小程序招商,wordpress首页添加价格,朝阳百姓网免费发布信息一文看懂 Mysql 核心存储 隔离级别 锁 MVCC 机制
Mysql InnoDB 引擎下核心存储
数据索引存储 IBD 文件
mysql 实际存储采用 B 树结构。
B 树是一种多路搜索树#xff0c;其搜索性能高于 B 树
所有叶节点在同一深度#xff0c;保证搜索效率仅叶节…一文看懂 Mysql 核心存储 隔离级别 锁 MVCC 机制
Mysql InnoDB 引擎下核心存储
数据索引存储 IBD 文件
mysql 实际存储采用 B 树结构。
B 树是一种多路搜索树其搜索性能高于 B 树
所有叶节点在同一深度保证搜索效率仅叶节点存储实际数据其他节点仅存储索引不存储数据节省空间可存储更多索引每个节点存储一组数据这组数据由小到大排列叶子节点用双向指针链接提高区间访问效率在 B 树中索引数据可能会被冗余存储
推荐一个在线构建 B 树的网址 https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
在 mysql 中一个节点也可以成为一页 这个节点数据默认最大 16kb 16384 byte
SELECT innodb_page_size; 可以用这个语句查询。
所以在 mysql 中实际的数据存储就是以 B 树索引的形式存储的叶子节点带有所有数据索引字段是主键 id。
其他非主键索引叶子节点带有的是主键数据和索引数据如果要查询列表不包含在索引字段内会进行”回表“去查询遍主键索引获取所需要的数据所以有时候优化查询速度时会考虑简历覆盖索引避免回表。
缓存日志 mysql 在实际存储和操作时并非直接操作磁盘这样效率太慢了。
所以基本上优化磁盘速度 -- 使用内存缓存
内存不可靠问题 -- 顺序写日志
在内存缓存上
BufferPool数据的增删改查都是直接操作 BufferPool 比如查询时会直接 load 相关的一页数据到 BufferPool 中RedoLogBuffer写 redolog 的缓冲区在合适的时机高效批量写入 如 COMMIT 操作时、执行 CHECKPOINT 操作时MySQL 内部定期执行的一种操作
在日志上
undologInnoDB用于一个事务中执行失败时的回滚操作以及在可见级别为 可重复读和读已提交 下 MVCC 机制的实现redologInnoDB用于在故障时重放没有同步到磁盘的操作数据同步数据到 binlog 后会将数据清除binlog记录全量数据日志用于恢复磁盘数据 MySQL 会在以下情况下将 redolog 中的数据同步到 binlog 中 执行 COMMIT 操作时。执行 FLUSH LOGS 操作时。执行 FLUSH BINARY LOGS 操作时。执行 FLUSH TABLES 操作时。执行 FLUSH TABLES WITH READ LOCK 操作时。执行 FLUSH RELAY LOGS 操作时。执行 FLUSH RELAY LOGS WITH READ LOCK 操作时。执行 FLUSH MASTER 操作时。 最终存储 IBD
IBD 文件是 MySQL 中用于存储表数据的文件它以索引形式存储数据
事务隔离级别
在并发多事务的情况下数据的读写更新会存在一些问题这与我们设置的隔离级别息息相关。
脏写指在一个事务中更新了一行数据但是这一行数据还没有提交另一个事务也更新了这一行数据 新的事物覆盖了旧事物写的值导致旧事物的更新失效脏读事务 A 读到了 事务 B 修改但未提交的数据不可重复读 事务 A 内部相同查询语句查询结果不同读到了其他事务已提交的数据幻读事务 A 读取到了事务 B 新增的数据
mysql 支持的事务隔离级别 默认的隔离级别是 可重复读 也是我们最常用的隔离级别。
表锁行锁间隙锁
在不同的纬度上 mysql 的锁分很多种
性能上
悲观锁乐观锁版本比较
操作分类上
读锁 共享做 S 锁写锁 排他锁 X 锁
锁粒度上
表级锁行锁间隙锁
在 innodb 引擎下聊聊锁
表锁
锁全表的情况一般出现在表结构变更时或者手动 lock table 时
如果一个事务需要更新多行MySQL 会尝试加上一个表锁
行锁
在写数据是会对该行数据加行锁即 在执行INSERT/UPDATE/DELETE语句时
无索引行进行 update 行锁可能会升级为表锁
间隙锁
在更新数据时在此数据与其他数据存在的空隙加锁如 存在 id 1 3 5 的数据
此时更新 3 号数据会锁 1,33,5 这两个区间无法插入数据这就是间隙锁可以解决一部分幻读问题
而 3 号数据在更新所以这个行会加行锁
行锁 对应的间隙锁 也称之为 临键锁。
MVCC 机制
这个机制是保证可重复读和读已提交的核心机制。是基于 undolog 版本链 以及 一致性视图 read-view
undo日志版本链是指一行数据被多个事务依次修改过后在每个事务修改完后Mysql会保留修改前的数据 undo 回滚
日志并且用两个隐藏字段 trx_id 和 roll_pointer 把这些 undo日志串联起来形成一个历史记录版本链。
而一致性视图是在一个事务开启后执行任何查询 sql 时进行生成read-view 会生成当前所有未提交事务的 id
而在 undolog 中 trx_id 小于未提交事务 id 的记录都是已提交记录是可读的而大于最大 id 的是视图生成时未开始的事务 不可读
如果 min_id trx_id max_id 且不在未提交数组中则也是可读的