|
|
@ -82,6 +82,109 @@
|
|
|
|
- 总结: 对于redo日志的三种刷盘策略, 我们的通常建议是1, 保证事务提交后, 数据绝对不能丢失
|
|
|
|
- 总结: 对于redo日志的三种刷盘策略, 我们的通常建议是1, 保证事务提交后, 数据绝对不能丢失
|
|
|
|
## 4. 聊聊binlog是什么?
|
|
|
|
## 4. 聊聊binlog是什么?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 binlog 日志概念
|
|
|
|
|
|
|
|
- binlog 日志叫做归档日志, 他里面记录的是偏向于逻辑性的日志, 类似于“对users表中的id=10的一行数据做了更新操
|
|
|
|
|
|
|
|
作,更新以后的值是什么”
|
|
|
|
|
|
|
|
- binlog不是InnoDB存储引擎特有的日志文件,是属于mysql server自己的日志文件。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 提交事务, 同时会写入binlog日志
|
|
|
|
|
|
|
|
![写入binlog日志](pic/写入binlog日志.png)
|
|
|
|
|
|
|
|
- 跟InnoDB存储引擎进行交互的组件加入了之前提过的执行器这个组件,
|
|
|
|
|
|
|
|
他会负责跟InnoDB进行交互,包括从磁盘里加载数据到Buffer Pool中进行缓存,包括写入undo日志,包括更新
|
|
|
|
|
|
|
|
Buffer Pool里的数据,以及写入redo log buffer,redo log刷入磁盘,写binlog,等等。
|
|
|
|
|
|
|
|
- 执行器是非常核心的一个组件,负责跟存储引擎配合完成一个SQL语句在磁盘与内存层面的全部数据更新操
|
|
|
|
|
|
|
|
作。
|
|
|
|
|
|
|
|
- 把一次更新语句的执行,拆分为了两个阶段,上图中的1、2、3、4几个步骤,其实本质是你执行这个更新语句的时候干的事。
|
|
|
|
|
|
|
|
- 5和6两个步骤,是从你提交事务开始的,属于提交事务的阶段了。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 binlog日志的刷盘策略分析
|
|
|
|
|
|
|
|
- binlog日志,其实也有不同的刷盘策略,有一个**sync_binlog**参数可以控制binlog的刷盘策略,他的默认值是0,
|
|
|
|
|
|
|
|
此时你把binlog写入磁盘的时候,其实不是直接进入磁盘文件,而是进入os cache内存缓存
|
|
|
|
|
|
|
|
- 如果此时机器宕机,那么你在os cache里的binlog日志是会丢失的
|
|
|
|
|
|
|
|
![binlog日志刷盘](pic/binlog日志刷盘.png)
|
|
|
|
|
|
|
|
- 如果要是把sync_binlog参数设置为1的话,那么此时会强制在提交事务的时候,把binlog直接写入到磁盘文件里去,
|
|
|
|
|
|
|
|
那么这样提交事务之后,哪怕机器宕机,磁盘上的binlog是不会丢失的
|
|
|
|
|
|
|
|
![binlog日志刷盘1](pic/binlog日志刷盘1.png)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 基于binlog和redo log完成事务的提交
|
|
|
|
|
|
|
|
- 当我们把binlog写入磁盘文件之后,接着就会完成最终的事务提交,此时会把**本次更新对应的binlog文件名称**和这次
|
|
|
|
|
|
|
|
**更新的binlog日志在文件里的位置**,都写入到redo log日志文件里去,同时在redo log日志文件里写入一个**commit标记**。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.4 最后一步在redo日志中写入commit标记的意义是什么?
|
|
|
|
|
|
|
|
- 用来保持redo log日志与binlog日志一致的
|
|
|
|
|
|
|
|
- 完整的事物提交成功, 必须是在redo log中写入最终的事务commit标记了,而且redo log里有本次更新对应的日 志,binlog里也有本次
|
|
|
|
|
|
|
|
更新对应的日志 ,redo log和binlog完全是一致的。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.5 后台IO线程随机将内存更新后的脏数据刷回磁盘
|
|
|
|
|
|
|
|
- 已经提交事务, 他已经把内存里的 buffer pool中的缓存数据更新了,同时磁盘里有redo日志和binlog日志都记录的新值,但是磁盘上可能还是旧值?
|
|
|
|
|
|
|
|
- 因为MySQL有一个后台的IO线程,会在之后某个时间里,随机的把内存buffer pool中的修改后的脏数据给刷回到磁 盘上的数据文件里去
|
|
|
|
|
|
|
|
![IO线程随机更新](pic/IO线程随机更新.png)
|
|
|
|
|
|
|
|
- 在你IO线程把脏数据刷回磁盘之前,哪怕mysql宕机崩溃也没关系,因为重启之后,会根据redo日志恢复之前提交事 务做过的修改到内存里去,
|
|
|
|
|
|
|
|
就是id=10的数据的name修改为了xxx,然后等适当时机,IO线程自然还是会把这个修改后的数据刷到磁盘上的数据文件里去的
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 4.6 总结
|
|
|
|
|
|
|
|
- InnoDB存储引擎: buffer pool、redo log buffer等内存里的缓存数据, undo日志文件, redo日志文件, 同时mysql server自己还有 binlog日志文件
|
|
|
|
|
|
|
|
- 在你执行更新的时候,每条SQL语句,都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤
|
|
|
|
|
|
|
|
- 当你提交事务的时候,一定会把redo log刷入磁盘,binlog刷入磁盘,完成redo log中的事务commit标记;最后后台的IO线程会随机的把buffer pool里的脏数据刷入磁盘里去。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 生产经验: 真实生产环境下的数据库机器配置如何规划?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 普通的Java应用系统部署在机器上能抗多少并发?
|
|
|
|
|
|
|
|
- Java应用系统部署的时候常选用的机器配置大致是2核4G和4核8G的较多一些,数据库部署的时候常选用的机器配置最低在8核16G以上,正常在16核32G
|
|
|
|
|
|
|
|
- 一台机器能抗下每秒多少请求,往往是跟你每个请求处理耗费多长时间是关联的
|
|
|
|
|
|
|
|
- 4核8G的机器部署普通的Java应用系统,每秒大致就是抗下几百的并发访问,从每秒一两百请求到每秒七八百请求,都是有可能的,关键是看你每个请求处理需要耗费多长时间。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 高并发场景下,数据库应该用什么样的机器?
|
|
|
|
|
|
|
|
- 往往对一个数据库而言,都是选用8核16G的机器作为起步,最好是选用16核32G的机器更加合适一些,因为数据库需要执行大量的磁盘IO操作,
|
|
|
|
|
|
|
|
他的每个请求都比较耗时一些,所以机器的配置自然需要高一些了
|
|
|
|
|
|
|
|
- 一般8核16G的机器部署的MySQL数据库,每秒抗个一两千并发请求是没问题的,但是如果你 的并发量再高一些,假设每秒有几千并发请求,那么可能数据库就会有点危险了,因为数据库的CPU、磁盘、IO、内存的负载
|
|
|
|
|
|
|
|
都会很高,弄不数据库压力过大就会宕机。
|
|
|
|
|
|
|
|
- 对于16核32G的机器部署的MySQL数据库而言,每秒抗个两三千,甚至三四千的并发请求也都是可以的,但是如果你达到每秒上万请求,
|
|
|
|
|
|
|
|
那么数据库的CPU、磁盘、IO、内存的负载瞬间都会飙升到很高,数据库也是可能会扛不住宕机的。
|
|
|
|
|
|
|
|
- 对于数据库而言,如果可以的话,最好是采用SSD固态硬盘而不是普通的机械硬盘,因为数据库最大的复杂就在于大量的 磁盘IO,他需要大量的读写磁盘文件,
|
|
|
|
|
|
|
|
所以如果能使用SSD固态硬盘,那么你的数据库每秒能抗的并发请求量就会更高一些。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 生产经验:互联网公司的生产环境数据库是如何进行性能测试的?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### QPS和TPS到底有什么区别?
|
|
|
|
|
|
|
|
- QPS,他的英文全称是:Query Per Second。
|
|
|
|
|
|
|
|
- QPS就是说,你的这个数据库每秒可以处理多少个请求,你大致可以理解为,一次请求就是一条SQL语句,也就是说这个数据库每秒可以处理多少个SQL语句
|
|
|
|
|
|
|
|
- TPS,他的英文全称是:Transaction Per Second
|
|
|
|
|
|
|
|
- 其实就是每秒可处理的事务量,这个TPS往往是用在数据库中较多一些,其实从字面意思就能看的出来,他就是说数据库每秒会处理多少次事务提交或者回滚。
|
|
|
|
|
|
|
|
- PS: 不同的服务或者系统, 关注的是QPS还是TPS是不一样的。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### IO相关的压测性能指标
|
|
|
|
|
|
|
|
- IOPS
|
|
|
|
|
|
|
|
- 这个指的是机器的随机IO并发处理的能力,比如机器可以达到200 IOPS,意思就是说每秒可以执行200个随机 IO读写请求
|
|
|
|
|
|
|
|
- 这个指标是很关键的,你在内存中更新的脏数据库,最后都会由后台IO线程在不确定的时间,刷回到磁盘里去,这就是随机IO的过程。
|
|
|
|
|
|
|
|
- 如果说IOPS指标太低了,那么会导致你内存里的脏数据刷回磁盘的效率就会不高。
|
|
|
|
|
|
|
|
- 吞吐量
|
|
|
|
|
|
|
|
- 这个指的是机器的磁盘存储每秒可以读写多少字节的数据量
|
|
|
|
|
|
|
|
- 这个指标也是很关键的,我们平时在执行各种SQL语句的时候,提交事务的时候,其实都是大量的会写redo log之类的日志的,这些日志都会直接写磁盘文件。
|
|
|
|
|
|
|
|
- 一台机器他的存储每秒可以读写多少字节的数据量,就决定了他每秒可以把多少redo log之类的日志写入到磁盘里去。
|
|
|
|
|
|
|
|
- 一般来说我们写redo log之类的日志,都是对磁盘文件进行顺序写入的,也就是一行接着一行的写,不会说进行随机的读写
|
|
|
|
|
|
|
|
- 一般普通磁盘的顺序写入的吞吐量每秒都可以达到200MB左右
|
|
|
|
|
|
|
|
- 所以通常而言,机器的磁盘吞吐量都是足够承载高并发请求的。
|
|
|
|
|
|
|
|
- latency
|
|
|
|
|
|
|
|
- 这个指标说的是往磁盘里写入一条数据的延迟
|
|
|
|
|
|
|
|
- 这个指标同样很重要,因为我们执行SQL语句和提交事务的时候,都需要顺序写redo log磁盘文件,所以此时你写一条日志到磁盘文件里去,
|
|
|
|
|
|
|
|
到底是延迟1ms,还是延迟100us,这就对你的数据库的SQL语句执行性能是有影响的。
|
|
|
|
|
|
|
|
- 一般来说,当然是你的磁盘读写延迟越低,那么你的数据库性能就越高,你执行每个SQL语句和事务的时候速度就会越快。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 压测的时候要关注的其他性能指标
|
|
|
|
|
|
|
|
- CPU负载
|
|
|
|
|
|
|
|
- CPU负载是一个很重要的性能指标,因为假设你数据库压测到了每秒处理3000请求了,可能其他的性能指标都还正常,但是此时CPU负载特别高,
|
|
|
|
|
|
|
|
那么也说明你的数据库不能继续往下压测更高的QPS了,否则CPU是吃不消的
|
|
|
|
|
|
|
|
- 网络负载
|
|
|
|
|
|
|
|
- 这个主要是要看看你的机器带宽情况下,在压测到一定的QPS和TPS的时候,每秒钟机器的网卡会输入多少
|
|
|
|
|
|
|
|
MB数据,会输出多少MB数据,因为有可能你的网络带宽最多每秒传输100MB的数据,那么可能你的QPS到1000的时候,网
|
|
|
|
|
|
|
|
卡就打满了,已经每秒传输100MB的数据了,此时即使其他指标都还算正常,但是你也不能继续压测下去了
|
|
|
|
|
|
|
|
- 内存负载
|
|
|
|
|
|
|
|
- 这个就是看看在压测到一定情况下的时候,你的机器内存耗费了多少,如果说机器内存耗费过高了,说明也不能继续压测下去了
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|