testing-04

MySQL

  • 如果需要恢复的二进制日志较多,较复杂,强烈建议使用MySQL自身复制来恢复binlog,而不要使用mysqlbinlog。

    在MySQL手册中一直是推荐使用mysqlbinlog工具来实现指定时间点的数据恢复,事实上,这是一个经常”让人郁闷”的办法。更好的办法是,使用MySQL内部复制线程中的SQL Thread来做恢复。

    这个idea来自Lazydba同学;在Google稍作搜索,在Xaprb上Baron Schwartz也很早提到了使用类似的方法来恢复binlog,在那篇讨论中,还可以看到Jeremy Cole也提到:使用MySQL手册中推荐的方法是困难重重的,而且mysqlbinlog这个办法从逻辑上来说也是一个错误–因为这样MySQL不得不在两个不同的地方实现一套相同的逻辑,最终难免会出错。使用mysqlbinlog来恢复,你可能会需要以下“让人郁闷”的问题:

    (*) Max_allowed_packet问题 (*) 恼人的Blob/Binary/text字段问题 (*) 特殊字符的转义问题 (*) 没有"断点恢复":执行出错后,没有足够的报错,也很难从失败的地方继续恢复

    1. 如何操作

    本文不打算写一个step by step的文档,只介绍主要的思路和粗略的操作步骤。

    1.1 将binlog作为relay log来执行

    优点:实施简单;缺点:需要关闭一次数据库(不确定不关闭数据库行不行);

    思路:直接将要恢复的binlog拷贝到relay log目录,并修改slave-info相关的文件,让MySQL把binlog当做relay log来执行

    简单的操作步骤: (more…)

  • 在上上周给下厨房做过一次数据恢复(故障回顾:故障发生的技术总结 致歉信),恢复使用了开源工具Percona Data Recovery Tool for InnoDB(后面简称PDRTI),这里分享一下期间的注意事项,和遇到MySQL数据丢失的一些应对。

    本文主要介绍在使用Percona Data Recovery Tool for InnoDB时候的一些注意事项,并不包括具体的step by step的使用步骤,使用文档可以参考:Reference Manual and Documentation(more…)

  • 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序。表结构和数据准备参考本文最后部分”测试环境”。这里主要介绍MySQL优化器的主要执行流程,而不是介绍一个优化器的各个组件(这是另一个话题)。

    我们知道,MySQL优化器只有两个自由度:顺序选择;单表访问方式;这里将详细剖析下面的SQL,看看MySQL优化器如何做出每一步的选择。

    explain select * from employee as A,department as B where A.LastName = 'zhou' and B.DepartmentID = A.DepartmentID and B.DepartmentName = 'TBX';

    1. 可能的选择

    这里看到JOIN的顺序可以是A|B或者B|A,单表访问方式也有多种,对于A表可以选择:全表扫描和索引`IND_L_D`(A.LastName = ‘zhou’)或者`IND_DID`(B.DepartmentID = A.DepartmentID)。对于B也有三个选择:全表扫描、索引IND_D、IND_DN。

    2. MySQL优化器如何做

    2.1 概述

    MySQL优化器主要工作包括以下几部分:Query Rewrite(包括Outer Join转换等)、const table detection、range analysis、JOIN optimization(顺序和访问方式选择)、plan refinement。这个案例从range analysis开始。

    2.2 range analysis

    这部分包括所有Range和index merge成本评估(参考1 参考2)。这里,等值表达式也是一个range,所以这里会评估其成本,计算出found records(表示对应的等值表达式,大概会选择出多少条记录)。

    本案例中,range analysis会针对A表的条件A.LastName = ‘zhou’和B表的B.DepartmentName = ‘TBX’分别做分析。其中: (more…)

  • index merge的补充说明

    ·

    在除了前面介绍的常见index merge的案例(Index Merge Union Access Algorithm)之外,还有一类很少见也比较特殊的index merge,多个索引扫描后进行交集,即 Index Merge Intersection。这类执行计划比较少见(因为MySQL需要ROR的原因),但是,在合适的场景使用,效率仍然会有很大的提示,本文将看看MySQL优化器如何评估和选择此类执行计划。MySQL手册对此只是三言两语简单介绍了一下,这里做个较为详细的说明。

    这类执行计划完整名称应该是:The Index Merge Intersection Access Algorithm,下文简称Intersection

    1. 为什么需要考虑Intersection

    考虑如下查询:

    SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;

    优化器可以考虑使用索引key1或者key2进行REF/Range访问,如果使用key1,那么key2=1则作为过滤条件。另外,优化器还会考虑使用Intersection,即同时使用索引key1和key2。这样做可能的好处是:

    (a) 如果两次索引扫描后做交集,如果最后ROWID很少,则回表次数大大减少

    (b) 如果扫描这两个索引能是覆盖扫描的话,则无需回表 (more…)

  • 前面以案例的形式介绍了什么是index merge,以及它的使用场景。本文将介绍index merge实现的主要数据结构以及MySQL如何评估index merge的成本。在开始本文之前,需要先理解Range访问相关的数据结构介绍:SEL_ARG结构SEL_TREE结构(more…)

  • 在看MySQL优化器代码过程中,这应该是相对较简单/代码较清晰的部分了。MySQL优化器有两个自由度:单表访问方式,多表顺序选择。前文已经介绍过MySQL单表访问的一些考量(ref/range等),本文将介绍JOIN在顺序选择上的复杂度分析。

    当有多个表需要JOIN的时候,MySQL首先会处理两类特殊情况,一个是常数表,一个是由于外连接导致顺序依赖关系。前者总是放在关联的最前面,后者会在遍历的时候考虑。本文将忽略上面两点,从较宏观角度看JOIN顺序选择时候的复杂度。 (more…)