当前位置: 首页 > >

mysql 查看函数fsync_如何用好 MySQL?万字详解其复杂原理

发布时间:


来源 | 简书? ?作者? | 七把刀
链接 | https://www.jianshu.com/p/d4cc0ea9d097
编辑 | 深度学*这件小事公众号

MySQL InnoDB 引擎现在广为使用,它提供了事务,行锁,日志等一系列特性,本文分析下 InnoDB 的内部实现机制,MySQL 版本为 5.7.24,操作系统为 Debian 9。
MySQL InnoDB 的实现非常复杂,本文只是总结了一些皮毛,希望以后能够研究的更加深入些。
???1、InnoDB 架构

Innodb 架构图
InnoDB 的架构分为两块:内存中的结构和磁盘上的结构。InnoDB 使用日志先行策略,将数据修改先在内存中完成,并且将事务记录成重做日志(Redo Log),转换为顺序IO高效的提交事务。
这里日志先行,说的是日志记录到数据库以后,对应的事务就可以返回给用户,表示事务完成。但是实际上,这个数据可能还只在内存中修改完,并没有刷到磁盘上去。内存是易失的,如果在数据落地前,机器挂了,那么这部分数据就丢失了。
InnoDB 通过 redo 日志来保证数据的一致性。如果保存所有的重做日志,显然可以在系统崩溃时根据日志重建数据。
当然记录所有的重做日志不太现实,所以 InnoDB 引入了检查点机制。即定期检查,保证检查点之前的日志都已经写到磁盘,则下次恢复只需要从检查点开始。
???2、InnoDB 内存中的结构
内存中的结构主要包括 Buffer Pool,Change Buffer、Adaptive Hash Index以及 Log Buffer 四部分。
如果从内存上来看,Change Buffer 和 Adaptive Hash Index 占用的内存都属于 Buffer Pool,Log Buffer占用的内存与 Buffer Pool独立。
Buffer Pool
缓冲池缓存的数据包括Page Cache、Change Buffer、Data Dictionary Cache等,通常 MySQL 服务器的 80% 的物理内存会分配给 Buffer Pool。
基于效率考虑,InnoDB中数据管理的最小单位为页,默认每页大小为16KB,每页包含若干行数据。
为了提高缓存管理效率,InnoDB的缓存池通过一个页链表实现,很少访问的页会通过缓存池的 LRU 算法淘汰出去。
InnoDB 的缓冲池页链表分为两部分:New sublist(默认占5/8缓存池) 和 Old sublist(默认占3/8缓存池,可以通过 innodb_old_blocks_pct修改,默认值为 37),其中新读取的页会加入到 Old sublist的头部,而 Old sublist中的页如果被访问,则会移到 New sublist的头部。
缓冲池的使用情况可以通过?
show engine innodb status
?命令查看。其中一些主要信息如下:

----------------------
?5、InnoDB 和 ACID 模型
事务有 ACID 四个属性, InnoDB 是支持事务的,它实现 ACID 的机制如下:
Atomicity
innodb的原子性主要是通过提供的事务机制实现,与原子性相关的特性有:
Autocommit 设置。
COMMIT 和 ROLLBACK 语句(通过 Undo Log实现)。
Consistency
innodb的一致性主要是指保护数据不受系统崩溃影响,相关特性包括:
InnoDB 的双写缓冲区(doublewrite buffer)。
InnoDB 的故障恢复机制(crash recovery)。
Isolation
innodb的隔离性也是主要通过事务机制实现,特别是为事务提供的多种隔离级别,相关特性包括:

Autocommit设置。

SET ISOLATION LEVEL 语句。

InnoDB 锁机制。


Durability
innodb的持久性相关特性:

Redo log。

双写缓冲功能。

可以通过配置项 innodb_doublewrite 开启或者关闭。

配置 innodb_flush_log_at_trx_commit。

用于配置innodb如何写入和刷新 redo 日志缓存到磁盘。

默认为1,表示每次事务提交都会将日志缓存写入并刷到磁盘。

innodb_flush_log_at_timeout 可以配置刷新日志缓存到磁盘的频率,默认是1秒。

配置 sync_binlog。

用于设置同步 binlog 到磁盘的频率,为0表示禁止MySQL同步binlog到磁盘,binlog刷到磁盘的频率由操作系统决定,性能最好但是最不安全。

为1表示每次事务提交前同步到磁盘,性能最差但是最安全。

MySQL文档推荐是 sync_binlog 和 innodb_flush_log_at_trx_commit 都设置为 1。

操作系统的 fsync 系统调用。

UPS设备和备份策略等。



参考资料
https://blog.jcole.us/innodb/
https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html
http://ourmysql.com/archives/1228


??为您推荐雷军 1994 年写的代码,不服不行MIT最新深度学*入门课,安排起来!有了这个神器,轻松用 Python 写个 App「最全」实至名归,NumPy 官方早有中文教程我为什么鼓励你读计算机领域的博士?






友情链接: