MySQL数据库基础(四)grant授权、binlog日志介绍

一、用户授权

1.1 grant授权

  • grant授权︰添加用户并设置权限 命令格式

**grant 权限列表 on 库名 to 用户名@”客户端地址” identified by “密码” //授权用户密码
with grant option; //有授权权限,可选项**

mysql> grant all on db4.*to yaya@"%" identified by "123qqq..A”;
  • 权限列表
    all //所有权限
    usage //无权限
    select,update,insert //I个别权限
    select,update (字段1,.. ..,字段N) //指定字段
    用户详情的权限列表请参考MySQL官网说明:https://dev.mysql.com/doc/ref...
  • 库名

    \*.*          //所有库所有表
    库名.*        //一个库
    库名.表名      //一张表
    
  • 用户名
    授权时自定义要有标识性
    存储在mysql库的user表里
  • 客户端地址

    %   //所有主机
    192.168.4.%  //网段内的所有主机
    192.168.4.1  //1台主机
    localhost    //数据库服务器本机
    

应用示例
添加用户mydba,对所有库、表有完全权限
允许从任何客户端连接,密码abc123
且有授权权限

mysql> grant all on *.*  to  mydba@'%'  identified  by  "abc123"  with grant  option;
Query OK, 0 rows affected, 1 warning (0.02 sec)

需要注意的是 8.0之后的新版的的mysql版本已经将创建账户和赋予权限的方式分开了
之前创建方式会报错:

mysql> grant all on *.* to mydba@"%" identified by "abc123" with grant option;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by "123qqq...A" with grant option' at line 1

8.0 版本后 grant授权 创建账户和赋予权限的需要分两步完成
1.创建账户:create user '用户名'@'访问主机' identified by '密码';
2.赋予权限:grant 权限列表 on 数据库 to '用户名'@'访问主机' ;(修改权限时在后面加with grant option)
添加用户mydba@"%"

mysql> create user mydba@"%" identified by "abc123";
Query OK, 0 rows affected (0.11 sec)

mysql> grant all on *.* to mydba@"%" with grant option;
Query OK, 0 rows affected (0.06 sec)

应用示例
添加admin用户,允许从192.168.4.0/24网段连接,对db3库的user表有查询权限,密码123qqq.….A
添加admin2用户,允许从本机连接,允许对db3库的所有表有查询/更新/插入/删除记录权限,密123qqq....A

mysql> grant select on db3.user to  admin@"192.168.4.%"  identified  by  "123qqq...A";
mysql> grant select,insert,update,delete  on  db3.*  to  admin2@"localhost"   identified  by  "123qqq.….A";

1.2 相关命令授权库

MySQL数据库基础(四)grant授权、binlog日志介绍_第1张图片

  • 授权库 mysql
  • mysql 库记录授权信息,主要表如下:
    user 表记录已有的授权用户及权限
    db 表记录已有授权用户对数据库的访问权限
    tables_priv 表记录已有授权用户对表的访问权限
    columns_priv 表记录已有授权用户对字段的访问权限

查看表记录可以获取用户权限;也可以通过更新记录,修改用户权限

1.3 revoke撤销权限

  • 命令格式
    mysql> revoke 权限列表 on 库名.表 from 用户名@"客户端地址";

    mysql> revoke insert,drop on   test.*  FROM  sqlero2@'localhost';
    Query OK,0 rows affected (0.00 sec)
    

案例1:用户授权
1.允许192.168.4.0/24网段主机使用root连接数据库服务器,对所有库和所有表有完全权限、密码为 abc123...A
2.添加用户dba001,对所有库和所有表有完全权限、且有授权权限,密码为abc123...A 客户端为网络中的所有主机。
3.撤销root从本机访问权限,然后恢复。
4.允许任意主机使用webuser用户连接数据库服务器,仅对webdb库有完全权限,密码为abc123...A.撤销webuser的权限,使其仅有查询记录权限。

1)允许192.168.4.0/24网段主机使用root连接数据库服务器,对所有库和所有表有完全权限、密码为 abc123...A
192.168.4.100远程登陆MySQL

[root@case100 ~]# mysql -u root -p -h 192.168.4.151
Enter password:     \\输入密码  登陆报错
ERROR 1045 (28000): Access denied for user 'root'@'192.168.4.100' (using password: YES)

添加192.168.4.0/24访问权限

[root@mysql ~]# mysql -uroot -p"123456"

