欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > MYSQL 存储引擎 和 日志

MYSQL 存储引擎 和 日志

2025/4/8 23:00:53 来源:https://blog.csdn.net/liiilbb/article/details/147017178  浏览:    关键词:MYSQL 存储引擎 和 日志

存储引擎

  • InnoDB 支持行级别的锁粒度,MyISAM 不支持,只支持表级别的锁粒度。
  • MyISAM 不提供事务支持。InnoDB 提供事务支持,实现了 SQL 标准定义了四个隔离级别。
  • MyISAM 不支持外键,而 InnoDB 支持。
  • MyISAM 不支持 MVCC,而 InnoDB 支持。
  • 虽然 MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是两者的实现方式不太一样。InnoDB 使用缓冲池(Buffer Pool)缓存数据页和索引页,MyISAM 使用键缓存(Key Cache)仅缓存索引页而不缓存数据页。
  • MyISAM 不支持数据库异常崩溃后的安全恢复,而 InnoDB 支持。
  • InnoDB 的性能比 MyISAM 更强大。

 

慢查询日志有什么用?

  • 性能优化:通过分析慢查询日志,可以发现执行时间长的 SQL,优化索引、调整查询语句或数据库配置。
  • 资源监控:识别占用大量 CPU、内存或 I/O 的查询,避免影响其他业务。
  • 故障排查:定位导致数据库响应延迟的异常 SQL。

binlog 主要记录了什么?

Binlog(二进制日志) 是 MySQL 记录数据库变更的逻辑日志,主要用于:

  • 主从复制:将主库的变更同步到从库。
  • 数据恢复:通过回放 Binlog 恢复数据。
  • 审计:记录所有数据修改操作。

记录内容

  • 记录 SQL 语句本身(如 UPDATE user SET age=20 WHERE id=1)。
  • 记录具体行的变更(如 id=1 的 age 字段从 18 改为 20)。

特点

  • 逻辑日志:记录的是 SQL 语义,而非物理数据页。
  • 依赖事务:Binlog 按事务提交顺序记录,保证主从一致性。

写入机制

  • 事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到 binlog 文件中。
  • 因为一个事务的 binlog 不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache
  • 我们可以通过binlog_cache_size参数控制单个线程 binlog cache 大小,如果存储内容超过了这个参数,就要暂存到磁盘(Swap)。

 

  • write 和 fsync 由参数sync_binlog控制,默认是1
  • write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快
  • fsync,才是将数据持久化到磁盘的操作

redo log 如何保证事务的持久性?    

Redo Log(重做日志) 是 InnoDB 的物理日志,用于保证事务的持久性(Durability)。其核心机制是 Write-Ahead Logging (WAL)

  1. 写日志先于写数据
    • 事务修改数据时,先将操作记录到 Redo Log 缓冲区(InnoDB 的 ib_logfile 文件)。
    • Redo Log 缓冲区满或检查点触发时,才会将日志刷盘。
    • 数据页的修改先暂存在 Buffer Pool,再异步刷盘到磁盘。
  2. 崩溃恢复
    • 如果数据库崩溃,重启时通过 Redo Log 重做(Redo)未完成的事务,确保数据一致性。

如何保证持久性?

  • 事务提交时:必须确保 Redo Log 已写入磁盘(fsync),才能返回成功。
  • 检查点(Checkpoint):定期将内存中的脏页(已修改的页)刷盘,并记录检查点位置,减少崩溃恢复时需要重做的日志量。

页修改之后为什么不直接刷盘呢?刷盘时机

  • MySQL 中数据是以页为单位,查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。
  • 后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。
  • 更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。
  • 然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到 redo log 文件里。每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成。

                 

 

原因

  1. 性能问题
    • 直接刷盘会导致频繁的磁盘 I/O,显著降低写入性能。
  2. 缓冲池(Buffer Pool)的作用
    • 数据页的修改首先暂存在内存中的 Buffer Pool。
    • 通过批量刷盘(如组提交 Group Commit)减少 I/O 开销。
  3. Redo Log 的保障
    • 即使系统崩溃,Redo Log 可以重做未持久化的修改,确保数据不丢失。

