深入浅出分析 Mysql 的 InnoDB 工作原理

作者:IT技术圈子 浏览量:134   更新于 2024-10-16 21:42 标签:

一 、上期回顾

上次小编讲了一条sql的执行流程,总结如下:

  1. 解析器(Parser):检查SQL语法,生成语法树。
  2. 优化器(Optimizer):选择最优执行计划,确定索引路径。
  3. 执行器(Executor):根据优化器计划,调用存储引擎执行操作。
  4. InnoDB存储引擎
    • 行级锁:对特定记录加锁,避免并发冲突。
    • 数据修改:实际更新记录,记录修改到redo log。
    • 事务控制(ACID):事务提交或回滚,确保数据一致性和持久性。
  5. 返回结果:将执行结果返回给客户端。

然后小编也说了,InnoDB存储引擎里面不止做了这几件事,所以这期小编来聊聊InnoDB存储引擎做了哪些事情。

二 、innoDB

2.1 一条更新sql语句的执行流程图

2.2 buffer pool(innoDB)

Buffer Pool的定义

Buffer Pool 是一块内存区域,专门用于存储数据库的数据页和索引页,以便数据库在查询或更新数据时,能够直接从内存读取而不是从磁盘读取,极大地提高了查询性能。

Buffer Pool的作用

  1. 缓存数据页:当用户查询数据时,InnoDB会首先查看Buffer Pool中是否已经缓存了所需的数据。如果缓存命中,数据直接从内存中读取,速度快于从磁盘读取。
  2. 减少磁盘I/O:由于磁盘I/O操作相对较慢,Buffer Pool能显著减少数据库对磁盘的读取次数,从而提高性能。
  3. 并发控制:InnoDB会管理对Buffer Pool的访问,确保在并发情况下对内存的访问是高效的。

性能调优建议

  1. 调整大小:合理分配Buffer Pool大小可以显著提高性能。建议分配服务器可用内存的一大部分给Buffer Pool,以减少磁盘访问。
  2. 监控和调整:使用命令SHOW ENGINE INNODB STATUS 或者查询性能视图来监控Buffer Pool的使用情况,如命中率、读取次数等,并根据需要调整Buffer Pool的大小。

另外 buffer pool既然是将物理磁盘的数据缓存起来,那么它的数据结构,内存不够时的淘汰策略等等,小编将新开一篇mysql innoDB的buffer pool单独讲解,有兴趣的同学记的关注后续文章。

2.3 undo log(innoDB)

Undo Log的定义

Undo Log 是用于记录数据在进行修改之前的状态的日志。当一个事务执行时,任何对数据的修改都会在修改前记录到Undo Log中。如果事务因为某些原因失败或被显式回滚,InnoDB会利用Undo Log将数据恢复到修改前的状态。

Undo Log的作用

  1. 事务回滚
    • 如果一个事务在执行过程中出现错误或者用户显式执行ROLLBACK,InnoDB会利用Undo Log中的记录将数据恢复到事务开始前的状态,确保事务的原子性。
  2. MVCC(多版本并发控制)
    • Undo Log帮助实现多版本并发控制(MVCC, Multiversion Concurrency Control)。当一个事务在读取数据时,可能有其他事务正在修改相同的数据。Undo Log允许未提交的事务看到修改前的数据,而其他事务可以继续访问原始版本的记录,确保事务之间的隔离性。
  3. 崩溃恢复
    • 如果数据库因意外宕机或崩溃,未完成的事务会被回滚。数据库在重新启动时,可以通过分析Undo Log,将未提交的事务的修改回滚,从而确保数据一致性。

Undo Log与Redo Log的区别

  • Undo Log:主要用于事务回滚和MVCC。记录的是数据修改前的旧值,以便在需要时回滚。
  • Redo Log:主要用于持久性(Durability)。记录的是数据的修改操作,以便在系统崩溃后恢复事务的修改。

2.4 redo log(innoDB)

Redo Log的定义

Redo Log 是一种物理日志,记录的是数据页的修改操作,而不是具体的数据内容。当一个事务对数据库中的数据进行修改时,InnoDB会先将这些修改操作记录到Redo Log中,然后再将这些操作实际写入到磁盘的数据文件中。