mysql> grant all on *.* to root@'192.168.4.%' identified by "abc123...A";
Query OK, 0 rows affected, 1 warning (0.00 sec)

再次从192.168.4.0/24网段的客户机访问时,输入正确的密码后可登入

[root@case100 ~]# mysql -u root -p -h 192.168.4.151
Enter password: 
mysql> select host,user from mysql.user ;       \\登陆成功
+-------------+-----------+
| host        | user      |
+-------------+-----------+
| %           | mydba     |
| 192.168.4.% | root      |
| localhost   | mysql.sys |
| localhost   | root      |
+-------------+-----------+
4 rows in set (0.01 sec)
mysql> create database rootdb;
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| rootdb             |      //新建的rootdb库
| sys                |
+--------------------+
5 rows in set (0.01 sec)

2)添加用户dba001,对所有库和所有表有完全权限、且有授权权限,密码为abc123...A 客户端为网络中的所有主机。

mysql> grant all on *.*   to  dba001@"%"  identified by "abc123...A"  with grant option;        //添加用户并授权
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show grants for dba001@"%";           //查看dba001权限
+---------------------------------------------------------------+
| Grants for dba001@%                                           |
+---------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'dba001'@'%' WITH GRANT OPTION |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

3)撤销root从本机访问权限,然后恢复。
注意:如果没有事先建立其他管理账号,请不要轻易撤销root用户的本地访问权限,否则恢复起来会比较困难,甚至不得不重装数据库。

mysql> revoke all on *.* from root@"localhost";     //撤销root@"localhost"所有权限
Query OK, 0 rows affected (0.01 sec)

mysql> show grants for root@localhost;          //查看root@localhost权限
+--------------------------------------------------------------+
| Grants for root@localhost                                    |
+--------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'root'@'localhost' WITH GRANT OPTION   |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+--------------------------------------------------------------+
2 rows in set (0.01 sec)

mysql> exit
Bye

[root@mysql ~]# mysql -uroot -p"123456"    //重装登陆测试

mysql> drop database rootdb;       //失败 报错
ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'rootdb'

尝试以当前的root用户恢复权限,也会失败(无权更新授权表):

mysql> grant all on *.* to root@localhost  with grant option;
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

mysql> exit
Bye

由管理账号dba001重新为root添加本地访问权限

[root@mysql ~]# mysql -udba001 -p"abc123...A"

mysql> grant all on *.* to root@localhost  with grant option;
Query OK, 0 rows affected (0.01 sec)

mysql> exit
Bye

[root@mysql ~]# mysql -uroot -p"123456"    //root帐号重新登陆测试

mysql> drop database rootdb;    //权限恢复 删除成功
Query OK, 0 rows affected (0.02 sec)

4)允许任意主机使用webuser用户连接数据库服务器,仅对webdb库有完全权限,密码为1abc123...A.撤销webuser的权限,使其仅有查询记录权限。

mysql> create database webdb;               //新建库webdb
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| webdb              |
+--------------------+
5 rows in set (0.01 sec)

mysql> grant all on webdb.* to webuser@'%' identified by "abc123...A";        //对用户webuser授权
Query OK, 0 rows affected, 1 warning (0.02 sec)

mysql> show grants for webuser@'%';
+----------------------------------------------------+
| Grants for webuser@%                               |
+----------------------------------------------------+
| GRANT USAGE ON *.* TO 'webuser'@'%'                |
| GRANT ALL PRIVILEGES ON `webdb`.* TO 'webuser'@'%' |
+----------------------------------------------------+
2 rows in set (0.00 sec)

mysql> revoke all on webdb.* from webuser@'%';     //撤销webuser@"%"所有权限
Query OK, 0 rows affected (0.02 sec)

mysql> show grants for webuser@'%';
+-------------------------------------+
| Grants for webuser@%                |
+-------------------------------------+
| GRANT USAGE ON *.* TO 'webuser'@'%' |
+-------------------------------------+
1 row in set (0.00 sec)

二、root密码

2.1 恢复root密码(忘记密码)

root密码忘了怎么办?
1.停止MySQL服务程序
2.跳过授权表启动MySQL服务程序
3.修改root密码
4.以正常方式重启MySQL服务程序

主要操作过程

]# vim  /etc/my.cnf
[mysqld]
......
skip_grant_tables              //配置中追加跳过权限检测
]# systemctl restart mysqld
]# mysql
mysql> update mysql.user set authentication_string=password(“密码”)
->where user="root" and host="localhost";                              //修改密码
mysql> flush privileges;                         //刷新立即生效,后面我们需要重启数据库,这步其实可以省略
mysql> quit ;

