zoukankan      html  css  js  c++  java
  • mysql利用mysqlbinlog命令恢复误删除数据

    1.编译安装MySQL

    如果有老的MySQL或Maridb,则要先卸载

    [root@monitor ~]# systemctl stop mysqld
    [root@monitor ~]# rpm -qa | egrep -i 'mysql|maria'
    [root@monitor ~]# rpm -qa | egrep -i 'mysql|maria'
    mariadb-libs-5.5.56-2.el7.x86_64
    # 而实际这个mariadb-libs-5.5.56-2.el7.x86_64不需要卸载没有关系。
    
    [root@monitor ~]# rpm -e --nodeps  + 包名1 包名2 .....
    
    # 删除老版本mysql的开发头文件和库
    rm -rf /usr/lib/mysql
    rm -rf /usr/include/mysql
    # 注意:卸载后/var/lib/mysql中的数据及/etc/my.cnf不会删除,如果确定没用后就手工删除
    rm -rf /etc/my.cnf
    rm -rf /var/lib/mysql

    下载安装配置

    # 下载
    
    [root@monitor ~]# wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.22-el7-x86_64.tar.gz -P /usr/local/    #下载慢的话通过浏览器下载后再传上去
    
    # 解压添加用户和环境变量
    
    [root@monitor ~]# 
    mkdir -p /usr/local/mysql && 
    cd /usr/local/ && 
    tar -xzvf mysql-5.7.22-el7-x86_64.tar.gz && 
    cp -arf mysql-5.7.22-el7-x86_64/* /usr/local/mysql/ && 
    cd /usr/local/mysql/ && 
    mkdir data && 
    mkdir log && 
    echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile && 
    source /etc/profile && 
    groupadd mysql && 
    useradd -r -g mysql -s /bin/false mysql
    
    # 查看目录
    
    [root@monitor mysql]# pwd
    /usr/local/mysql
    [root@monitor mysql]# ll
    total 36
    drwxr-xr-x  2 root root   4096 Jan  4 11:07 bin
    -rw-r--r--  1 7161 31415 17987 Mar  4  2018 COPYING
    drwxr-xr-x  2 root root      6 Jan  4 11:08 data
    drwxr-xr-x  2 root root     55 Jan  4 11:07 docs
    drwxr-xr-x  3 root root   4096 Jan  4 11:07 include
    drwxr-xr-x  5 root root    229 Jan  4 11:07 lib
    drwxr-xr-x  2 root root      6 Jan  4 11:08 log
    drwxr-xr-x  4 root root     30 Jan  4 11:07 man
    -rw-r--r--  1 7161 31415  2478 Mar  4  2018 README
    drwxr-xr-x 28 root root   4096 Jan  4 11:07 share
    drwxr-xr-x  2 root root     90 Jan  4 11:07 support-files
    
    # 更新配置文件
    
    [root@monitor mysql]# 
    cp -arf /etc/my.cnf /etc/my.cnf.bak`date +%F`
    cat >/etc/my.cnf << EOF
    [client]
    socket=/usr/local/mysql/mysql.sock  
    [mysqld]
    basedir=/usr/local/mysql
    datadir=/usr/local/mysql/data
    pid-file=/usr/local/mysql/data/mysqld.pid
    socket=/usr/local/mysql/mysql.sock
    log_error=/usr/local/mysql/log/mysql.error.log
    EOF
    
    # 改为mysql用户和组
    
    [root@monitor mysql]# 
    cd /usr/local/mysql && 
    chmod 750 data/ && 
    chown -R mysql . && 
    chgrp -R mysql .
    [root@monitor mysql]# ll
    total 36
    drwxr-xr-x  2 mysql mysql  4096 Jan  4 11:07 bin
    -rw-r--r--  1 mysql mysql 17987 Mar  4  2018 COPYING
    drwxr-x---  2 mysql mysql     6 Jan  4 11:08 data
    drwxr-xr-x  2 mysql mysql    55 Jan  4 11:07 docs
    drwxr-xr-x  3 mysql mysql  4096 Jan  4 11:07 include
    drwxr-xr-x  5 mysql mysql   229 Jan  4 11:07 lib
    drwxr-xr-x  2 mysql mysql     6 Jan  4 11:08 log
    drwxr-xr-x  4 mysql mysql    30 Jan  4 11:07 man
    -rw-r--r--  1 mysql mysql  2478 Mar  4  2018 README
    drwxr-xr-x 28 mysql mysql  4096 Jan  4 11:07 share
    drwxr-xr-x  2 mysql mysql    90 Jan  4 11:07 support-files
    
    # 初始化
    
    [root@monitor mysql]# pwd
    /usr/local/mysql
    [root@monitor mysql]# /usr/local/mysql/bin/mysqld --initialize --user=mysql
    或 [root@monitor mysql]# /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --initialize
    [root@monitor mysql]# grep 'temporary password' /usr/local/mysql/log/mysql.error.log
    2019-01-04T03:11:29.386050Z 1 [Note] A temporary password is generated for root@localhost: n!rDqonId0qi
    
    # 添加服务启动项
    
    [root@monitor mysql]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld && service mysqld status
    ERROR! MySQL is not running
    [root@monitor mysql]# chkconfig --add mysqld && chkconfig mysqld on
    [root@monitor mysql]# service mysqld start
    Starting MySQL. SUCCESS!
    
    # 首次登录要更改密码,初始化时查到的初始密码为n!rDqonId0qi
    
    [root@monitor mysql]# mysql -uroot -p
    Enter password:n!rDqonId0qi
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 2
    Server version: 5.7.22
    
    Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> use mysql;
    ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'GoldrockMonitor01!';
    Query OK, 0 rows affected (0.00 sec)
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'GoldrockMonitor01!';
    Query OK, 0 rows affected (0.00 sec)
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    mysql> select host,user,password from user;
    ERROR 1054 (42S22): Unknown column 'password' in 'field list'
    mysql> select user,host,authentication_string from user;
    +---------------+-----------+-------------------------------------------+
    | user          | host      | authentication_string                     |
    +---------------+-----------+-------------------------------------------+
    | root          | localhost | *8E058CA664EDC92380733BD602CD9A297CEE7FC4 |
    | mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
    | mysql.sys     | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
    +---------------+-----------+-------------------------------------------+
    3 rows in set (0.00 sec)
    
    mysql>

    2.开启MySQL binlog日志

    1、登录MySQL,查看binlog日志的状态

    登录MySQL后,输入show variables like '%log_bin%';查看到binlog日志为OFF关闭状态;

    mysql> show variables like '%log_bin%';
    +---------------------------------+---------------------------------+
    | Variable_name                   | Value                           |
    +---------------------------------+---------------------------------+
    | log_bin                         | off                             |
    | log_bin_basename                |                                 |
    | log_bin_index                   |                                 |
    | log_bin_trust_function_creators | OFF                             |
    | log_bin_use_v1_row_events       | OFF                             |
    | sql_log_bin                     | ON                              |
    +---------------------------------+---------------------------------+
    6 rows in set (0.00 sec)

    2、开启MySQL binlog日志

    退出MySQL,使用vi编辑器修改MySQL的my.cnf配置文件

    在my.cnf配置文件中添加如下图的两句

    [root@localhost /]*# vim /etc/my.cnf
       
    log-bin=mysql-bin  #*#开启二进制日志(默认放到data)

    3.重启MySQL

    查看/usr/local/mysql目录下的内容

    使用命令:ls /usr/local/mysql

    此时再次进入MySQL,查看binlog日志的状态。显示binlog日志为ON开启状态

    mysql> show variables like '%log_bin%';
    +---------------------------------+---------------------------------+
    | Variable_name                   | Value                           |
    +---------------------------------+---------------------------------+
    | log_bin                         | ON                              |
    | log_bin_basename                | /var/mysql/data/mysql-bin       |
    | log_bin_index                   | /var/mysql/data/mysql-bin.index |
    | log_bin_trust_function_creators | OFF                             |
    | log_bin_use_v1_row_events       | OFF                             |
    | sql_log_bin                     | ON                              |
    +---------------------------------+---------------------------------+
    
    ————————————————

    3.binlog文件 恢复mysql 数据库

    1、执行:FLUSH LOGS;

    刷新日志是为了实验内容更直观,更容易观察到整个实验过程的内容。

    我看到网上许多文章有在用REST MASTER;而未说明此命令的严重性

    这条命令会删除所有日志文件,并将文件名和记录点进行重置归零,99%的情况下是用不到这条命令的

    删除日志可以用PURGE MASTER LOGS...这样保险一点

    2、新日志文件已经生成,先观察一下内容,有几个点需要了解

    ![img](https://img-blog.csdn.net/20180903162809221?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoYWlnYW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    查看二进日日志文件命令:mysqlbinlog mysql-bin.000001

    # at 4
    
    # 180903 16:19:12 server id 1  end_log_pos 123 CRC32 0xe03659b3  Start: binlog v 4, server v 5.7.22-log created 180903 16:19:12
    
    先看上边两个箭头:
    
    # at 4(事件开始点)
    
    # 180903 16:19:12 (代表的是时间)
    
    server id 1(主备复制时需要为每个MYSQL数据库指定唯一的SERVER ID,我的未配置,默认是1)
    
    end_log_pos 123(事件结束点)
    
    再看下边两个箭头:
    
    # at 123(事件开始点,和上边的事件结束点是对应的)
    
    end_log_pos 154(事件结束点)
    
    at 4 和 at 123之间的内容就是事件内容

    3、模拟业务场景,建表,插入数据,最后将某个表删除;为了真实,我建了两个库,同时向不同的库写入内容,最后将其中一个库中的某个表删除。

    mysql> FLUSH LOGS;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> create database t1;
    Query OK, 1 row affected (0.03 sec)
    
    mysql> create database t2;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> use t1;
    Database changed
    mysql> create table t1 (id int);
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> use t2;
    Database changed
    mysql> create table t2 (id int);
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> insert into t2 values (3);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into t2 values (4);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> use t1;
    Database changed
    mysql> insert into t1 values (1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into t1 values (2);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> use t2;
    Database changed
    mysql> insert into t2 values(20);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> use t1;
    Database changed
    mysql> insert into t1 values(10);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> drop table t1;
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> use t2;
    Database changed
    mysql> insert into t2 values(222);
    Query OK, 1 row affected (0.01 sec)
    
    mysql>
    
    建立T1、T2库,建立T1、T2表。
    
    向T1插入数据:1210
    
    向T2插入数据:3420222
    
    模拟场景,删除T1表,T2库T2表业务还在继续运行

    现在将要通过日志将T1表进行恢复。

    首先要先找到那个删除命令的日志点:

    mysqlbinlog master-bin.000014|grep -5a "DROP TABLE"

    ![img](https://img-blog.csdn.net/20180903165303675?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoYWlnYW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    看到#AT 2439 (记下这个数字)

    在这个事件点执行的DROP TABLE操作。

    由于日志文件内不只有T1库的日志,还有T2库的日志,一会只取T1数据库的日志

    而且还只取2439日志点之前的日志,再进行重新应用

    如果把2439的日志取的话,再应用时数据库会重新建库建表,插数据, 还会执行这条删表语句。

    mysqlbinlog mysql-bin.000001 -d t1  --skip-gtids --stop-position=2439>test.sql

    -d:参数是指定某个数据库日志

    命令意思是将mysql-bin.000001日志文件内的T1数据库日志,事件点2439之前的日志,输出到test.sql

    # tail test.sql

    看看文件最后几行

    ![img](https://img-blog.csdn.net/20180903173513452?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoYWlnYW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    登录数据库:

    mysql> use t1;
    Database changed
    
    mysql> source test.sql

    再查看表内容

    ![img](https://img-blog.csdn.net/20180903173723296?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoYWlnYW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    这样数据就回来了。

  • 相关阅读:
    近期前端中的 一些常见的面试题
    一道前端学习题
    前端程序员容易忽视的一些基础知识
    web前端工程师入门须知
    Web前端知识体系精简
    面试分享:一年经验初探阿里巴巴前端社招
    抽象类、抽象函数/抽象方法详解
    C#语法-虚方法详解 Virtual 虚函数
    面向对象语言:继承关系教程
    C#动态创建Xml-LinQ方式
  • 原文地址:https://www.cnblogs.com/zy-303/p/13889629.html
Copyright © 2011-2022 走看看