5-03 MySQL底层执行原理
2022-12-11 14:11:57 0 举报
03 MySQL底层执行原理
作者其他创作
大纲/内容
<b>MySQL的内部组件结构</b>
<b><font color="#2196f3">MySQL</font>大体可分为</b> <b><font color="#2196f3">Server层</font></b> <b>和</b> <font color="#2196f3"><b>存储引擎层</b> </font><b>两部分</b>
<a class="link" target="_bank" href="https://www.processon.com/diagraming/6393e4826376895515fa19e1">MySQL的内部组件结构概览图</a>
<b><font color="#2196f3">Server层</font></b>
主要包括<b><font color="#2196f3">连接器</font></b>、<b><font color="#2196f3">查询缓存</font></b>、<b><font color="#2196f3">分析器</font></b>、<b><font color="#2196f3">优化器</font></b>、<b><font color="#2196f3">执行器</font></b>等<br>
<b><font color="#2196f3">涵盖</font></b>MySQL的<b><font color="#2196f3">大多数核心服务</font></b>功能,以及<b><font color="#2196f3">所有的内置函数</font></b>(如<b>日期</b>、<b>时间</b>、<b>数学</b>、<b>加密函数</b>等)
<b><font color="#2196f3">所有跨存储引擎的功能</font></b>都在这一层实现,比如<b>存储过程</b>、<b>触发器</b>、<b>视图</b>等
<b><font color="#2196f3">Store层(存储引擎层)</font></b>
存储引擎层<b><font color="#2196f3">负责数据的存储和提取</font></b>
其<b><font color="#2196f3">架构模式</font></b>是<font color="#2196f3" style="font-weight: bold;">插件式</font><b><font color="#2196f3">的</font></b>,支持 <b>InnoDB</b>、<b>MyISAM</b>、<b>Memory </b>等多个存储引擎
目前<b><font color="#2196f3">最常用</font></b>的存储引擎是<b><font color="#2196f3">InnoDB</font></b>,它从 MySQL <b>5.5.5 版本开始</b>成为了<b>默认存储引擎</b>
<b>Server层内部组件作用</b>
示例表:<font color="#9e9e9e">(应用于下面的所有示例)</font>
<b><font color="#2196f3">连接器</font></b>
由于<b><font color="#2196f3">MySQL</font></b>是<b><font color="#2196f3">开源</font></b>的,它<b><font color="#2196f3">有非常多</font></b>种类的<b><font color="#2196f3">客户端</font></b>:<b>navicat</b>、<b>mysql front</b>、<b>jdbc</b>、<b>SQLyog </b>等
以上这些<b>客户端</b>要向MySQL发起通信都必须先<b>与Server端建立通信连接</b>,而<b><font color="#2196f3">建立连接的工作</font></b>就是<b><font color="#2196f3">由连接器完成</font></b>的。
<b><font color="#2196f3">具体连接过程</font></b>如下:
1)你要先<b>连接到MySQL数据库</b>上,这时候<b>接待你的就是连接器</b>
<b>连接器职责</b><font color="#9e9e9e">(与客户端)</font>:
1. 建立连接
2. 获取权限
3. 维持和管理连接
<b>连接命令</b>如下:
1. 查看MySQL服务是否启动:
<b><font color="#9c27b0">[root@192 ~]#</font> <font color="#0000ff">ps -ef|grep mysql</font></b>
2. 客户端连接Mysql服务:
<font color="#9c27b0"><b>[root@192 ~]#</b></font> <b><font color="#0000ff">mysql ‐h host</font><font color="#4caf50">[数据库地址]</font></b> <b><font color="#0000ff">‐u</font></b> <font color="#4caf50"><b>[用户]</b></font> <b><font color="#0000ff">‐p</font></b> <font color="#4caf50"><b>[密码]</b></font> <b><font color="#0000ff">‐P</font></b> <b><font color="#4caf50">3306</font></b>
连接命令中的 <b>mysql</b> 是客户端工具,<b>用来跟服务端建立连接</b>
1. 完成经典的 TCP 握手
2. 开始认证你的身份<font color="#9e9e9e">(这时候用的就是你输入的用户名和密码)</font>
如果<font color="#f44336">用户名或密码不对</font>,你就会收到一个"<font color="#f44336">Access denied for user</font>"的错误,然后客户端程序结束执行
如果<font color="#4caf50">用户名密码认证通过</font>,连接器会<font color="#00bcd4">到权限表</font>里面<font color="#00bcd4">查出你拥有的权限</font>
之后<font color="#ff9800">这个连接</font>里面的<font color="#ff9800">权限判断逻辑</font>,<font color="#ff9800">都将依赖于此时读到的权限</font>
2)一个<b>用户成功建立连接后</b>
成功建立连接后,<b>MySQL会划出一块用来存放连接的内存区域</b>,并将获取到的<b>用户权限信息也会缓存到当前连接会话</b>
从上可知,<b>即使</b>你用管理员账号对<b>这个用户的权限做了修改</b><font color="#9e9e9e">(会话中缓存的user是不会更新的)</font>,<b>也不会影响已经存在连接的权限</b>
MySQL为什么这么设计?
举例说明:假如正在进行秒杀活动,更新user信息后如果要同步更新会话中缓存的user信息,MySQL为保护隔离进行阻塞所有连接就会出现性能上的短暂假死,从而产生性能波动,这对一个秒杀活动是致命的。
<b>用户权限修改后</b>,如果要使用新的权限设置,只有<b>再新建的连接才会使用新的权限</b>设置
<b>用户的权限表</b>在系统表空间的<b>mysql</b>的<b>user表</b>中
如下图所示:
<b>创建新用户、赋权限、修改user密码:</b>
创建新用户:
<b><font color="#9c27b0">mysql></font><font color="#0000ff"> CREATE USER</font> <font color="#4caf50">'username'@'host'</font> <font color="#0000ff">IDENTIFIED BY</font> <font color="#4caf50">'password'</font><font color="#0000ff">;</font></b>
赋权限,%表示所有(host):
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">grant all privileges on</font> <font color="#4caf50">*.*</font> <font color="#0000ff">to </font><font color="#4caf50">'username'@'%'</font><font color="#0000ff">;</font></b>
刷新数据库:
<b><font color="#9c27b0">mysql></font></b> <b><font color="#0000ff">flush privileges</font></b>
设置用户密码:
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">update user set password=password(”</font><font color="#4caf50">123456</font><font color="#0000ff">″) where user=’</font><font color="#4caf50">root</font><font color="#0000ff">’;</font></b>
查看当前用户的权限:
<b><font color="#9c27b0">mysql></font><font color="#0000ff"> show grants for </font><font color="#4caf50">root@"%"</font><font color="#0000ff">;</font></b>
<b>查看连接当前状态:</b>
<b>连接完成后</b>,如果你<b>没有后续的动作</b>,这个<b>连接就处于空闲状态</b>
可以通过 <b>show processlist 命令查看连接的状态</b>,其中 <b>Command 列显示</b>的就是当前<b>连接状态</b>
<b>命令</b>如下:
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">show processlist;</font></b>
<b>3)连接被断开</b>
客户端如果<b>长时间不发送command</b>到Server端,<b>连接器</b>就会<b>自动将它断开</b>
这里的时间是<b>由参数 wait_timeout() 控制</b>的,<b>默认</b>值是 <b>8h</b>
<b>查看wait_timeout:</b><font color="#9e9e9e">(单位-秒)</font>
<b><font color="#9c27b0">mysql></font><font color="#0000ff"> show global variables like "</font><font color="#4caf50">wait_timeout</font><font color="#0000ff">";</font></b>
<b>设置wait_timeout:</b><font color="#9e9e9e">(单位-秒)</font>
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">set global wait_timeout=</font><font color="#4caf50">28800</font><font color="#0000ff">;</font></b>
在<b>连接被断开之后</b>,客户端<b>再次发送请求</b>的话,就会收到一个<b>错误提醒</b>:<font color="#f44336"> Lost connection to MySQL server during query</font><br>
长连接、短连接:
数据库里面,<b>长连接</b>是指连接成功后,如果<b>客户端持续有请求</b>,则<b>一直使用同一个连接</b>
数据库里面,<b>短连接</b>是指<b>每次执行完很少的几次查询就断开连接</b>,<b>下次查询再重新建立一个</b>
<b>实际开发</b>我们<b>大多数用</b>的都是<b>长连接,</b>通常把长连接放在<b>Pool内</b>进行<b>管理</b>
<b><font color="#e57373">使用长连接存在的问题:</font></b>
1. <b>长连接</b>有时候会<b>导致MySQL占用内存涨的特别快</b>
2. 如果<b>长连接累积下来</b>,可能<b>导致内存占用太大</b>,被系统强行杀掉(<b>OOM</b>),从现象看就是<b>MySQL异常重启</b>了
<font color="#f57c00"><b>这类问题产生的原因:</b></font>
1. 因为MySQL在执行过程中临时使用的内存是管理在连接里面的
2. 这些资源会在连接断开的时候才释放
<b><font color="#4caf50">怎么解决这类问题呢?</font></b>
1. <font color="#4caf50">定期断开长连接</font>:<font color="#00bcd4" style="">使用一段时间</font>或者<font color="#00bcd4">程序里面判断执行过一个占用内存的大查询</font>后断开连接,之后要查询再重建连接
2. <font color="#4caf50">MySQL 5.7 或 更高版本:</font>
可以在<font color="#00bcd4">每次执行一个比较大的操作后</font>,通过 <font color="#00bcd4" style="">mysql_reset_connection </font>来<font color="#00bcd4">重新初始化连接资源</font>
<font color="#00bcd4">这个过程不需要重连和重新做权限验证</font>,<font color="#f57c00">但</font>是会<font color="#f57c00">将连接恢复到刚刚创建完时的状态</font>
<b><font color="#2196f3">查询缓存</font></b>
<b><font color="#2196f3">常用</font>的一些操作<font color="#2196f3">命令</font>:</b>
显示所有数据库
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">show databases;</font></b>
打开数据库
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">use dbname;</font></b>
显示数据库mysql中所有的表
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">show tables;</font></b>
显示表mysql数据库中user表的列信息<br>
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">describe user;</font></b>
<b>连接建立完成后的 <font color="#2196f3">select 执行逻辑</font>:</b>
1. 连接建立完成后,就可以执行 select 语句了;执行逻辑就会来到<b>第二步:查询缓存</b>
2. MySQL 拿到一个查询请求后,会<b>先到查询缓存看看</b>,之前<b>是不是执行过这条语句</b>
3. 之前执行过的语句及其结果可能会<b>以 key-value 对</b>的形式,被直接<b>缓存在内存中</b>
<b>key 是查询的语句</b>,<b>value 是查询的结果</b>
4. <b>如果命中查询缓存</b>,那么这个 <b>value </b>就<b>会被直接返回</b>给客户端<font color="#9e9e9e">(在查询缓存返回结果的时候,做权限验证)</font>
5. 如果语句不在查询缓存中,就会继续后面的执行阶段
6. <b>执行完成后</b>,<b>执行结果会被存入查询缓存中</b>
<b>大多数情况查询缓存就<font color="#2196f3">是个鸡肋</font>,为什么呢?</b><br>
因为查询缓存往往弊大于利
1. 查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空
2. 因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了
3. 对于更新压力大的数据库来说,查询缓存的命中率会非常低
<b>一般建议在<font color="#2196f3">静态表</font>里使用查询缓存</b>
静态表:就是一般我们极少更新的表
比如,一个系统配置表、字典表
这些张表上的查询才适合使用查询缓存
<b>MySQL也提供了“<font color="#2196f3">按需使用</font>”配置</b>
你可以将 <b>my.cnf </b>参数 <font color="#2196f3"><b>query_cache_type</b> </font>设置成 <b><font color="#4caf50">DEMAND</font></b>
有3个值:<b>0</b>代表关闭查询缓存OFF,<b>1</b>代表开启ON,<b>2</b>(DEMAND)代表当sql语句中<b>有 <font color="#2196f3">SQL_CACHE </font>关键词时<font color="#2196f3">才缓存</font></b>
这样对于默认的 SQL 语句都不使用查询缓存
这样对于你<b>确定要使用查询缓存的语句</b>,可以<b>用</b> <b><font color="#2196f3">SQL_CACHE </font>显式指定</b>,如下图所示:
<b><font color="#9c27b0"> mysql></font><font color="#4caf50"> select </font><font color="#2196f3">SQL_CACHE </font><font color="#4caf50">* from test where ID=5;</font></b>
<b>查看当前mysql实例是否开启缓存机制:</b>
<b><font color="#9c27b0">mysql> </font><font color="#0000ff">show global variables like "%</font><font color="#4caf50">query_cache_type</font><font color="#0000ff">%";</font></b>
<b>监控查询缓存的命中率:</b><font color="#9e9e9e">(查看运行的缓存信息)</font><br>
<b><font color="#9c27b0">mysql> </font><font color="#0000ff">show status like '%</font><font color="#4caf50">Qcache</font><font color="#0000ff">%'; </font></b>
<b>Qcache_free_blocks:表示查询缓存中目前还有多少剩余的blocks</b>
如果该值显示较大,则说明查询缓存中的内存碎片过多了,可能在一定的时间进行整理
<b>Qcache_free_memory:查询缓存的内存大小</b>
通过这个参数可以很清晰的知道当前系统的查询内存是否够用,是多了,还是不够用,DBA可以根据实际情况做出调整
<b><font color="#2196f3">Qcache_hits:表示有多少次命中缓存</font></b>
我们主要可以通过该值来验证我们的查询缓存的效果。数字越大,缓存效果越理想
<b>Qcache_inserts:表示多少次未命中然后插入</b>
意思是新来的SQL请求在缓存中未找到,不得不执行查询处理,执行查询处理后把结果insert到查询缓存中
这样的情况的次数,次数越多,表示查询缓存应用到的比较少,效果也就不理想。
当然系统刚启动后,查询缓存是空的,这很正常
<b>Qcache_lowmem_prunes:该参数记录有多少条查询因为内存不足而被移除出查询缓存</b>
通过这个值,用户可以适当的调整缓存大小。<br>
<b>Qcache_not_cached:表示因为query_cache_type的设置而没有被缓存的查询数量</b>
<b>Qcache_queries_in_cache:当前缓存中缓存的查询数量</b>
<b>Qcache_total_blocks:当前缓存的block数量</b>
<b><font color="#e57373">MySQL 8.0 已经移除了查询缓存功能</font></b>
<b><font color="#2196f3">分析器</font></b>
如果<b>没有命中查询缓存</b>,就要<b>开始真正执行语句</b>了
首先,MySQL 需要知道<b>你要做什么</b>,因此需要<b>对 SQL 语句做解析</b>
<b>分析器对 SQL 语句解析过程:</b>
<b>1. 分析器先会做“<font color="#2196f3">词法分析</font>”:</b>
1) 你输入的是由多个字符串和空格组成的一条 SQL 语句
2) MySQL 需要识别出里面的字符串分别是么,代表什么
3) MySQL 从你输入的"select"这个关键字识别出来,这是一个查询语句
4) 它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”
<b>2. 做完“<font color="#4caf50">词法分析</font>”后,就要做“<font color="#2196f3">语法分析</font>”:</b>
1) 根据词法分析的结果,语法分析器会根据语法规则则,判断你输入的这个 SQL 语句是否满足 MySQL 语法
2)如果你的语句不对,就会收到“<font color="#f44336">You have an error in your SQL syntax</font>”的错误提醒
比如:下面这个语句 from 写成了"rom"
<b>词法分析器原理:</b>
<b>词法分析器</b>分成<b>6个主要步骤</b>完成对sql语句的分析:
1、词法分析
2、语法分析
3、语义分析<br>
4、构造执行树<br>
5、生成执行计划
6、计划的执行
<a class="link" target="_bank" href="https://www.processon.com/diagraming/6393e4826376895515fa19e1">SQL词法分析的过程步骤如下图所示:</a><br>
<b>SQL语句的分析</b>分为<b>词法分析</b>与<b>语法分析</b>
<b>词法分析</b>由<b>MySQLLex</b><font color="#9e9e9e">[MySQL自己实现的]</font>完成
<b>语法分析</b>由<b>Bison</b>生成
经过<b>Bison语法分析之后</b>,会<b>生成</b>一个这样的<b><a class="link" target="_bank" href="https://www.processon.com/diagraming/6393e4826376895515fa19e1">语法树</a></b>
<font color="#f57c00" style="">关于<b>语法树</b></font><font color="#f57c00"><b>深入研究</b>可以参考这篇wiki文章:</font><a class="link" target="_bank" href="https://en.wikipedia.org/wiki/LR_parser">https://en.wikipedia.org/wiki/LR_parser</a>
<b><font color="#f57c00">Java</font></b>也有<b>开源的词法结构分析工具</b>:如 <b><font color="#f57c00">Antlr4</font></b>
ANTLR从语法生成一个解析器,可以构建和遍历解析树
可以在IDEA工具当中安装插件:<b>antlr v4 grammar plugin</b>
<b><font color="#2196f3">优化器</font></b>
经过了分析器,MySQL就知道你要做什么了
在开始执行之前,还要先经过<b><font color="#2196f3">优化器</font></b>处理
1、优化器是在表里有<b><font color="#2196f3">多个索引</font></b>的时候,<b><font color="#2196f3">决定使用哪个索引</font></b>
2、在一个语句有<b><font color="#2196f3">多表关联(join)</font></b>的时候,<b><font color="#2196f3">决定各个表的连接顺序</font></b>
如下多表关联示例:
<b><font color="#9c27b0">mysql></font> <font color="#4caf50">select * from test1 join test2 using(ID) where test1.name=yangguo and test2.name=xiaolongnv;</font></b><br>
1)既可以<b>先从表 <font color="#00bcd4">test1 </font>里面取出 name=yangguo 的记录的 ID 值</b>,再根据 ID 值<b>关联到表 <font color="#4caf50">test2</font></b>,再判断 <font color="#4caf50"><b>test2 </b></font>里面 name的值是否等于 yangguo
2)也可以<b>先从表 <font color="#4caf50">test2 </font>里面取出 name=xiaolongnv 的记录的 ID 值</b>,再根据 ID <b>值关联到 <font color="#00bcd4">test1</font></b>,再判断 <font color="#00bcd4"><b>test1 </b></font>里面 name的值是否等于 yangguo
以上<b>两种执行方法</b>的<b>逻辑结果是一样的</b>,<b>但</b>是<b>执行的效率会有不同</b>,而<font color="#2196f3"><b>优化器的作用</b></font>就是<b><font color="#2196f3">决定选择使用哪一个方案</font></b>
<b><font color="#2196f3">优化器</font></b>阶段完成后,这个语句的执行方案就确定下来了,然后进入<font color="#00bcd4"><b>执行器</b></font>阶段
<b><font color="#2196f3">执行器</font></b>
1. <b><font color="#f57c00">先判断</font></b>一下你对这个表 T<b><font color="#f57c00"> 有没有执行查询的权限</font></b><b style="color: rgb(245, 124, 0);">?</b><font color="#9e9e9e">(查询在优化器之前也会调用 precheck 验证权限)</font>
如果<font color="#e57373" style="">没有权限</font>,就会<font color="#e57373">返回没有权限的错误</font>
如果<font color="#2196f3">有权限</font>,就<font color="#2196f3">打开表继续执行</font>
2. 打开表的时候,<b><font color="#2196f3">执行器会根据表的引擎定义</font></b>,去<b><font color="#2196f3">使用这个引擎提供的接口</font></b>
对于<font color="#e57373"><b>没有索引的表</b></font>,<b>执行器的执行流程</b>,如下所示:<br>
<b><font color="#9c27b0">mysql></font> <font color="#4caf50">select * from test where id=1;</font></b><br>
1) 调用 InnoDB 引擎接口取这个表的<b>第一行</b>,判断 ID 值是不是 1?
<font color="#e57373">如果不是,则跳过</font>
<font color="#2196f3">如果是,则将这行存在结果集中</font>
2) 调用引擎接口取“<b>下一行</b>”,<b>重复相同的判断逻辑</b>,直到取到这个表的<b>最后一行</b>
3) <b>执行器将</b>遍历过程中<b>所有满足条件的行组成的记录集作为结果集返回给客户端</b>
至此,这个语句就执行完成了
对于<b><font color="#4caf50">有索引的表</font></b>,<b>执行的逻辑也差不多</b>,如下所示:
1)第一次调用的是“取满足条件的第一行”这个接口
2)之后循环取“满足条件的下一行”这个接口
<b>这些接口都是引擎中已经定义好的</b>
<b><font color="#2196f3">慢查询日志</font></b>中的 <font color="#2196f3"><b>rows_examined:</b></font>
你会在数据库的<b>慢查询日志</b>中看到一个 <b>rows_examined </b>的字段,表示这个语句<b>执行过程中扫描了多少行</b>
<b>rows_examined </b>值就是在<b>执行器每次调用引擎获取数据行</b>的时候<b>累加的</b>
在<b><font color="#f57c00">有些场景下</font></b>,<b>执行器调用一次</b>在引擎内部则<b>扫描了多行</b>,因此<b>引擎扫描行数</b>跟 <b>rows_examined </b>并<b>不是完全相同</b>的
<font color="#000000" style=""><b>Binlog归档</b></font>
<b><font color="#2196f3">什么是bin-log呢?</font></b>
binlog是<b>Server层实现的二进制日志</b>,他会<b>记录我们的crud操作</b>
<b><font color="#2196f3">bin-log的特点</font></b>
1、Binlog在MySQL的<b>Server层实现</b>(<b>引擎共用</b>)
2、Binlog为<b>逻辑日志</b>,<b>记录的是一条语句的原始逻辑</b>
3、Binlog<b>不限大小</b>,<b>追加写入</b>,不会覆盖以前的日志
<b><font color="#2196f3">bin-log可以用来恢复数据</font></b>
因为我们的SQL执行时,会将SQL语句的执行逻辑记录在我们的bin-log当中
如果我们<b>误删了数据库</b>,<b>可以使用bin-log进行归档</b><font color="#9e9e9e">(恢复数据)</font>,不需要跑路<br>
<b>要使用bin-log归档</b>,首先我们得记录bin-log,因此<b><font color="#e57373">需要先开启MySQL的bin-log功能</font></b>
<b><font color="#2196f3">开启MySQL的bin-log功能</font></b>
<b>1. 进入 my.cnf 文件 编辑模式</b>,配置bin-log
<b>2. 配置开启 bin-log</b>,即设置bin-log的目录位置
<b><font color="#0000ff">log‐bin=</font><font color="#4caf50">/usr/local/mysql/data/binlog/mysql‐bin</font></b>
<b>3. 配置 server-id</b>,<font color="#f44336">注意5.7以及更高版本需要配置本项</font><font color="#9e9e9e">(保证唯一性)</font>
<b><font color="#0000ff">server‐id=</font><font color="#4caf50">123454</font></b>
<b>4. 配置 bin-log 格式</b><font color="#9e9e9e">(有3种值:statement、row、mixed)</font>
<b><font color="#0000ff">binlog‐format=</font><font color="#4caf50">ROW</font></b>
<b>5. 配置 bin-log 执行写入与磁盘同步机制</b>(<font color="#9e9e9e">有2种值:0-由系统决定,事务提交时不刷盘;1-每次执行写入就与磁盘同步,影响性能)</font>
<b><font color="#0000ff">sync‐binlog=</font><font color="#4caf50">1</font></b>
<b><font color="#2196f3">bin-log 相关命令</font></b>
<b>1. 查看 bin‐log 是否开启:</b>
<b><font color="#9c27b0">mysql> </font><font color="#0000ff">show variables like '%</font><font color="#4caf50">log_bin</font><font color="#0000ff">%'; </font></b>
<b>2. 新开一个最新的 bin‐log 日志:</b>
<b><font color="#9c27b0">mysql> </font><font color="#0000ff">flush logs; </font></b>
<b>3. 查看最后一个 bin‐log 日志的相关信息:</b>
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">show master status;</font></b>
<b>4. 清空所有的 bin‐log 日志:</b>
<b><font color="#9c27b0">mysql> </font><font color="#0000ff">reset master; </font></b>
<b>5. 查看 bin-log 内容:</b>
<b><font color="#9c27b0">mysql></font><font color="#4caf50"> /usr/local/mysql/bin/mysqlbinlog </font><font color="#0000ff">‐‐no‐defaults</font><font color="#4caf50"> /usr/local/mysql/data/binlog/mysql‐bin.000001</font></b>
<b><font color="#2196f3">bin-log 的内容</font></b>
binlog内容如下:
bin-log 里的<b><font color="#e57373">内容不具备可读性</font></b>,所以<b><font color="#2196f3">需要我们自己去判断恢复的逻辑点位</font></b>,怎么观察呢?
<b>看重点信息</b>,比如 <b>begin</b>、<b>commit </b>这种<b>关键词</b>信息
可以理解为 <b>begin ~ commit 之间</b>的信息<b>是一个完整的事务逻辑,</b>然后再<b>根据位置</b> <b>position 判断恢复</b>即可
<b><font color="#2196f3">bin-log 数据归档操作</font></b>
<b>1. </b>从 bin-log <b>恢复全部数据</b>
<b><font color="#9c27b0">mysql></font><font color="#4caf50"> /usr/local/mysql/bin/mysqlbinlog </font><font color="#0000ff">‐‐no‐defaults</font> <font color="#4caf50">/usr/local/mysql/data/binlog/mysql‐bin.000001 </font><font color="#0000ff">|mysql ‐u</font><font color="#4caf50">root </font><font color="#0000ff">‐p</font> <font color="#4caf50">fw_test</font></b>
<b>2. </b>从 bin-log <b>恢复指定位置数据</b>
<b><font color="#9c27b0">mysql></font><font color="#4caf50"> /usr/local/mysql/bin/mysqlbinlog</font> <font color="#0000ff">‐‐no‐defaults ‐‐start‐position="</font><font color="#4caf50">408</font><font color="#0000ff">" ‐‐stop‐position="</font><font color="#4caf50">731</font><font color="#0000ff">" </font></b><font color="#4caf50"><b>/usr/local/mysql/data/binlog/mysql‐bin.000001</b></font><b><font color="#4caf50"> </font><font color="#0000ff">|mysql ‐u</font><font color="#4caf50">root </font><font color="#0000ff">‐p</font><font color="#4caf50"> fw_test</font></b>
<b>3. </b>从 bin-log <b>恢复指定时间段数据</b>
<b><font color="#9c27b0">mysql> </font><font color="#4caf50">/usr/local/mysql/bin/mysqlbinlog</font><font color="#0000ff"> ‐‐no‐defaults </font><font color="#4caf50">/usr/local/mysql/data/binlog/mysql‐bin.000001</font><font color="#0000ff"> ‐‐stop‐date= "</font><font color="#4caf50">2018‐03‐02 12:00:00</font><font color="#0000ff">" ‐‐start‐date= "</font><font color="#4caf50">2019‐03‐02 11:55:00</font><font color="#0000ff">" |mysql ‐u</font><font color="#4caf50">root</font> <font color="#0000ff">‐p </font><font color="#4caf50">fw_test</font></b>
<b><font color="#2196f3">bin-log 数据归档应用示例</font></b>
<b>1、</b>定义一个存储过程,<b>写入数据</b>
<b>2、删除数据</b><br>
<b><font color="#9c27b0">mysql></font> <font color="#0000ff">truncate test;</font></b><br>
<b>3、利用bin-log归档</b>
<b><font color="#9c27b0">mysql> </font><font color="#4caf50">/usr/local/mysql/bin/mysqlbinlog </font><font color="#0000ff">‐‐no‐defaults</font><font color="#4caf50"> /usr/local/mysql/data/binlog/mysql‐bin.000001 </font><font color="#0000ff">|mysql ‐u</font><font color="#4caf50">root</font><font color="#0000ff"> ‐p</font><font color="#4caf50"> fw_test</font></b>
<b>4、归档完毕,数据恢复</b>
0 条评论
下一页