一个查询语句的例子
在执行下面这个查询语句时的执行的流程是怎么样的?
MySQL> select * from t where id=1;执行器的执行流程是这样的:
1.调用 InnoDB 引擎接口取这个表的第一行 , 判断 id 值是不是 1 , 如果不是则跳过 , 如果是则将这行存在结果集中;
2.调用引擎接口取“下一行” , 重复相同的判断逻辑 , 直到取到这个表的最后一行 。
3.执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端 。
一个 SQL 的执行过程为:
1.连接2.查询缓存3.词法分析4.语法分析5.语义分析6.构造执行树7.生成执行计划8.执行器执行计划9.返回执行结果一个更新语句的例子
更新语句:
mysql> update table set c = c+1 where id = 2;
执行流程:
1.执行器先找引擎取 ID=2 这一行 。ID 是主键 , 引擎直接用树搜索找到这一行 。如果 ID=2 这一行所在的数据页本来就在内存中 , 就直接返回给执行器;否则 , 需要先从磁盘读入内存 , 然后再返回 。2.执行器拿到引擎给的行数据 , 把这个值加上1 , 比如原来是N , 现在就是N+1 , 得到新的一行数据 , 再调用引擎接口写入这行新数据 。3.引擎将这行新数据更新到内存中 , 同时将这个更新操作记录到 redo log 里面 , 此时 redo log 处于 prepare 状态 。然后告知执行器执行完成了 , 随时可以提交事务 。4.执行器生成这个操作的 binlog , 并把 binlog 写入磁盘 。5.执行器调用引擎的提交事务接口 , 引擎把刚刚写入的 redo log 改成提交(commit)状态 , 更新完成 。query和update执行流程不一样的在于 update涉及了日志模块 , binlog (归档日志)和 redo log (重做日志) 。
两阶段提交
redo log 的写入拆成了两个步骤:prepare 和 commit , 这就是"两阶段提交" 。
为什么必须有“两阶段提交”呢?这是为了让两份日志之间的逻辑一致 。
由于 redo log 和 binlog 是两个独立的逻辑 , 如果不用两阶段提交 , 要么就是先写完 redo log 再写 binlog , 或者采用反过来的顺序 。我们看看这两种方式会有什么问题 。
仍然用前面的 update 语句来做例子 。假设当前 ID=2 的行 , 字段 c 的值是 0 , 再假设执行 update语句过程中在写完第一个日志后 , 第二个日志还没有写完期间发生了 crash , 会出现什么情况呢?
情况 1 :先写 redo log 后写 binlog 。
假设在 redo log 写完 , binlog 还没有写完的时候 , MySQL 进程异常重启 。由于我们前面说过的 , redo log 写完之后 , 系统即使崩溃 , 仍然能够把数据恢复回来 , 所以恢复后这一行 c 的值是 1 。但是由于 binlog 没写完就 crash 了 , 这时候 binlog 里面就没有记录这个语句 。因此 , 之后备份日志的时候 , 存起来的 binlog 里面就没有这条语句 。然后你会发现 , 如果需要用这个 binlog 来恢复临时库的话 , 由于这个语句的 binlog 丢失 , 这个临时库就会少了这一次更新 , 恢复出来的这一行 c 的值就是 0 , 与原库的值不同 。
情况 2:先写 binlog 后写 redo log 。
如果在 binlog 写完之后 crash , 由于 redo log 还没写 , 崩溃恢复以后这个事务无效 , 所以这一行 c 的值是 0 。但是 binlog 里面已经记录了“把 c 从 0 改成 1”这个日志 。所以 , 在之后用 binlog 来恢复的时候就多了一个事务出来 , 恢复出来的这一行 c 的值就是 1 , 与原库的值不同 。
可以看到 , 如果不使用“两阶段提交” , 那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致 。
MySQL逻辑架构
MySQL是一个开放源代码的关系数据库管理系统 。原开发者为瑞典的MySQL AB公司 , 最早是在2001年MySQL3.23进入到管理员的视野并在之后获得广泛的应用 。
当MySQL启动(MySQL服务器就是一个进程) , 等待客户端连接 , 每一个客户端连接请求 , 服务器都会新建一个线程处理(如果是线程池的话 , 则是分配一个空的线程) , 每个线程独立 , 拥有各自的内存处理空间 。
推荐阅读
- mysql千万级数据量插入的几种方案耗时,看完就知道如何选择
- MySQL的优化,看这篇文章就够了
- PHP的微服务框架预览
- MySQL性能优化分区之实战
- MacOS下brew安装mysql5.7数据库
- 电商支付架构设计
- 详解Docker架构原理、功能及使用
- mysql导入数据,涉及到时间转换,乱码问题解决
- 如何基于 MySQL 主从模式搭建上万并发的系统架构?
- 你知道CentOS 6和 CentOS 7的区别吗?