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

目录
一、用户授权
1.1 grant授权
1.2 相关命令授权库
1.3 revoke撤销权限
二、root密码
2.1 恢复root密码(忘记密码)
2.2 重置root密码
三、MySQL备份
3.1 备份概述物理、逻辑备份
3.2 数据备份策略完全备份、增量备份
四、增量备份 binlog日志
4.1 binlog日志概述
4.2 启用日志
4.3 分析日志
4.4 恢复数据

一、用户授权
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/refman/5.7/en/privileges-provided.html

  • 库名
    *.* //所有库所有表
    库名.* //一个库
    库名.表名 //一张表

  • 用户名
    授权时自定义要有标识性
    存储在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
  • 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主从同步的必要条件

启用日志主要操作

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

[root@mysql ~]# systemctl restart mysqld

启用日志

  • 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)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容