Redo Log的作用

  1. 数据恢复:
    • 在发生系统崩溃、宕机或硬件故障时,Redo Log能够用于重做未完成的事务,确保数据库在恢复时仍然可以反映出所有已提交的事务修改。这是事务的持久性保证。
  2. 性能优化:
    • Redo Log允许数据库在不必每次修改都立即将数据写入磁盘的情况下,先把修改记录到日志中。这极大提高了性能,因为写入日志通常比随机写入磁盘上的数据页要快。
    • 数据修改可以在适当的时候(比如内存不足时或达到一定的时间间隔时)通过后台进程慢慢刷新到磁盘文件中,而不影响事务的提交速度。
  3. 支持事务提交:
    • 当事务执行COMMIT时,InnoDB首先会将所有相关的修改操作写入Redo Log,并确保这些日志已经安全地存储在磁盘上,之后事务才会被认为是成功提交。即使在事务提交后数据库发生崩溃,事务的修改也可以通过Redo Log来恢复。

Redo Log的工作原理

  • 当事务开始修改数据时,InnoDB将修改操作记录到Redo Log Buffer中。
  • 当事务提交时,Redo Log Buffer中的日志会被同步到磁盘上的Redo Log文件(这个过程叫做 刷盘(fsync))。
  • 在后台,InnoDB会根据一定的时间间隔或Buffer Pool中的压力,将修改的数据页从内存刷新到磁盘文件中(这称为 Checkpoint 机制)。
  • 如果数据库崩溃或重启,InnoDB会读取Redo Log文件中的日志,并将其中未完成的事务操作重新应用到数据库中(重做(redo)),从而恢复数据。

Redo Log的性能调优

  • 日志文件大小 (innodb_log_file_size):较大的日志文件可以减少Checkpoint的频率,但会增加崩溃恢复的时间,因为日志文件越大,恢复时需要重做的日志条目也越多。
  • Redo Log Buffer大小 (innodb_log_buffer_size):如果事务提交频率高,可以适当增加Redo Log Buffer的大小,以减少刷盘的频率。
  • 写入频率:通过innodb_flush_log_at_trx_commit参数控制事务提交时写日志到磁盘的策略:
    1. 0:事务提交时不强制写日志到磁盘,日志在后台刷新。这种配置性能高但风险较大。
    2. 1:每次事务提交时,Redo Log会立即刷入磁盘。这是默认的设置,确保了事务的强持久性。
    3. 2:事务提交时,日志写入文件系统缓存中,而不是立即写入磁盘,崩溃时可能丢失部分数据。

2.5 bin log(mysql)

Binlog的定义

Binlog是MySQL的二进制日志,记录了所有更改数据库数据的语句以及与其相关的事务。它与InnoDB存储引擎的Redo Log不同,Redo Log是用于恢复崩溃后未完成的事务,而Binlog是记录事务日志,用于备份、恢复和复制。

Binlog的作用

  1. 数据恢复:
    • Binlog可以用作增量备份工具。通过定期备份Binlog文件,MySQL管理员可以将数据库恢复到某一时刻之前的状态,然后通过应用Binlog中的修改来恢复到崩溃前的最新状态。与完整备份配合,能够实现更精细的恢复过程。
    • 如果数据库因某种原因崩溃,可以通过Point-in-Time Recovery(PITR,时间点恢复),将数据库恢复到特定的时间点,或恢复到某个已知的稳定状态。
  2. 主从复制:
    • MySQL支持主从复制(Replication),其中主服务器上的数据更改会通过Binlog同步到从服务器。主服务器会将所有更改记录到Binlog中,然后从服务器读取并应用这些日志,从而保持与主服务器的数据一致性。
    • 这种机制使得可以创建冗余的从服务器来提高高可用性和读性能,分担查询负载。

三 、总结

InnoDB的Buffer Pool是MySQL用于缓存数据和索引页的内存区域,减少磁盘I/O,提升读写性能。Undo Log记录事务修改前的数据,用于回滚未提交的事务和实现MVCC。Redo Log则记录已提交事务的修改操作,确保系统崩溃后能够恢复事务,保证数据的持久性。Buffer Pool优化了内存使用,Undo Log维护事务一致性,Redo Log确保持久性与数据恢复,三者协同保障InnoDB的高效性与可靠性。