哪些网站可以注册邮箱,南通专业企业门户网站设计,深圳鼎诚网站建设,上海土地建设官方网站MySQL中一条SQL语句的执行过程发布时间#xff1a;2018-11-24 18:35,浏览次数#xff1a;390, 标签#xff1a;MySQLSQL查询语句的执行顺序#xff1a;#xff11;.客户端通过TCP连接发送连接请求到mysql连接器#xff0c;连接器会对该请求进行权限验证及连接资源分配(ma…MySQL中一条SQL语句的执行过程发布时间2018-11-24 18:35,浏览次数390, 标签MySQLSQL查询语句的执行顺序.客户端通过TCP连接发送连接请求到mysql连接器连接器会对该请求进行权限验证及连接资源分配(max_connections8小时超时).建立连接后客户端发送一条语句mysql收到该语句后通过命令分发器判断其是否是一条select语句如果是在开启查询缓存的情况下先在查询缓存中查找该SQL是否完全匹配如果完全匹配验证当前用户是否具备查询权限如果权限验证通过直接返回结果集给客户端该查询也就完成了。如果不匹配继续向下执行。(注意此步并不做词法及语法分析也就是用不到分析器这块原来我也很疑惑如果不做分析mysql怎么知道我要查什么解释如下{MySQL将缓存存放在一个引用表中通过一个哈希值引用这个哈希值包括了以下因素即查询本身、当前要查询的数据库、客户端协议的版本等一些其他可能影响返回结果的信息。当判断缓存是否命中时MySQL不会进行解析查询语句而是直接使用SQL语句和客户端发送过来的其他原始信息。所以任何字符上的不同例如空格、注解等都会导致缓存的不命中。}其实说白了大概就是拿着你的SQL和原始缓存的SQL比对)3.如果在查询缓存中未匹配成功则将语句交给分析器作语法分析MySQL需要知道到底要查哪些东西如果语法不对就会返回语法错误中断查询。4.分析器的工作完成后将语句传递给预处理器检查数据表和数据列是否存在解析别名看是否存在歧义等5.语句解析完成后MySQL就知道要查什么了之后会将语句传递给优化器进行优化(通过索引选择最快的查找方式)并生成执行计划。6.之后交给执行器去具体执行该语句在执行之前会先检查该用户是否具有查询权限如果有继续执行该语句。执行器开始执行后会逐渐将数据保存到结果集中同时会逐步将数据缓存到查询缓存中最终将结果集返回给客户端。(缓存到查询缓存受到几个参数的影响1.query_cache_type 是否打开查询缓存,默认为OFF 2.query_cache_size:查询缓存使用的总内存空间,默认值为1M3.query_cache_limit对于大于该值的结果集不会被缓存默认值1M在8.0版本后该参数被移除了)(如果该SQL执行过程中超过了慢查询阀值该SQL会被记录到慢查询日志中)#######################################################一条更新语句的执行顺序.客户端通过TCP连接发送连接请求到mysql连接器连接器会对该请求进行权限验证及连接资源分配(max_connections8小时超时)2.建立连接后客户端发送一条语句mysql收到该语句后通过命令分发器判断其是否是一条更新语句如果是则直接发送给分析器做语法分析。3.分析器阶段MySQL需要知道到底要查哪些东西如果语法不对就会返回语法错误中断查询4.分析器的工作完成后将语句传递给预处理器检查数据表和数据列是否存在解析别名看是否存在歧义等5.语句解析完成后MySQL就知道要查什么了之后会将语句传递给优化器进行优化(通过索引选择最快的查找方式)并生成执行计划。6.执行器根据生成的执行计划去opentable此时会先去查看该表上是否有元数据(MDL)排他锁(如果有元数据共享锁则无影响)如果有元数据排他锁则事物被阻塞进入等待状态(时间由lock_wait_timeout决定默认是一年。。。。)等元数据锁被释放继续执行。如果无元数据锁或者是有元数据共享锁则该事务在表上加元数据共享锁(因为元数据共享读锁之间是不冲突的如果表上有元数据共享锁我们执行altertable这样的DDL语句时会进入等待状态因为DDL语句需要在表上加元数据排他锁)7.进入引擎层(默认innodb)去innodb_buffer_pool里面的data dictionary得到表得相关信息8.根据表信息去innodb_buffer_pool里面的lockinfo查看是否有相关的锁信息如果有则等待(因为要加排它锁)如果没有则加排它锁更新lock info。9.取读取相关数据页到innodb_buffer_pool中(如果数据页本身就在缓存中则不用从硬盘读取)10.将页中的原始数据(快照)保存到undo log buffer中(undo log buffer会以相关参数定义的规则进行刷盘操作写入到undotablespace中)11.在innodb_buffer_pool中将相关页面更新该页变成脏页(脏页会以相关参数定义的规则进行刷盘操作写入所属表空间中)12.页面修改完成后会把修改后的物理页面保存到redo log buffer中(redo logbuffer会以相关参数定义的规则进行刷盘操作写入到redo tablespace中)13.如果开启binlog则更新数据的逻辑语句也会记录在binlog_cache中(binlog会以相关参数定义的规则进行刷盘操作写入到binlogfile 中)14.如果该表上有二级索引并且本次操作会影响到二级索引则会把相关的二级索引修改写入到innodb_buffer_pool中的changebuffer里(change buffer 会以相关参数定义的规则进行刷盘操作写入所属表空间中)15.前期的准备工作到此已经做完了之后便是事务的commit或者rollback操作。一般情况下执行的是commit操作16.执行commit操作后(mysql默认开启自动提交如果手动开始事务begin则需要显示提交commit)由于要保证redolog与binlog的一致性redolog采用2阶段提交方式。17.将undo log buffer及redo logbuffer刷盘(innodb_flush_log_at_trx_commit1)并将该事务的redolog标记为prepare状态。18.将binlog_cache数据刷盘(sync_binlog1)19.如果开启了主从结构此时会将binlog_cache中的信息通过io线程发送给从机如果开启了半同步复制则需要等待从机落盘(relaylog)并反馈。如果是异步复制则无需等待(默认是异步复制)20.待binlog落盘完成再将redolog中该事务信息标记为commit释放相关锁资源。此时一个更新事务的操作已经完成返回给客户端成功更新提示。21.标记undolog中该事务修改页的原始快照信息为delete当无其他事务引用该原始数据时(MVCC)再将其删除22.如果此时触发了脏页刷盘操作会先将脏页写入到double writebuffer中(防止写入过程中出现断页因为mysql页面默认为16Klinux操作系统最大为4K如果写了8K时系统挂了这个数据页将不完整标记为损坏)然后再写到期所在表空间的相应位置。