2.2 重置root密码

修改管理员root密码有很多种方法以下介绍几种常用的

1)方法1,在Shell命令行下设置

[root@mysql ~]# mysqladmin -uroot -p password 'abc321...A'
Enter password: 
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

2)方法2,以root登入mysql> 后,使用SET PASSWORD指令设置
这个与新安装MySQL-server后首次修改密码时要求的方式相同,平时也可以用:

mysql> SET PASSWORD FOR root@localhost=PASSWORD('1234567');
Query OK,0 rows affected,1warning(0.00 sec)

3)方法3,以root登入mysql> 后,使用GRANT授权工具设置,这个是最常见的用户授权方式:

mysql> GRANT all ON *.* TO root@localhost IDENTIFIED BY '1234567';
Query OK,0 rows affected,1warning(0.00 sec)

4)方法4,以root登入mysql> 后,使用UPDATE更新相应的表记录
这种方法与恢复密码时的操作相同:

mysql> UPDATE mysql.user SET authentication_string=PASSWORD('1234567') 
    -> WHERE user='root' AND host='localhost';        //重设root的密码
Query OK,0 rows affected,1warning(0.00 sec)
Rows matched:1  Changed:0  Warnings:1
mysql> FLUSH PRIVILEGES;                  //刷新授权表
Query OK,0 rows affected(0.00 sec)

在上述方法中,需要特别注意:当MySQL服务程序以 skip-grant-tables 选项启动时,如果未执行“FLUSH PRIVILEGES;”操作,是无法通过SET PASSWORD或者GRANT方式来设置密码的。比如,验证这两种方式时,都会看到ERROR 1290的出错提示:

