• Centos7 使用 Binlog2sql 恢复Mysql8.0 数据


    0.环境

    CentOS Linux release 7.6.1810 (Core)
    mysql Ver 8.0.16
    python 3.8.1  (下面步骤安装)
    pymysql 0.9.3 (下面步骤安装)

    1. Binlog2sql 安装

    1.1 安装python

    1.依赖包安装
    yum install -y wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc libffi-devel
    2.安装python3.8.1(20191230最新稳定版)
    wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
    tar -xzvf Python-3.8.1.tgz 
    cd Python-3.8.1
    ./configure --prefix=/etc/python3.8 --enable-optimizations
    make && make install
    [root@mysql1 python3.8]# ll /usr/bin/python*
    lrwxrwxrwx. 1 root root    7 Jun  3  2019 /usr/bin/python -> python2
    lrwxrwxrwx. 1 root root    9 Jun  3  2019 /usr/bin/python2 -> python2.7
    -rwxr-xr-x. 1 root root 7216 Oct 31  2018 /usr/bin/python2.7
    [root@mysql1 python3.8]# unlink /usr/bin/python
    [root@mysql1 python3.8]# ln -s /etc/python3.8/bin/python3.8 /usr/bin/python
    [root@mysql1 python3.8]# ll /usr/bin/python*                                   
    lrwxrwxrwx  1 root root   28 Dec 30 10:22 /usr/bin/python -> /etc/python3.8/bin/python3.8
    lrwxrwxrwx. 1 root root    9 Jun  3  2019 /usr/bin/python2 -> python2.7
    -rwxr-xr-x. 1 root root 7216 Oct 31  2018 /usr/bin/python2.7
    [root@mysql1 python3.8]# python -V
    Python 3.8.1

    1.1.1 yum修复

    问题
    因为yum需要使用python2,将/usr/bin/python改为python3后,yum就不能正常运行了,报错如下
    [root@mysql1 python3.8]# yum list
      File "/usr/bin/yum", line 30
        except KeyboardInterrupt, e:
                                ^
    SyntaxError: invalid syntax
    修复
    sed -i '1s/usr/bin/python/usr/bin/python2/' /usr/bin/yum
    sed -i '1s/usr/bin/python/usr/bin/python2/' /usr/libexec/urlgrabber-ext-down

    1.2 安装Python-pip

    yum -y install epel-release
    yum -y install python-pip
    pip install --upgrade pip
    [root@mysql4 Python-3.8.1]# pip --version
    pip 19.3.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)
    
    修改pip 使用3.8的python
    python -m ensurepip
    python -m pip install --upgrade pip
    sed -i '1s/usr/bin/python2/usr/bin/python/' /usr/bin/pip
    [root@mysql4 Python-3.8.1]# pip --version
    pip 19.3.1 from /etc/python3.8/lib/python3.8/site-packages/pip (python 3.8)

    1.3 安装pymysql 模块

    [root@mysql4 Python-3.8.1]# pip install PyMySQL
    [root@mysql4 Python-3.8.1]# pip install --upgrade PyMySQL  (不升级会遇到报错 KeyError: 255 )
    Collecting PyMySQL
      Downloading https://files.pythonhosted.org/packages/ed/39/15045ae46f2a123019aa968dfcba0396c161c20f855f11dea6796bcaae95/PyMySQL-0.9.3-py2.py3-none-any.whl (47kB)
         |████████████████████████████████| 51kB 402kB/s 
    Installing collected packages: PyMySQL
    Successfully installed PyMySQL-0.9.3
    
    [root@mysql4 Python-3.8.1]# pip show pymysql
    Name: PyMySQL
    Version: 0.9.3
    Summary: Pure Python MySQL Driver
    Home-page: https://github.com/PyMySQL/PyMySQL/
    Author: yutaka.matsubara
    Author-email: yutaka.matsubara@gmail.com
    License: "MIT"
    Location: /etc/python3.8/lib/python3.8/site-packages
    Requires: 
    Required-by: 
    
    [root@mysql4 Python-3.8.1]# pip list
    Package    Version
    ---------- -------
    pip        19.3.1 
    PyMySQL    0.9.3  
    setuptools 41.2.0 

    1.4 安装binlog2sql

    yum install -y git
    git clone https://github.com/danfengcao/binlog2sql.git && cd binlog2sql
    pip install -r requirements.txt
    以上完成了binlog2Mysql 的安装。

    2. Binlog2Mysql 使用测试

    2.1  检查数据库参数

    是否包含如下参数,没有则添加
    [mysqld]
    server_id=1
    log_bin = binlog.index
    max_binlog_size = 1G
    binlog_format = row
    binlog_row_image = full (默认,保存了变更前和变更后的所有列镜像)
    重启数据库使生效
    systemctl stop mysqld
    systemctl stop mysqld

    2.2 创建测试用例

    创建测试库cymdb, 测试用户cym, 测试表cymtable
    --1.创建测试库 cymdb
    create database cymdb;
    
    --2. 创建测试用户
    create user cym identified by "Hello3306";
    GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO cym;
    
    --3.创建测试表
    use cymdb;
    create table cymtable(id int,name varchar(10),addtime datetime default now());
    insert into cymtable values(1,'',now()),(2,'',now()),(3,'','2022-01-12 12:12:12'),(4,'','2000-12-12 1:00:00');
    mysql> select * from cymtable;
    +------+------+---------------------+
    | id   | name | addtime             |
    +------+------+---------------------+
    |    1 || 2019-12-30 13:18:20 |
    |    2 || 2019-12-30 13:18:20 |
    |    3 || 2022-01-12 12:12:12 |
    |    4 || 2000-12-12 01:00:00 |
    +------+------+---------------------+
    4 rows in set (0.00 sec)
    
    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2019-12-30 13:18:39 |
    +---------------------+
    1 row in set (0.00 sec)
    
    --4.删除数据
    mysql> delete from cymtable;
    Query OK, 4 rows affected (0.00 sec)
    
    mysql> select * from cymtable;
    Empty set (0.00 sec)
    
    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2019-12-30 13:21:15 |
    +---------------------+
    1 row in set (0.00 sec)
    以上案例:
    数据正常时间:2019-12-30 13:18:39
    数据丢失时间:2019-12-30 13:21:15
    面临数据丢失,我们要如何恢复?

    2.3 通过binlog2mysql 获取 Redo SQL 和 Undo SQL

    2.3.1 获取binlog 位置

    mysql> show variables like 'log_bin%';
    +---------------------------------+------------------------------------+
    | Variable_name                   | Value                              |
    +---------------------------------+------------------------------------+
    | log_bin                         | ON                                 |
    | log_bin_basename                | /u01/app/mysql/mydata/binlog       |
    | log_bin_index                   | /u01/app/mysql/mydata/binlog.index |
    | log_bin_trust_function_creators | OFF                                |
    | log_bin_use_v1_row_events       | OFF                                |
    +---------------------------------+------------------------------------+
    5 rows in set (0.00 sec)

    2.3.2 检查binlog 的最后修改时间,获取需要的binlog

    [root@mysql4 mydata]# ls -ltrh /u01/app/mysql/mydata/binlog*
    -rw-r----- 1 mysql mysql  178 Dec 27 14:31 /u01/app/mysql/mydata/binlog.000001
    -rw-r----- 1 mysql mysql 1.2K Dec 27 14:37 /u01/app/mysql/mydata/binlog.000002
    -rw-r----- 1 mysql mysql  521 Dec 27 17:02 /u01/app/mysql/mydata/binlog.000003
    -rw-r----- 1 mysql mysql  218 Dec 27 23:18 /u01/app/mysql/mydata/binlog.000004
    -rw-r----- 1 mysql mysql  218 Dec 27 23:20 /u01/app/mysql/mydata/binlog.000005
    -rw-r----- 1 mysql mysql  218 Dec 27 23:21 /u01/app/mysql/mydata/binlog.000006
    -rw-r----- 1 mysql mysql  218 Dec 30 12:38 /u01/app/mysql/mydata/binlog.000007
    -rw-r----- 1 mysql mysql  128 Dec 30 12:39 /u01/app/mysql/mydata/binlog.index
    -rw-r----- 1 mysql mysql 1.9K Dec 30 13:21 /u01/app/mysql/mydata/binlog.000008
    知数据丢失时间为 2019-12-30 13:18:39 ~ 2019-12-30 13:21:15
    /u01/app/mysql/mydata/binlog.000008 的时间周期是 Dec 30 12:38 ~ Dec 30 13:21 是我们需要的binlog。

    2.3.3 从binlog中解析出Redo SQL 和Undo SQL

    2.3.3.1 解析 Redo SQL
    cd binlog2sql/
    [root@mysql4 binlog2sql]# python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -ucym -pHello3306 -dcymdb -t cymtable --start-file='binlog.000008' --start-datetime='2019-12-30 13:18:39' --stop-datetime='2019-12-30 13:21:15'
    DELETE FROM `cymdb`.`cymtable` WHERE `addtime`=1 AND `id`='' AND `name`='2019-12-30 13:18:20' LIMIT 1; #start 1585 end 1817 time 2019-12-30 13:21:06
    DELETE FROM `cymdb`.`cymtable` WHERE `addtime`=2 AND `id`='' AND `name`='2019-12-30 13:18:20' LIMIT 1; #start 1585 end 1817 time 2019-12-30 13:21:06
    DELETE FROM `cymdb`.`cymtable` WHERE `addtime`=3 AND `id`='' AND `name`='2022-01-12 12:12:12' LIMIT 1; #start 1585 end 1817 time 2019-12-30 13:21:06
    DELETE FROM `cymdb`.`cymtable` WHERE `addtime`=4 AND `id`='' AND `name`='2000-12-12 01:00:00' LIMIT 1; #start 1585 end 1817 time 2019-12-30 13:21:06
    这里看到对应时间段的cymtable表的 RedoSQL 已经被解析出来,但是注意 `addtime`=1 AND `id`='赵' AND `name`='2019-12-30 13:18:20' 顺序是错误的。
    2.3.3.2 解析 Undo SQL
    [root@mysql4 binlog2sql]# python binlog2sql/binlog2sql.py --flashback -h127.0.0.1 -P3306 -ucym -pHello3306 -dcymdb -t cymtable --start-file='binlog.000008' --start-datetime='2019-12-30 13:18:39' --stop-datetime='2019-12-30 13:21:15'
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (4, '', '2000-12-12 01:00:00'); #start 1585 end 1817 time 2019-12-30 13:21:06
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (3, '', '2022-01-12 12:12:12'); #start 1585 end 1817 time 2019-12-30 13:21:06
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (2, '', '2019-12-30 13:18:20'); #start 1585 end 1817 time 2019-12-30 13:21:06
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (1, '', '2019-12-30 13:18:20'); #start 1585 end 1817 time 2019-12-30 13:21:06

    顺序同样是错的,下面使用Linux 命令修复

    [root@mysql4 binlog2sql]# python binlog2sql/binlog2sql.py --flashback -h127.0.0.1 -P3306 -ucym -pHello3306 -dcymdb -t cymtable --start-file='binlog.000008' --start-datetime='2019-12-30 13:18:39' --stop-datetime='2019-12-30 13:21:15'| cut -d '#' -f1 >undo.sql
    [root@mysql4 binlog2sql]# more undo.sql 
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (4, '', '2000-12-12 01:00:00'); 
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (3, '', '2022-01-12 12:12:12'); 
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (2, '', '2019-12-30 13:18:20'); 
    INSERT INTO `cymdb`.`cymtable`(`addtime`, `id`, `name`) VALUES (1, '', '2019-12-30 13:18:20'); 
    
    [root@mysql4 binlog2sql]# sed -i 's/addtime/vcol1/g' undo.sql 
    [root@mysql4 binlog2sql]# sed -i 's/name/addtime/g' undo.sql
    [root@mysql4 binlog2sql]# sed -i 's/id/name/g' undo.sql           
    [root@mysql4 binlog2sql]# sed -i 's/vcol1/id/g' undo.sql      
    
    [root@mysql4 binlog2sql]# more undo.sql                       
    INSERT INTO `cymdb`.`cymtable`(`id`, `name`, `addtime`) VALUES (4, '', '2000-12-12 01:00:00'); 
    INSERT INTO `cymdb`.`cymtable`(`id`, `name`, `addtime`) VALUES (3, '', '2022-01-12 12:12:12'); 
    INSERT INTO `cymdb`.`cymtable`(`id`, `name`, `addtime`) VALUES (2, '', '2019-12-30 13:18:20'); 
    INSERT INTO `cymdb`.`cymtable`(`id`, `name`, `addtime`) VALUES (1, '', '2019-12-30 13:18:20'); 
    
    #修复成功
    2.3.3.3 数据库应用Undo、
    [root@mysql4 binlog2sql]# mysql -uroot -p123456 cymdb <undo.sql            
    mysql: [Warning] Using a password on the command line interface can be insecure.
    [root@mysql4 binlog2sql]# mysql -uroot -p123456 cymdb -e 'select * from cymtable'
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+---------------------+
    | id   | name | addtime             |
    +------+------+---------------------+
    |    4 | 李   | 2000-12-12 01:00:00 |
    |    3 | 孙   | 2022-01-12 12:12:12 |
    |    2 | 钱   | 2019-12-30 13:18:20 |
    |    1 | 赵   | 2019-12-30 13:18:20 |
    +------+------+---------------------+
    至此完成了mysql 误删除数据的恢复。
     

    以上操作是在联网环境下完成的,安装过程中遇到的错误还好都解决了。如果是离线环境估计又有很多问题需要处理。

    参考

  • 相关阅读:
    raw_input() 与 input()对比
    你很熟悉CSS,却没掌握这些CSS技巧
    CSS样式设置
    javascript基本语法和变量(转)
    手机/移动前端开发需要注意的20个要点
    移动端”宴席知多少
    git第一次提交代码到远程仓库
    java对过反射调用方法
    站点收集
    别人抢红包,我们研究一下红包算法
  • 原文地址:https://www.cnblogs.com/plluoye/p/12119810.html
Copyright © 2020-2023  润新知