mysql学习内容1

1、sql执行流程

我们的系统通过一个数据库连接发送到了MySQL上,然后肯定会经过SQL接口、解析器、优化器、执行器几个环节,解析SQL语句,生成执行计划,接着去由执行器负责这个计划的执行,调用InnoDB存储引擎的接口去执行。

 

1、用户发送请求到tomcat中开启一个线程执行sql语句时,首先从数据库连接池中获取一个数据库连接。(常见的数据库连接池有DBCP,C3P0,Druid)。

2、多个系统要与mysql数据库建立很多个连接,Mysql也必然要维护与系统之间的多个连接,Mysql自身也有一个连接池(其维护了与系统之间的多个数据库连接)。

3、Mysql的一个线程获取到要执行SQL,将SQL语句交给SQL接口去执行。

4、SQL接口将SQL交给SQL解析器,解析器根据SQL语法规则对其进行解析。

5、解析完后,会找查询优化器选择最优的查询路径。查询优化器会针对你编写的几十行、几百行甚至上千行的复杂SQL语句生成查询路径树,然后从里面选择一条最优的查询路径出来。

6、执行器就会去根据我们的优化器生成的一套执行计划,然后不停的调用存储引擎的各种接口去完成SQL语句的执行计划,大致就是不停的更新或者提取一些数据出来。

 

2、InnoDB的重要内存结构:缓冲池

InnoDB存储引擎中有一个非常重要的放在内存里的组件,就是缓冲池(Buffer Pool),这里面会缓存很多的数据,以便于以后在查询的时候,万一你要是内存缓冲池里有数据,就可以不用去查磁盘了,先看看数据是否在缓冲池里,如果不在的话,那么会直接从磁盘里加载到缓冲池里来,而且接着还会对这行记录加独占锁。

 

3、undo日志文件:如何让你更新的数据可以回滚?

为了考虑到未来可能要回滚数据的需要,这里会把你更新前的值写入undo日志文件

4、更新buffer pool中的缓存数据

当我们把要更新的那行记录从磁盘文件加载到缓冲池,同时对他加锁之后,而且还把更新前的旧值写入undo日志文件之后,我们就可以正式开始更新这行记录了,更新的时候,先是会更新缓冲池中的记录,此时这个数据就是脏数据了。

为什么是脏数据?因为内存的数据更改了,还没有同步到磁盘中,磁盘上的数据还是原来的值。

 

5、Redo Log Buffer:万一系统宕机,如何避免数据丢失?

已经把内存里的数据进行了修改,但是磁盘上的数据还没修改那么此时万一MySQL所在的机器宕机了,必然会导致内存里修改过的数据丢失,这可怎么办呢?

这个时候,就必须要把对内存所做的修改写入到一个Redo Log Buffer里去,这也是内存里的一个缓冲区,是用来存放redo日志的。

 

6、如果还没提交事务,MySQL宕机了怎么办?

在数据库中,哪怕执行一条SQL语句,其实也可以是一个独立的事务,只有当你提交事务之后,SQL语句才算执行结束。

到目前为止,其实还没有提交事务,那么此时如果MySQL崩溃,必然导致内存里Buffer Pool中的修改过的数据都丢失,同时你写入Redo Log Buffer中的redo日志也会丢失。

 

那么此时数据丢失要紧吗?

其实是不要紧的,因为你一条更新语句,没提交事务,就代表他没执行成功,此时MySQL宕机虽然导致内存里的数据都丢失了,但是你会发现,磁盘上的数据依然还停留在原样子。

7、提交事务的时候将redo日志写入磁盘中

我们想要提交一个事务了,此时就会根据一定的策略把redo日志从redo log buffer里刷入到磁盘文件里去。

此时这个策略是通过innodb_flush_log_at_trx_commit来配置的,他有几个选项。

策略1:

参数的值设置为0,提交事务不会把redo log buffer里的数据刷入磁盘文件,此时提交事务了,结果mysql宕机了,然后此时内存里的数据全部丢失。

相当于你提交事务成功了,但是由于MySQL突然宕机,导致内存中的数据和redo日志都丢失了,我们看下图:

 

策略2:

参数的值设置为1,提交事务,就必须把redo log从内存刷入到磁盘文件里去,只要事务提交成功,那么redo log就必然在磁盘里了,我们看下图:

 

只要提交事务成功之后,redo日志一定在磁盘文件里,此时你肯定会有一条redo日志说了。

我们看下图,提交事务之后,可能处于的一个状态。

 

如果说提交事务后处于上图的状态,然后mysql系统突然崩溃了,此时会如何?会丢失数据吗?

肯定不会啊,因为虽然内存里的修改成name=xxx的数据会丢失,但是redo日志里已经说了,对某某数据做了修改name=xxx。

所以此时mysql重启之后,他可以根据redo日志去恢复之前做过的修改,我们看下图。

 

策略3:

参数的值设置为2,他的意思就是,提交事务的时候,把redo日志写入磁盘文件对应的os cache缓存里去,而不是直接进入磁盘文件,可能1秒后才会把os cache里的数据写入到磁盘文件里去。

这种模式下,你提交事务之后,redo log可能仅仅停留在os cache内存缓存里,没实际进入磁盘文件,万一此时你要是机器宕机了,那么os cache里的redo log就会丢失,同样会让你感觉提交事务了,结果数据丢了。

 

三种redo日志刷盘策略到底选择哪一种?

也就是说,提交事务的时候,redo日志必须是刷入磁盘文件里的。

这样可以严格的保证提交事务之后,数据是绝对不会丢失的,因为有redo日志在磁盘文件里可以恢复你做的所有修改。

如果要是选择0的话,可能你提交事务之后,mysql宕机,那么此时redo日志没有刷盘,导致内存里的redo日志丢失,你提交的事务更新的数据就丢失了;

如果要是选择2的话,如果机器宕机,虽然之前提交事务的时候,redo日志进入os cache了,但是还没进入磁盘文件,此时机器宕机还是会导致os cache里的redo日志丢失。

所以对于数据库这样严格的系统而言,

一般建议redo日志刷盘策略设置为1,保证事务提交之后,数据绝对不能丢失。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值