mysql> SET PASSWORD FOR root@localhost=PASSWORD('1234567');
ERROR 1290(HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
mysql> GRANT all ON *.* TO root@localhost IDENTIFIED BY '1234567';
ERROR 1290(HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

案例2: root密码
具体要求如下:
1.恢复管理员root密码123qqq...A
2.重置管理员root密码 A...qqq321

[root@mysql ~]# systemctl stop mysqld
[root@mysql ~]# systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since 二 2020-12-22 17:38:12 CST; 6s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 21258 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 21240 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 21261 (code=exited, status=0/SUCCESS)

12月 22 11:45:03 mysql systemd[1]: Starting MySQL Server...
12月 22 11:45:04 mysql systemd[1]: Started MySQL Server.
12月 22 17:38:09 mysql systemd[1]: Stopping MySQL Server...
12月 22 17:38:12 mysql systemd[1]: Stopped MySQL Server.

[root@mysql ~]# vim /etc/my.cnf
skip_grant_tables
......

[root@mysql ~]# systemctl start mysqld
[root@mysql ~]# mysql 
mysql> update mysql.user set authentication_string=password('abc123...B') where user="root" and  host="localhost";
Query OK, 0 rows affected, 1 warning (0.02 sec)
Rows matched: 1  Changed: 0  Warnings: 1
mysql> flush privileges;                 
Query OK, 0 rows affected (0.01 sec)

mysql> exit

[root@mysql ~]# vim /etc/my.cnf
#skip_grant_tables
......
[root@mysql ~]# vim /etc/my.cnf
#skip_grant_tables              //删除skip_grant_tables  重启服务
......
[root@mysql ~]# systemctl restart mysqld
[root@mysql ~]# mysql -uroot  -p"abc123...B"

mysql> 

三、MySQL备份

3.1 备份概述物理、逻辑备份、完全备份、增量备份

备份概述
数据备份方式
物理备份
冷备:cp、tar、...

  • 逻辑备份

    mysqldump   //备份命令
    mysql   //恢复命令
    
  • 物理备份及恢复
  • 备份操作

    cp -r /var/lib/mysql  备份目录/mysql.bak
    tar -zcvf /root/mysql.tar.gz  /var/lib/mysql/*
    
  • 恢复操作

    cp -r 备份目录/mysql.bak  /var/lib/mysql/
    tar -zxvf /root/mysql.tar.gz  -C  /var/lib/mysq1/
    chown -R  mysql:mysql  /var/lib/mysql
    

数据备份策略

  • 完全备份
    备份所有数据
  • 增量备份
    备份上次备份后,所有新产生的数据
  • 差异备份
    备份完全备份后,所有新产生的数据
  • 完全备份及恢复

    完全备份
    ]#mysqldump -uroot -p密码库名 > 目录/xxx.sql
    完全恢复
    ]#mysql -uroot -p密码[库名] < 目录/xxx.sql
    
  • 备份时库名表示方式
    --all-databases 或 -A //所有库
    数据库名 //单个库
    数据库名表名 //单张表
    -B 数据库1 数据库2 //多个库

注意事项
无论备份还是恢复,都要验证用户权限!!!

完全备份及恢复 应用示例1

-将所有的库备份为allbak.sql文件
-将db3库备份为db3.sql文件

[root@dbsvr1 ~]# mysqldump  -uroot  -p密码   -A > allbak.sql
[root@dbsvr1 ~]# mysqldump  -uroot   -p密码   db3 > db3.sql
[root@dbsvr1 ~]# ls  -lh  *.sql
-rw-r--r--.1 root root 595K 1月2 13:54 allbak.sql-rw-r--r--. 1 root root 4.1K 1月2 13:55 db3.sql

案例3:数据备份与恢复
具体要求如下∶
1.练习mysqldump命令的使用
2.使用mysql命令恢复删除的数据

1)备份MySQL服务器上的所有库
将所有的库备份为mysql-all.sql文件

[root@mysql ~]# mysqldump -u root -p --all-databases >/root/alldb.sql       //备份所有库
Enter password: 

[root@mysql ~]# file /root/alldb.sql                //确定备份文件类型
/root/alldb.sql: UTF-8 Unicode text, with very long lines

[root@mysql ~]# cat /root/alldb.sql|head -15           //查看备份文件alldb.sql的部分内容:
-- MySQL dump 10.13  Distrib 8.0.22, for Linux (x86_64)
--
-- Host: localhost    Database: 
-- ------------------------------------------------------
-- Server version    8.0.22

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!50606 SET @OLD_INNODB_STATS_AUTO_RECALC=@@INNODB_STATS_AUTO_RECALC */;
/*!50606 SET GLOBAL INNODB_STATS_AUTO_RECALC=OFF */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
[root@mysql ~]# 

注意:若数据库都使用MyISAM存储引擎,可以采用冷备份的方式,直接复制对应的
数据库目录即可;恢复时重新复制回来就行。

2)只备份指定的某一个库

[root@mysql ~]# mysqldump -uroot -p db1 > db1.sql   //备份db1
Enter password: 

[root@mysql ~]# cat /root/db1.sql|head -15
-- MySQL dump 10.13  Distrib 8.0.22, for Linux (x86_64)
--
-- Host: localhost    Database: db1
-- ------------------------------------------------------
-- Server version    8.0.22

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

3)同时备份指定的多个库

[root@mysql ~]# mysqldump -u root -p -B mysql db1 db2  >mysql.db1.db2.sql  //备份db1 db2
Enter password:

[root@mysql ~]# ll /root/mysql.db1.db2.sql 
-rw-r--r-- 1 root root 1130849 12月 23 15:18 /root/mysql.db1.db2.sql

4)使用mysql 命令恢复删除的数据
以恢复db1库为例,可参考下列操作把数据恢复到另一台数据库上,如果是在原数据库操作通常不建议直接覆盖旧库,而是采用建立新库并导入逻辑备份的方式执行恢复,待新库正常后即可废弃或删除旧库

mysql> create databases db1bak;   
Query OK, 1 row affected (0.01 sec)
mysql> exit

[root@mysql ~]# mysql -u root -p db1bak < /root/db1.sql    //恢复所有库到db1bak
Enter password: 
[root@mysql ~]# mysql -uroot -p"abc321...A"
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db1bak             |
| mysql              |
| performance_schema |
| sys                |
| webdb              |
+--------------------+
6 rows in set (0.00 sec)

mysql> use db1bak
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> show tables;          //查看数据完整性
+------------------+
| Tables_in_db1bak |
+------------------+
| gz               |
| school           |
| t1               |
| t3               |
| t4               |
| t5               |
| t6               |
| t8               |
| tea4             |
| yg               |
+------------------+
10 rows in set (0.00 sec)

mysql> select * from t1;
+------+---------+
| name | homedir |
+------+---------+
| bob  | USA     |
+------+---------+
1 row in set (0.00 sec)

四、增量备份 binlog日志

