• MySQL Flashback 闪回功能详解


    1. 简介

    mysqlbinlog flashback(闪回)用于快速恢复由于误操作丢失的数据。在DBA误操作时,可以把数据库恢复到以前某个时间点(或者说某个binlog的某个pos)。比如忘了带where条件的update、delete操作,传统的恢复方式是利用全备+二进制日志前滚进行恢复,相比于传统的全备+增备,flashback显然更为快速、简单。

    目前MySQL的flashback功能是利用binlog完成的,第一个实现该功能的是阿里云的彭立勋, 他在MySQL 5.5版本上就已实现,并将其提交给MariaDB。

    2. 闪回原理

    原理:flashback工具(-B 参数)可对rows格式的binlog可以进行逆向操作,delete反向生成insert、update生成反向的update、insert反向生成delete。

    MySQL的binlog以event的形式,记录了MySQL中所有的变更情况,利用binlog我们就能够重现所记录的所有操作。

    MySQL引入binlog主要有两个用途/目的:一是为了主从复制;二是用于备份恢复后需要重新应用部分binlog,从而达到全备+增备的效果。

    MySQL的binlog有三种格式:

    • statement,基于SQL语句的模式,一般来说生成的binlog尺寸较小,但是某些不确定性SQL语句或函数在复制过程可能导致数据不一致甚至出错;
    • row,基于数据行的模式,记录的是数据行的完整变化。相对更安全,推荐使用(但通常生成的binlog会比其他两种模式大很多);
    • mixed,混合模式,可以根据情况自动选用statement抑或row模式;这个模式下也可能造成主从数据不一致。它属于MySQL 5.1版本时期的过渡方案,已不推荐使用了。

    注意:使用mysqlbinlog flashback 工具必须设置:binlog_format = row

    3. flashback安装

    下载flashback工具 mysqlbinlog : https://pan.baidu.com/s/1c1Ub1x2,并将mysqlbinlog文件移至mysql安装路径的bin目录下(可备份原来的mysqlbinlog为mysqlbinlog_bak),执行mysqlbinlog --help命令,可能会报错(系统版本为 CentOS 6.4_x64):

    [root@centos64-slave1 bin]# mysqlbinlog --help
    mysqlbinlog: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mysqlbinlog)

    需要安装新版本的libstdc++.so.6,下载链接:https://pan.baidu.com/s/1gfIarCn 

    复制代码
    [root@centos64-slave1 ~]# cp libstdc++.so.6.0.20  /usr/lib64/
    [root@centos64-slave1 ~]# cd /usr/lib64/
    [root@centos64-slave1 lib64]# mv libstdc++.so.6 libstdc++.so.6_bak
    [root@centos64-slave1 lib64]# ln -s libstdc++.so.6.0.20 libstdc++.so.6
    [root@centos64-slave1 lib64]# ll libstdc*
    lrwxrwxrwx  1 root root      19 4月   6 09:30 libstdc++.so.6 -> libstdc++.so.6.0.20
    -rwxr-xr-x. 1 root root  987096 7月  19 2013 libstdc++.so.6.0.13
    -rw-r--r--  1 root root 1011824 4月   6 09:28 libstdc++.so.6.0.20
    lrwxrwxrwx. 1 root root      19 1月  14 12:25 libstdc++.so.6_bak -> libstdc++.so.6.0.13
    复制代码

    安装完后执行mysqlbinlog --help,若报错:mysqlbinlog: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /usr/lib64/libstdc++.so.6),需要更新/lib64库文件。下载链接:https://pan.baidu.com/s/1kViGrIZ

    复制代码
    # tar zxvf  glibc-2.14.tar.gz
    # cd glibc-2.14
    # mkdir build
    # cd build
    # ../configure  --prefix=/opt/glibc-2.14
     ## 检查是否有问题。
    # make  ## (4核可加-j4 ,8核可加-j8)
    # make install
    # strings libc.so | grep GLIBC   ## 这是我们需要的lib了,然后去更新系统的库
    # cp libc.so  /lib64/libc-2.14.so
    # mv /lib64/libc.so.6   /lib64/libc.so.6_bak
    # LD_PRELOAD=/lib64/libc-2.14.so ln -s  /lib64/libc-2.14.so  /lib64/libc.so.6  
    # strings /lib64/libc.so.6 | grep GLIBC 
    复制代码

    安装完成后执行:

    [root@centos64-slave1 ~]# mysqlbinlog -V
    mysqlbinlog Ver 3.4-InnoSQL for Linux at x86_64
    [root@centos64-slave1 ~]# mysqlbinlog --help |grep flashback
      -B, --flashback     Flashback data to start_postition or start_datetime.
      -E, --fb-event=name only flashback this type of
    flashback                         FALSE

    发现mysqlbinlog版本已变为3.4-InnoSQL(之前的版本为3.4),且多了一个 -B 参数,此参数即用于实现flashback功能。到此,mysqlbinlog已安装完成!

    4. ldconfig 解决依赖库

    上面我们介绍过了直接替换 /lib64 的软连接来解决 mysqlbinlog 的依赖问题,但是这样做对于系统来说有一定的风险性,这里采用 ldconfig 解决。ldconfig 是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。

    mysqlbinlog5.7 -V    #该命令已经集成到系统环境变量,可以直接调用
    mysqlbinlog5.7: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mysqlbinlog5.7)

    添加 MySQL的库环境到 ldconfig 配置文件:

    echo "/data/mysql-5.7.21-linux-glibc2.12-x86_64/lib" >> /etc/ld.so.conf

    然后把需要的库文件上传到  /data/mysql-5.7.21-linux-glibc2.12-x86_64/lib  目录下。

    复制代码
    # chmod +x libc-2.14.so libstdc++.so.6.0.20 
    # ldconfig  重载,系统会给库文件自动创建软连接
    # mysqlbinlog5.7 -V
    mysqlbinlog5.7: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /data/dmx/mysql-5.7.21-linux-glibc2.12-x86_64/lib/libstdc++.so.6)
    
    报错发生了变化,
    echo $LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=/data/mysql-5.7.21-linux-glibc2.12-x86_64/lib
    并将 LD_LIBRARY_PATH 写到 /etc/profile :
    export LD_LIBRARY_PATH=/data//mysql-5.7.21-linux-glibc2.12-x86_64/lib
    source /etc/profile
    但是这个方法需要退出bash,重新登录,对于consul等一些监控程序不友好。
    复制代码

    5. 使用简介

    先创建一张表user,向user表中插入一条数据,查看binlog日志内容,可以找到刚才插入的记录:

    # mysqlbinlog -vv mysql-bin.000004 

    ### INSERT INTO `test`.`user`
    ### SET
    ###   @1=30 /* SHORTINT meta=0 nullable=1 is_null=0 */
    ###   @2='Stephen Curry' /* VARSTRING(80) meta=80 nullable=1 is_null=0 */

    然后使用flashback工具(-B参数)查看binlog内容,可以找到刚才插入记录的逆向操作:

    # mysqlbinlog -vv mysql-bin.000004 -B

    ### DELETE FROM `test`.`user`
    ### WHERE
    ###   @1=30 /* SHORTINT meta=0 nullable=1 is_null=0 */
    ###   @2='Stephen Curry' /* VARSTRING(80) meta=80 nullable=1 is_null=0 */

    同理,delete操作将会被转换为insert,update被转换为反向的update;若在一个事务中既有insert、update、delete语句,通过使用-B参数后,不仅三种DML语句完成了逆向转换,并且语句顺序也会发生颠倒。

    在binlog中找到误操作的pos变化区间后,使用mysqlbinlog -B 恢复:

    # mysqlbinlog -B --start-position=296 --stop-position=429 mysql-bin.000004 | mysql -uroot -p

     注意:执行恢复时不能加 -v、--base64-output=decode-rows 等参数,否则binlog中的语句不会被执行。

    另外,如果遇到:ERROR 1782 (HY000) at line 13: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.

    需要加上 --skip-gtids 参数, mysqlbinlog mysql-bin.001024 -B --start-position=908 --stop-position=1156 --skip-gtids | mysql

    6. Flashback工具使用注意点

    • binlog日志格式必须是ROW格式:binlog_format = row ;
    • 一个事务中的DML语句不仅会逆向转换,并且语句顺序也会发生颠倒;
    • 只支持 insert、update、delete , 不支持drop 、truncate、alter等DDL语句。
  • 相关阅读:
    JavaScript模态对话框类
    事件模块的演变(1)
    html5中可通过document.head获取head元素
    How to search for just a specific file type in Visual Studio code?
    What do 'lazy' and 'greedy' mean in the context of regular expressions?
    正则非获取匹配 Lookahead and Lookbehind ZeroLength Assertions
    regex length 正则长度问题
    Inversion of Control vs Dependency Injection
    How to return View with QueryString in ASP.NET MVC 2?
    今天才发现Google Reader
  • 原文地址:https://www.cnblogs.com/moxiaotao/p/10142089.html
Copyright © 2020-2023  润新知