刷盘时机

  • Buffer Pool 中的脏页达到阈值(如 innodb_max_dirty_pages_pct)。

  • 检查点触发 ,因为InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。

  • 服务器正常关闭时。

  • 当事务提交时,log buffer 里的 redo log 会被刷新到磁盘(可以通过innodb_flush_log_at_trx_commit参数控制)默认 1,提交时刷盘。

    innodb_flush_log_at_trx_commit 的值有 3 种,也就是共有 3 种刷盘策略:

  1. 0:设置为 0 的时候,表示每次事务提交时不进行刷盘操作。这种方式性能最高,但是也最不安全,因为如果 MySQL 挂了或宕机了,可能会丢失最近 1 秒内的事务。
  2. 1:设置为 1 的时候,表示每次事务提交时都将进行刷盘操作。这种方式性能最低,但是也最安全,因为只要事务提交成功,redo log 记录就一定在磁盘里,不会有任何数据丢失。
  3. 2:设置为 2 的时候,表示每次事务提交时都只把 log buffer 里的 redo log 内容写入 page cache(文件系统缓存)。page cache 是专门用来缓存文件的,这里被缓存的文件就是 redo log 文件。这种方式的性能和安全性都介于前两者中间。

binlog 和 redolog 有什么区别?

  • 写入时机不同:redo log 在事务执行过程中可以不断写入,而 binlog 只有在提交事务时才写入。
  • Binlog 是逻辑日志,数据恢复,保证数据一致性Redo Log 是物理日志,崩溃恢复,保证事务持久性

两阶段提交

  • 两阶段提交是解决两份日志之间的逻辑一致问题:比如 执行过程中写完 redo log 日志后,binlog 日志写期间发生了异常,由于 binlog 没写完就异常,这时候 binlog 里面没有对应的修改记录。因此,之后用 binlog 日志恢复数据时,就会少这一次更新,而原库因为 redo log 日志崩溃恢复,恢复出来的数据不一致。
  • 解决方案:将 redo log 的写入拆成了两个步骤preparecommit,这就是两阶段提交
  • 使用两阶段提交后,写入 binlog 时发生异常,但是因为 MySQL 根据 redo log 日志崩溃恢复时,发现 redo log 还处于prepare阶段,并且没有对应 binlog 日志,就会回滚该事务。

Undo log (回滚日志)

每一个事务对数据的修改都会被记录到 undo log ,当执行事务过程中出现错误或者需要执行回滚操作的话,MySQL 可以利用 undo log 将数据恢复到事务开始之前的状态。

MySQL InnoDB 引擎使用 undo log(回滚日志) 来保证事务的原子性

undo log 属于逻辑日志,记录的是 SQL 语句

比如说事务执行一条 DELETE 语句,那 undo log 就会记录一条相对应的 INSERT 语句。同时,undo log 的信息也会被记录到 redo log 中,因为 undo log 也要实现持久性保护

并且,undo-log 本身是会被删除清理的,例如 INSERT 操作,在事务提交之后就可以清除掉了;UPDATE/DELETE 操作在事务提交不会立即删除,会加入 history list,由后台线程 purge 进行清理。

undo log 如何保证事务的原子性?

Undo Log 记录数据修改前的旧值,用于事务回滚和 MVCC:

  1. 事务回滚
    • 当事务执行 ROLLBACK 或因错误终止时,通过 Undo Log 将数据恢复到修改前的状态。
  2. MVCC 读一致性
    • 读操作通过 Undo Log 访问历史版本数据,避免读到未提交或已回滚的修改。
  3. 原子性保证
    • 如果事务未提交,其他事务无法看到其修改(通过 Undo Log 的版本控制)。
    • 事务回滚时,通过 Undo Log 撤销所有已做的修改。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词