4.1 binlog日志概述

-binlog日志也称做二进制日志
-MySQL服务日志文件的一种
-记录除查询之外的所有SQL命令
-可用于数据备份和恢复
-配置mysql主从同步的必要条件

MySQL数据库基础(四)grant授权、binlog日志介绍_第2张图片
启用日志主要操作

[root@mysql ~]# vim /etc/my.cnf
[mysqld]
...
log_bin   //启用binlog日志
server_id=100   //指定id值

[root@mysql ~]# systemctl restart mysqld

2.2 启用日志

  • binlog相关文件
    主机名-bin.index \\索引文件
    主机名-bin.000001 \\第1个二进制日志
    主机名-bin.000002 \\第2个二进制日志
  • 手动生成新的日志文件:
    方法1. ]# systemctl restart mysqld
    方法2. mysql> flush logs; 或 ]# mysql -uroot -p密码 -e'flush log'
    方法3.mysqldump --flush-logs
  • 清理日志
    删除指定编号之前的binlog日志文件
    Mysql> purge master logs to "binlog文件名"; \\删除所有binlog日志,重建新日志
    Mysql> reset master;

案例4 : binlog日志
启用binlog日志,具体要求如下:
1) 启用binlog日志,把日志文件存放到系统的/mylog目录下,日志文件为db50
2) 手动创建3个新的日志文件
3) 删除编号3之前的日志文件

[root@mysql ~]# vim /etc/my.cnf
[mysqld]
......
log_bin=/mylog/db50
server_id=1

[root@mysql ~]# systemctl restart mysqld
[root@mysql ~]# ll /mylog/
总用量 8
-rw-r----- 1 mysql mysql 154 12月 23 16:49 db50.000001
-rw-r----- 1 mysql mysql  19 12月 23 16:49 db50.index

[root@mysql ~]# mysql -uroot -p"abc321...A"

mysql> flush logs;                   //每执行一次都会生成新的日志文件
Query OK, 0 rows affected (0.08 sec)

mysql> flush logs;
Query OK, 0 rows affected (0.02 sec)

mysql> flush logs;                  
Query OK, 0 rows affected (0.02 sec)

mysql> system ls /mylog/
db50.000001  db50.000002  db50.000003  db50.000004  db50.index

mysql> show master status;    //查看当前使用的日志文件
+-------------+----------+--------------+------------------+-------------------+
| File        | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------+----------+--------------+------------------+-------------------+
| db50.000004 |      154 |              |                  |                   |
+-------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> purge master logs to "db50.000003";     //删除db50.000003之前的日志文件
Query OK, 0 rows affected (0.05 sec)

mysql> system ls /mylog/
db50.000003  db50.000004  db50.index
mysql>  cat /mylog/db50.index           //查看日志索引
/mylog/db50.000003
/mylog/db50.000004

4.3 分析日志

查看日志当前记录格式

mysql> show variables like "binlog_format";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.03 sec)
  • 三种记录方式:
    1.statement报表模式
    2.row行模式
    3.mixed混合模式
    以上3种模式具体差异可自行查找,推荐mixed混合模式结合了1,2的优势
  • 修改日志记录格式操作
    [root@localhost ~]# vim /etc/my.cnf
    [mysqld]
    .. ..
    binlog_format=“名称”
    [root@localhost ~]# systemctl restart mysqld
  • 查看日志内容
    mysqlbinlog [选项] binlog 日志文件名
    选项
    用途
    --start-datetime="yyyy-mm-dd hh:mm:ss” 起始时间 从二进制日志中读取指定等于时间戳或者晚于本地计算机的时间
    --stop-datetime="yyyy-mm-dd hh:mm:ss"结束时间 从二进制日志中读取指定小于时间戳或者等于本地计算机的时间
    --start-position=数字 起始偏移量 从二进制日志中读取指定position 事件位置作为开始。
    --stop-position=数字 结束偏移量 从二进制日志中读取指定position 事件位置作为事件截至

在使用binlog数据恢复时,推荐使用事件位置来确定开始与截至段 会更精确
时间的方式只精确到秒,如果一秒内同时发生了添加和删除操作恢复会失败

4.4 恢复数据

  • 基本思路
    使用mysqlbinlog提取历史SQL操作,通过管道交给mysql命令执行
    ·命令格式
    mysqlbinlog 日志文件│mysql -uroot -p密码
  • 应用示例
    使用编号为1的日志文件恢复数据
    ]# cd /var/lib/mysql
    ]# mysqlbinlog mysql-bin.000001 | mysql -uroot -p123456

