QPS/TPS

qps:query per second 每秒处理多少个请求
tps:transaction per second 每秒处理多少个事务,一个事务里可能多个sql

查询语句经历的流程

  1. 用数据库连接池建立连接
  2. 数据库服务器由sql接口获取sql语句
  3. SQL解析器解析sql
  4. 查询优化器优化出最优路径,例如select name from user where id=8,我是先把所有name都拿到再去找id为8的还是我先定位出id为8的一条数据,再去拿name字段
  5. 执行器调用sql完成语句到存储引擎
  6. 存储引擎通过规则去内存或磁盘或缓存取数据

image.png

InnoDB存储引擎

缓冲池

buffer pool,查询的时候先从缓存池中取,如果缓冲池没有才去磁盘文件中取
image.png

修改语句经历的流程

例:update user set name=’wrx’ where id=10

  1. 引擎先看看user表id=10的数据有没有,有的话是不是在缓存池中,不在,则把数据加载到缓存池并且加锁
  2. 把name从xxx改成wrx,把原来的值xxx和id=10这些信息,都放到undo日志文件中去,undo日志就是用于事务的回滚
  3. 刚才把xxx改成wrx,只是把缓存池中的数据改了,没有真正的落盘,现在缓存池中应该叫脏数据
  4. redo log buffer开始工作,redo日志也是在缓冲区,就是记录下对什么数据做了什么修改
  5. 提交事务把redo日志写入磁盘中,通过配置innodb_flush_log_at_trx_commit策略实现

    innodb_flush_log_at_trx_commit=0

    提交事务时,不会把redo log buffer里的数据刷入到磁盘文件中,如果宕机了内存数据全部丢失
    image.png

    innodb_flush_log_at_trx_commit=1

    提交事务必须把redo log从缓存区刷到磁盘中去,只要事务提交成功,redo log必然在磁盘里,如果此时系统故障奔溃怎么办?虽然缓冲池的数据没有了,但是redo日志已经提交到了磁盘中,mysql重启后,根据redo日志去恢复之前做过的修改
    image.png

    innodb_flush_log_at_trx_commit=2

    提交事务时,把redo日志写入磁盘文件的os cache缓存里去,不是直接进入磁盘文件,要1秒左右后才会把os cache里的数据写入到磁盘文件里去。会出现一种情况,redo log在os cache里没有写入磁盘中,就宕机了,os cache里的redo就消失,事务是提交了,但没有修改成数据
    image.png

    binlog

    概念

    redo log是偏向物理性质的重做日志,记录类似:对那个数据页中的什么记录,做了什么修改
    binlog是归档日志,偏向逻辑性的日志,类似于:对users表中id10的一行数据做了更新操作,更新以后值是什么;它不是innodb存储引擎特有的日志,是属于mysql server自己的日志文件,也是提交事务时把binlog写入磁盘
    image.png

    入盘策略

    sync_binlog=0,默认

    当事务提交时,先刷入os cache,如果宕机,binlog丢失
    image.png

    sync_binlog=1

    提交事务时,强制刷入到磁盘文件中,宕机不丢失
    image.png

    binlog和redolog完成事务提交

    把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入redo log日志文件里,同时在redo log日志文件里写入一个commit标记
    image.png

    commit标记意义

    保持redoLog和binLog的最终一致性,5/6/7,任何一个步骤宕机,都不能确保最终一致性,就确定事务是提交失败的。

    image.png

    内存中数据刷入磁盘

    mysql会启动一个io线程,把buffer pool中修改后的数据刷入磁盘中。哪怕是宕机也没关系,有redoLog和binLog的存在能处理