1.如果我们想要执行一行SQL,例如 update users set name = lisi where id = 10
那么该段SQL会如何去执行呢?
先从java系统使用驱动器跟MySQL建立连接,然后走SQL接口,解析器,优化器,执行器,执行器执行最优方案调用存储引擎的接口直至完成SQL语句
2.innodb的重要内存结构:缓冲池(buffer poll)
因为缓冲池会缓存大量的数据,所有MySQL会先在缓冲池中寻找id= 10的字段是否存在,存在则使用,不存在则从磁盘中将数据缓存到缓存池中并且加上独占锁,因为我们期望在这之中只有我们才能对id=10这个字段的信息进行操作
2.undo日志:回滚数据时使用
我们都知道MySQL是有事务这个说法的,直到你提交事务这段SQL才算结束,那么在事务提交之前都可以进行回滚,回滚到旧数据,旧数据我们就会存储到undo日志中去
3.当我们同步了缓存数据,也写好了undo日志之后就可以更新buffer poll中的数据了,但此时更新过后name=lisi将会是脏数据,因为内存数据跟磁盘数据不相符
4.Redo Log Buffer:如果系统宕机如何避免数据的丢失
Redo Log Buffer中会记录对内存文件修改的日志(比如将id=10的name字段修改为lisi就会记录在其中),但是它本身也是在内存中的一个缓冲区,系统宕机依旧会导致数据的丢失,那么这个Redo Log Buffer是如何做到避免数据丢失这一点呢?
5.如果在事务提交之前MySQL宕机了会有什么影响吗
其实每一句SQL都可以看作是一个事务,这个事务还没有提交就宕机就代表
内存缓冲的数据将会丢失,丢失了要紧吗?没有关系啊,因为MySQL是在我们提交事务之前宕机的,虽然宕机会导致缓冲区的数据丢失,也就是name更新为lisi会失效,但我们没有提交事务其本身就代表这句SQL没有执行成功,我们重启之后会看见数据还是老数据 name=zhangsan,所以说此时的MySQL宕机没有问题
6.但当我们想要提交事务的时候 老子就是要数据不丢失 用Redo Log Buffer咋整
redo日志会按照一定的策略将Redo Log Buffer刷到磁盘文件中去
这个策略就是innodb-flush-log-at-trx-commit 他有三个值0,1,2 代表着不同的策略
参数为0的时候,就算你提交了事务Redo Log Buffer也不会将日志刷入到磁盘中去,所以你提交完事务此时宕机的话,内存数据将会丢失
参数为1的话,只要你提交了事务,只要事务提交成功,那么必定会将redo日志刷入磁盘文件,此时系统崩溃也没事不会造成数据的丢失,系统会按照redo日志里的信息去redo系统
参数为2的话,会先将数据刷入到一个叫 os cache的缓存中去,可能过一秒的样子再刷入到磁盘日志文件中去,也就是参数为0的优化版本,如果宕机丢失数据也只是丢失os cache中的数据,不会像参数为0的时候数据全部丢失