案例5:使用binlog日志恢复数据
利用binlog恢复库表,要求如下∶
1.启用binlog日志、并修改格式为mixed
2.创建db1库和tb1表并插入3条记录
3.删除tb1表中刚插入的3条记录
4.使用binlog日志恢复删除的3条记录

[root@mysql ~]# vim /etc/my.cnf
......
binlog_format="mixed"

[root@mysql ~]# systemctl restart mysqld
[root@mysql ~]# ll /var/lib/mysql/mysql-bin.*
-rw-r----- 1 mysql mysql 177 12月 23 16:30 /var/lib/mysql/mysql-bin.000001
-rw-r----- 1 mysql mysql 154 12月 23 17:09 /var/lib/mysql/mysql-bin.000002
-rw-r----- 1 mysql mysql  38 12月 23 17:09 /var/lib/mysql/mysql-bin.index

[root@mysql ~]# systemctl restart mysqld           //每次重启服务都会生成新的日志文件
[root@mysql ~]# ls /var/lib/mysql/mysql-bin.*
/var/lib/mysql/mysql-bin.000001  /var/lib/mysql/mysql-bin.000003
/var/lib/mysql/mysql-bin.000002  /var/lib/mysql/mysql-bin.index

[root@mysql ~]# mysql -uroot -p"abc321...A"

mysql> create database db1;      //新建库db1
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db1                |
| db1bak             |
| mysql              |
| performance_schema |
| sys                |
| webdb              |
+--------------------+
7 rows in set (0.00 sec)

mysql> use db1;
Database changed
mysql> create table tb1( id int(4) not null,name varchar(24));
Query OK, 0 rows affected (0.12 sec)

mysql> insert into db1.tb1 values
    -> (1,"Jack");
Query OK, 1 row affected (0.15 sec)

mysql> insert into db1.tb1 values    //写入数据
    -> (2,"Kenthy"),
    -> (3,"Bob");
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from tb1;
+----+--------+
| id | name   |
+----+--------+
|  1 | Jack   |
|  2 | Kenthy |
|  3 | Bob    |
+----+--------+
3 rows in set (0.02 sec)

mysql> delete from tb1;
Query OK, 3 rows affected (0.07 sec)

mysql> select * from tb1;
Empty set (0.00 sec)

mysql> exit
Bye

[root@mysql ~]# ls /var/lib/mysql/mysql-bin.*
/var/lib/mysql/mysql-bin.000001  /var/lib/mysql/mysql-bin.000003
/var/lib/mysql/mysql-bin.000002  /var/lib/mysql/mysql-bin.index
[root@mysql ~]# mysqlbinlog /var/lib/mysql/mysql-bin.000003    //查看mysql-bin.000003日志内容
......
# at 310
#201223 17:23:29 server id 1  end_log_pos 375 CRC32 0xeb6b5cae     Anonymous_GTID    last_committed=1    sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 375
#201223 17:23:29 server id 1  end_log_pos 501 CRC32 0x8378de25     Query    thread_id=3    exec_time=0 error_code=0
use `db1`/*!*/;
SET TIMESTAMP=1608715409/*!*/;
create table tb1( id int(4) not null,name varchar(24))
/*!*/;
# at 501
#201223 17:26:25 server id 1  end_log_pos 566 CRC32 0xbe733bf7     Anonymous_GTID    last_committed=2    sequence_number=3
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 566
#201223 17:26:25 server id 1  end_log_pos 643 CRC32 0xc08d9b7f     Query    thread_id=3    exec_time=0 error_code=0
SET TIMESTAMP=1608715585/*!*/;
BEGIN
/*!*/;
# at 643                       //起启位置为643
#201223 17:26:25 server id 1  end_log_pos 752 CRC32 0xc2cee70c     Query    thread_id=3    exec_time=0 error_code=0
SET TIMESTAMP=1608715585/*!*/;
insert into db1.tb1 values                         
(1,"Jack")
/*!*/;
# at 752
#201223 17:26:25 server id 1  end_log_pos 783 CRC32 0xf25ad0e7     Xid = 17
COMMIT/*!*/;
# at 783
#201223 17:27:25 server id 1  end_log_pos 848 CRC32 0x35f44d85     Anonymous_GTID    last_committed=3    sequence_number=4
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 848
#201223 17:27:25 server id 1  end_log_pos 925 CRC32 0xbf81905c     Query    thread_id=3    exec_time=0 error_code=0
SET TIMESTAMP=1608715645/*!*/;
BEGIN
/*!*/;
# at 925
#201223 17:27:25 server id 1  end_log_pos 1047 CRC32 0x494b097c     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1608715645/*!*/;
insert into db1.tb1 values
(2,"Kenthy"),
(3,"Bob")
/*!*/;
# at 1047                  
#201223 17:27:25 server id 1  end_log_pos 1078 CRC32 0x45782a98     Xid = 18
COMMIT/*!*/;
# at 1078                      //以1078为截至 
#201223 17:28:48 server id 1  end_log_pos 1143 CRC32 0x92d54ab2     Anonymous_GTID    last_committed=4    sequence_number=5
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1143
#201223 17:28:48 server id 1  end_log_pos 1220 CRC32 0xc58763f7     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1608715728/*!*/;
BEGIN
/*!*/;
# at 1220
#201223 17:28:48 server id 1  end_log_pos 1307 CRC32 0xc2402c25     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1608715728/*!*/;
delete from tb1
/*!*/;
# at 1307
#201223 17:28:48 server id 1  end_log_pos 1338 CRC32 0x9be4cbf8     Xid = 20
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
......

