网站报价表网络空间的竞争归根结底是

当前位置: 首页 > news >正文

网站报价表,网络空间的竞争归根结底是,重庆建设工程安全管理网查询,深圳市建设工程质量检测网站大家好#xff0c;我是此林。 今天来介绍下InnoDB底层架构。 1. 磁盘架构 我们所有的数据库文件都保存在 /var/lib/mysql目录下。 由于我这边是docker部署的mysql#xff0c;用如下命令查看mysql数据挂载。 docker inspect mysql-master 如下图#xff0c;目前只有一个数…大家好我是此林。 今天来介绍下InnoDB底层架构。 1. 磁盘架构 我们所有的数据库文件都保存在 /var/lib/mysql目录下。 由于我这边是docker部署的mysql用如下命令查看mysql数据挂载。 docker inspect mysql-master 如下图目前只有一个数据库 db_user数据库本质上是文件夹的形式。 在db_user文件夹下目前只有一张表表空间就是idb文件形式。 表空间idb文件以B树的形式组织存储其中B树的非叶子结点存储索引段叶子结点存储的是数据段。此外还有回滚段。段用来管理多个区。 区是表空间的单元结构每个区大小为1M一个区有64个连续的页。 页是InnoDB存储引擎磁盘管理的最小单元每个页默认大小为16K。为了保证页的连续性Inn哦DB存储引擎每次从磁盘申请4-5个区。 行InnoDB存储引擎数据是按行存放的。 所有文件介绍 1. db_user自定义的数据库 2. mysqlmysql自带数据库包含用户、权限和管理信息表 3. performance_schema、sysmysql自带数据库用于mysql性能监控 4. ib_logfile0、ib_logfile1redo_log重做日志 5. binlog.000001、binlog000002binlog二进制日志 6. undo_001、undo_002undo_log回滚日志 2. 内存架构

  1. BufferPool 数据表都保存在磁盘文件中而用户是无法直接操作磁盘文件的必须先把数据文件加载到内存中用户对内存中的数据进行增删改操作最后再以一定的频率把内存中的数据刷新到磁盘中。 InnoDB内存架构中BufferPool缓冲区就是类似的作用。 BufferPool 中以页Page为单位每次它会去磁盘中加载整页16K数据。这样做的好处是减少磁盘IO相当于缓存的作用。 BufferPool 中的 Page有三种类型 1. 空页free page空闲页未被使用 2. clean page被使用的页但是数据没有被修改过 3. 脏页dirty page被使用的page数据被修改过也就是和磁盘中数据不一致的页。 2. ChangeBuffer 更改缓冲区针对非唯一的二级索引在执行DML语句增删改语句时如果这些这些数据Page不在BufferPool中不会区操作磁盘而是先把数据变更存在更改缓冲区中未来数据被读取时再将数据合并恢复到BufferPool中最后再刷新到磁盘。 存在的意义 和聚簇索引不同二级索引通常是非唯一的并且每次以相对随机的顺序插入二级索引。同样删除和更新可能会影响索引树中不相邻的二级索引页如果每一次都操作一次磁盘IO会造成大量的磁盘IO有了ChangeBuffer后我们可以在缓冲池中进行合并操作减少磁盘IO。 3. Adaptive Hash Index InnoDB不支持Hash索引它只支持B树索引我们目前所有的索引底层结构都是B树主要原因是Hash索引虽然快但是只支持等值匹配不支持范围查询。 自适应Hash索引用于优化对BufferPool的查询。InnoDB 存储引擎会监控对表上各个索引页的查询如果观察到Hash索引可以提升速度则建立Hash索引。系统自动优化无需人工干预。 查询参数 show variables like %hash%; 默认是开启的。 4. LogBuffer 日志缓冲区用来保存要写入到磁盘中的log日志数据redo logundo log。默认大小为16MB日志缓冲区的日志会定期刷到磁盘中。 参数 show variables like innodb_log_buffer_size; # 缓冲区大小 show variables like innodb_flush_log_at_trx_commit; # 日志刷新到磁盘的时机 innodb_flush_log_at_trx_commit 1 日志在每次事务提交时写入并刷新磁盘 0每秒将日志写入并刷新磁盘一次 2日志在每次事务提交后写入并且每秒刷新一次到磁盘中。 3. 后台线程
  2. Master Thread 核心后台线程负责调度其他线程还负责将缓冲区中的数据异步刷新到磁盘中保持数据的一致性还包括脏页的刷新、合并插入缓存、undo页的回收。
  3. IO Thread 在InnoDB中大量使用AIO异步非阻塞来处理IO请求极大提高数据库性能。 IO Thread主要负责这些IO请求的回调。 命令 show engine innodb status; 3. Purge Thread 主要用于回收事务已经提交的undo_log在事务提交之后undo log已经无用需要回收。 4. Page Cleaner Thread 协助Master Thread刷新脏页到磁盘的线程减轻Master Thread的工作压力减少阻塞。 4. InnoDB 事务原理 事务特性ACID
  4. 原子性事务操作不可分割要么同时成功要么同时失败。
  5. 一致性事务完成时所有数据必须保证一致性。
  6. 隔离性数据库系统提供的隔离机制保证事务在不受外部并发的影响的独立环境下运行。
  7. 持久性事务一旦 提交对数据库的改变就是永久的。 原子性、一致性由undo_log来实现 持久性由redo_log来实现 隔离性由锁和MVCC机制来实现。 1. redo_log重做日志 我们知道在执行update、delete、insert操作的时候实际操作的是BufferPool内存中的数据 但是BufferPool中的数据是由后台线程以一定的频率或由操作系统来决定何时同步到磁盘中的。 若BufferPool数据没来得及刷到磁盘中服务器宕机那么就会导致数据丢失。 redo_log出现后流程变化如下
  8. 变更BufferPool中的数据
  9. 数据页变化写入redo_log_buffer内存
  10. 事务提交后redo_log_buffer刷新到磁盘redo_log中。
  11. 之后即使BufferPool没来得及刷新到磁盘也可以通过redo_log来恢复。 问redo_log不是多此一举吗为什么不操作完BufferPool后直接把脏页刷新到磁盘里 答 1. 我们一般在事务操作很多条记录这些记录一般都是随机操作数据页的此时将涉及大量的磁盘IO性能极低。 2. 而redo_log日志文件写入都是追加顺序写入性能高于随机磁盘IO。这种机制叫WALWrite-Ahead-logging——先写日志。 3. 当BufferPool中脏页的数据成功刷新到磁盘中redo_log日志文件会被定期删除。 2. undo_log 回滚日志 回滚日志用于记录数据被修改前的信息作用有两个
  12. 提供回滚
  13. MVCC多版本并发控制 可以认为当delete一条语句undo_log中会记录一条对应的insert语句当update一条语句undo_log中会记录一条相反的update语句。 事务提交后undo_log不会被立即删除因为可能用于多版本并发控制MVCC。 3. MVCC 机制
  14. 概要 简单来说要保证并发安全MYSQL觉得每次读的时候都要加锁太损耗性能了。所以提出了MVCC机制是不加锁的快照读非阻塞读提升了性能。 1. 当前读 select … lock in share mode (读锁 select … for update (写锁 update、insert、delete 以上操作都是当前读会对读取的记录加锁。 2. 快照读 简单的select不加锁就是快照读。 Read Committed: 每次select都生成一个快照读。 Repeatable Comitted: 开启事务后第一个select语句就是快照读的地方。 Serializable: 快照读退化成当前读。 2. 实现原理 MVCC的实现依赖数据库的行记录中的三个隐藏字段、undo_log、readView。 DB_TRX_ID最近修改的事务ID记录插入这条数据或最后一次修改该记录的事务ID。DB_ROLL_PTR回滚指针指向这条记录的上一个版本用于配合undo_log指向上一个版本。DB_ROW_ID当表中没有定义主键MYSQL自动生成此字段作为主键。 查看命令 idb2sdi table_name.idb 当insert的时候产生的undo_log日志只在回滚时需要事务提交后可以立即删除。 当update、delete时候产生的undo_log日志不仅在回滚时需要在快照读的时候也需要不能立即删除。 3. 案例分析 来看下面一个案例 undo_log版本链如下 那我select的时候如何知道要访问哪个版本呢 简单来说它会拿到当前行的DB_TRX_ID(事务id)逐个和ReadView各个字段做条件判断满足条件即返回该版本数据若不满足会通过DB_ROLL_PTR回滚指针继续寻找版本进行比对。 先看事务5 假设当前事务隔离级别为RC即每次select都会生成一个ReadView。
  15. 执行第一个查询id为30的记录命令时生成如下ReadView。读取到的事务2修改的age10nameA3。 ReadView m_ids当前活动事务id[3,4,5]min_trx_id最小活动事务id事务id时自增的3max_trx_id最大活动事务id 1预分配的6creator_trx_id当前ReadView创建的事务id5 2. 执行第二个查询id为30的记录命令时生成如下ReadView。读取到的是age3nameA30。 ReadView m_ids当前活动事务id[4,5]min_trx_id最小活动事务id事务id时自增的4max_trx_id最大活动事务id 1预分配的6creator_trx_id当前ReadView创建的事务id5 但是当RR隔离级别下第二个查询id为30的记录 会和 第一个查询id为30的记录 的结果一样因为用的是同一个ReadView。如果这个时候不想快照读用select for update可以查到最新的记录因为这条加锁命令不走MVCC。 4. 总结 综上MYSQL使用了MVCC和锁机制来保证了事务的四大特性ACID。