MySQL初探
与MySQL打交道
在Java工程师眼中,MySQL不外乎就是具备建库、建表、建索引,执行增删改查CRUD等功能。同时还会时不时遇到一些小麻烦,例如死锁、报错和事务问题等。

Java应用在底层与数据库建立网络连接,并通过代码执行SQL
查询。

但是,通常应用不只有一个连接请求,数据库也不只服务于某个连接。以Java中的Tomcat为例,它会通过多个线程来处理并发请求,达到资源利用的效率最大化。
如果每处理一个请求就创建一个数据库连接,用完之后再销毁,效率会极其低下,这就好比公交车每上一个人就关一下门,每吃一口饭就洗一次碗。为了解决这种问题,数据库连接池诞生了。


连接池的核心任务就是维护与多个系统之间的多个连接。

MySQL架构设计
SQL
语句一般执行的过程如下。
由线程来处理网路哟连接请求(这是不变的前提条件和原则)。
SQL
接口负责处理接收到的SQL语句。查询解析器让MySQL能看懂
SQL
语句。选择最优的查询路径。
调用存储引擎接口,执行
SQL
查询。根据执行计划调用存储引擎接口。

问题
MySQL有哪些存储引擎?
分别适用于什么场景?
InnoDB存储引擎的架构
在MySQL中,一条更新语句的执行过程如下。
如果缓冲池内有数据,就不用再去查询磁盘,否则就从磁盘加载,同时加锁。
把更新之前的值写入到
undo
日志文件。更新
buffer pool
中的缓存数据。Redo Log Buffer
防止宕机时数据丢失,用来恢复更新过的数据。提交事务时将
redo
日志写入磁盘。innodb_flush_log_at_trx_commit = 0
:提交事务时不把redo log buffer
刷入磁盘。innodb_flush_log_at_trx_commit = 1
:提交事务时必须把redo log buffer
刷入磁盘。innodb_flush_log_at_trx_commit = 2
:提交事务时把redo log buffer
刷入os cache
。

问题
这三种
redo
日志刷盘策略,应该选择哪一种?每一种刷盘策略的优缺点是什么?为什么?
MySQL binlog
binlog
是一种归档日志,它不是redo log
,但它属于MySQL系统。提交事务时,会同时将提交内容写入binlog
。
binlog
的刷盘策略如下。
sync_binlog = 0
:binlog
不直接写入磁盘,而是先写到os cache
。sync_binlog = 1
:binlog
强制写入到磁盘文件。
当binlog
写入磁盘后,会将binlog
文件名及更新数据在binlog
里的位置offset
都写入到redo log
,并在redo log
中写入一个commit
标记,保持两种日志一致。

总之,InnoDB
存储引擎有如下特点。
主要包含一些
buffer pool
、redo log buffer
等缓存数据。同时还包含一些
undo
日志文件、redo
日志文件。binlog
是属于MySQL系统级别的日志。执行更新时,每条
SQL
语句都会对应修改buffer pool
、redo log buffer
、undo
日志。提交时,一定会把
redo
日志、binlog
写入磁盘,同时保持redo
日志和binlog
的一致。最后,后台
I/O
线程会随机把buffer pool
里的脏数据刷入磁盘。
问题
为什么MySQL在更新数据时,要处理包括
buffer pool
、undo log
、redo log
、binlog
、事务提交、脏数据、随机刷盘这么多事情?为什么最关键同步磁盘数据,要通过
I/O
随机刷盘实现?为什么执行完
SQL
语句不直接更新磁盘数据?
关注公众号后回复 mysql
即可获得MySQL系统化工程实践
栏目剩余文章的访问密码。