也可以通过 show binlog命令查看位置点 更清晰

mysql> show binlog events in "mysql-bin.000003"; 
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos  | Event_type     | Server_id | End_log_pos | Info                                                              |
+------------------+------+----------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000003 |    4 | Format_desc    |         1 |         123 | Server ver: 5.7.17-log, Binlog ver: 4                             |
| mysql-bin.000003 |  123 | Previous_gtids |         1 |         154 |                                                                   |
| mysql-bin.000003 |  154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |
| mysql-bin.000003 |  219 | Query          |         1 |         310 | create database db1                                               |
| mysql-bin.000003 |  310 | Anonymous_Gtid |         1 |         375 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |
| mysql-bin.000003 |  375 | Query          |         1 |         501 | use `db1`; create table tb1( id int(4) not null,name varchar(24)) |
| mysql-bin.000003 |  501 | Anonymous_Gtid |         1 |         566 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |
| mysql-bin.000003 |  566 | Query          |         1 |         643 | BEGIN                                   //起启位置为643            |
| mysql-bin.000003 |  643 | Query          |         1 |         752 | use `db1`; insert into db1.tb1 values
(1,"Jack")                  |
| mysql-bin.000003 |  752 | Xid            |         1 |         783 | COMMIT /* xid=17 */                                               |
| mysql-bin.000003 |  783 | Anonymous_Gtid |         1 |         848 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |
| mysql-bin.000003 |  848 | Query          |         1 |         925 | BEGIN                                                             |
| mysql-bin.000003 |  925 | Query          |         1 |        1047 | use `db1`; insert into db1.tb1 values
(2,"Kenthy"),
(3,"Bob")     |
| mysql-bin.000003 | 1047 | Xid            |         1 |        1078 | COMMIT /* xid=18 */                    //以1078为截至            |
| mysql-bin.000003 | 1078 | Anonymous_Gtid |         1 |        1143 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |
| mysql-bin.000003 | 1143 | Query          |         1 |        1220 | BEGIN                                                             |
| mysql-bin.000003 | 1220 | Query          |         1 |        1307 | use `db1`; delete from tb1                                        |
| mysql-bin.000003 | 1307 | Xid            |         1 |        1338 | COMMIT /* xid=20 */                                               |
| mysql-bin.000003 | 1338 | Anonymous_Gtid |         1 |        1403 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                              |

注意:起启和截至位置要包含需要恢复的位置段,不能等于需要恢复位置 比如以上的起启位置不能为752 结束不能为1047

[root@mysql ~]# mysqlbinlog --start-position="643" --stop-position="1078" /var/lib/mysql/mysql-bin.000003|mysql -u root -p"abc321...A"
mysql: [Warning] Using a password on the command line interface can be insecure.

[root@mysql ~]# mysql -uroot -p"abc321...A"

mysql> use db1
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 * from db1.tb1;     //恢复成功
+----+--------+
| id | name   |
+----+--------+
|  1 | Jack   |
|  2 | Kenthy |
|  3 | Bob    |
+----+--------+
3 rows in set (0.01 sec)

你可能感兴趣的