mysql【周六】day13

课程回顾:
事务的生命周期管理
标准的事务控制语句

begin
DML  #标准的事务语句
commit
rollback

autocommit机制
触发前提:参数为1----开启了
没有显示的触发 begin操作和commit操作
特点:每次执行任何的DML语句时,会自动添加begin,结束时commit

隐式提交
事务期间出现了DML时,自动提交
隐式回滚
客户端连接关闭、实例关闭、资源冲突时(死锁时)

事务的‘隔离级别

RU 读未提交 可能出现问题:脏读、不可重复读、幻读
RC 读以提交 可能出现问题:不可重复读、幻读
RR 可重复读 可能出现问题: 有时会出现“幻读”,大部分情况可以预防
SR 串行化 完全隔离 但是并发性不好

事务的工作流程原理:
专业名词介绍
redo
( redo log、log buffer) 内存数据的变化日志
page
(ibd 磁盘page、 buffer pool 内存配置) 存储数据行和索引
undo
(5.7默认在ibdataN中,可以配置为独立;undo的段(128段);96个段在undo中 ;32个临时表空间使用) 存储回滚信息
LSN

:日志序列号 (从小到大增长的,增长的幅度取决于日志的字节量)存储位置(redo log buffer 当前LSN;redo log flush log LSN; 磁盘数据页的LSN CKPT LSN)
数据库宕机启动时,flush log 的LSN 和CKPT LSN 对比 进行判断是否要进行恢复数据
WAL (日志优先写)
wwrite ahead log
redo 优先于数据页落盘
dirtry 脏页
在buffer中被修改过的数据页,还有落盘的
checkpoit (异步落盘)

作用:较为及时的将数据页刷写到磁盘上
触发条件:1、sharp checkpoint 正常关闭数据库时触发
2、fuzzy checkpoint master thread checkpoint 大约每秒或者每十秒触发一次
触发的参数

mysql> show  variables  like '%innodb_io%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |  每次200个
| innodb_io_capacity_max | 2000  |   不能超过2000
+------------------------+-------+
2 rows in set (0.00 sec)

3、fuzzy flush_lru_list__checkpoint 介绍:buffer pool 中的LRU内存链表可用内存页数 最近最少使用原则内存链表

show  variables  like '%lru%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+
1 row in set (0.01 sec)

当低于这几个值的时候,就会触发CKPT
async/sync flush checkpoint (75% 软限制 async)
(90% 硬限制 sync)
checkpoint_age=redo_lsn-checkpoint_lsn
dirty page too much checkpoint
(buffer pool 脏页太多的时候,默认75%) (innodb_max_dirty_pages_pct)

mysql> show  variables  like '%innodb_max_%';
+--------------------------------+-----------+
| Variable_name                  | Value     |
+--------------------------------+-----------+
| innodb_max_dirty_pages_pct     | 75.000000 |

回滚信息
DB_TRX_ID 事务编号
DB_ROLL_PTR undo回滚信息
redo log重做日志如何应用
作用:提供ACID的,主要是D的特性,对AC也有关联,CR过程中提供前滚功能
记录的是,内存数据页的变化,LSN号码生成
redo日志 由于有批量刷新的功能,有部分未提交的事务,二redo也会被写到磁盘,使用commit标签进行区分。
undo log 回滚日志如何应用
作用:ACID中,主要提供A的特性,对于C和I也有影响;在CR过程中提供回滚功能。
事务中C的特性怎么保证
CR
DWB
在这里插入图片描述

脏页控制参数
在这里插入图片描述

在这里插入图片描述

事务中的I的特性怎么保证?
隔离级别:读隔离性
RU : 脏读 、 不可重复读 、幻读
RC : 不可重复读、幻读
RR :有可能会出现幻读。
SR(SE) :事务串行工作。

锁的机制 写的隔离
作用:保护并发访问资源
保护的资源分类:
latch (栓锁):rwlock、mutex 主要保护内存资源
MDL:metadata lock 元数据锁(DDL操作的)
table_lock : 表级锁
lock table t1 read;
mysqldump\XBK(PBK):备份非innodb数据时,触发FTWRL全局锁表(global)
行锁升级为表锁:默认情况下innodb的锁都是行锁,如果是修改全表的所有行升级时,会升级为表锁。

row lock:默认锁粒度是行级锁,加锁的方式都是在索引上加锁的
record lock 记录锁,在聚簇索引加锁
gap lock 间隙锁 在辅助索引加锁 (辅助索引的键值范围)
next lock GAP+record 所有(辅助索引加锁+聚簇索引加锁)索引加锁 下键锁。

RC级别只存在record lock 锁
RR级别中存在 gap lock 和 next lock 防止幻读。(虽然RR级别也可能出现幻读,但是很少出现)

什么是幻读,RR级别又是如何防止幻读的?

演示:不可重复读现象
第一步:查看隔离级别

select  @@transact
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-COMMITTED          |
+-------------------------+
1 row in set (0.00 sec)



RC级别下幻读现象演示:  

准备工作: 
mysql> alter table t1 add index(num);
[root@db01 ~]# mysqldump  test t1 >/tmp/t1.sql

session A : 

第一步: 
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | aa   |
|  2 |   3 | c    |
|  3 |   6 | d    |
|  4 |   7 | x    |
|  5 |  11 | a    |
|  6 |  23 | c    |
|  7 |  36 | d    |
|  8 |  37 | x    |
|  9 |  51 | as   |
| 10 |  63 | hc   |
| 11 |  76 | ds   |
| 12 |  87 | xyz  |
+----+-----+------+
12 rows in set (0.00 sec)


第三步: 
mysql> update t1 set num=10 where num<10;
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0

第五步: 
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |  10 | aa   |
|  2 |  10 | c    |
|  3 |  10 | d    |
|  4 |  10 | x    |
|  5 |  11 | a    |
|  6 |  23 | c    |
|  7 |  36 | d    |
|  8 |  37 | x    |
|  9 |  51 | as   |
| 10 |  63 | hc   |
| 11 |  76 | ds   |
| 12 |  87 | xyz  |
| 13 |   5 | aaa  |
+----+-----+------+


Session B: 

第二步: 
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | aa   |
|  2 |   3 | c    |
|  3 |   6 | d    |
|  4 |   7 | x    |
|  5 |  11 | a    |
|  6 |  23 | c    |
|  7 |  36 | d    |
|  8 |  37 | x    |
|  9 |  51 | as   |
| 10 |  63 | hc   |
| 11 |  76 | ds   |
| 12 |  87 | xyz  |
+----+-----+------+
12 rows in set (0.00 sec)

第四步: 
mysql> insert into t1(num,name) values(5,'aaa');
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)



演示二:RC读以提交 级别下幻读现象演示:
在事务工作期间,SQL层已经执行了,只是没有落盘,在还没有提交之前,又一个窗口进行插入操作,并且已经commit,提交了。此时第一个SQL层再commit,会导致新插入的数据即使满足第一条语句的条件,但是还是不会作用到这个语句上
打开两个会话窗口

RC级别下不可重读现象演示:  
vim /etc/my.cnf 
#添加隔离级别参数:
transaction_isolation=READ-COMMITTED
#重启数据库 
[root@db01 ~]# /etc/init.d/mysqld restart

打开两个会话窗口: 

sessionA: 
第一步:
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-COMMITTED          |
+-------------------------+
1 row in set (0.00 sec)


第三步: 
mysql> create database test charset utf8mb4;
mysql> use test;
mysql> create table t1 (id int primary key auto_increment,num int not null , name varchar(20) not null);
mysql> insert into t1(num,name) values(1,'a'),(3,'c'),(6,'d'),(7,'x');
mysql> insert into t1(num,name) values(11,'a'),(23,'c'),(36,'d'),(37,'x'');
mysql> insert into t1(num,name) values(51,'as'),(63,'hc'),(76,'ds'),(87,'x','xyz');
mysql> commit;
mysql> select * from t1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | a    |
|  2 |   3 | c    |
|  3 |   6 | d    |
|  4 |   7 | x    |
|  5 |  11 | a    |
|  6 |  23 | c    |
|  7 |  36 | d    |
|  8 |  37 | x    |
|  9 |  51 | as   |
| 10 |  63 | hc   |
| 11 |  76 | ds   |
| 12 |  87 | xyz  |
+----+-----+------+

第五步: 
mysql> begin;


第七步: 
mysql> update t1 set name='aa' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

=================================================
sessinB: 
第二步:
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| READ-COMMITTED          |
+-------------------------+
1 row in set (0.00 sec)

第四步: 
mysql> use test;

mysql> select * from test.t1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | a    |
|  2 |   3 | c    |
|  3 |   6 | d    |
|  4 |   7 | x    |
|  5 |  11 | a    |
|  6 |  23 | c    |
|  7 |  36 | d    |
|  8 |  37 | x    |
|  9 |  51 | as   |
| 10 |  63 | hc   |
| 11 |  76 | ds   |
| 12 |  87 | xyz  |
+----+-----+------+
12 rows in set (0.00 sec)

第六步: 
mysql> begin;
mysql> select * from t1 where id=1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | a    |
+----+-----+------+
1 row in set (0.00 sec)

第八步: 
mysql> select * from t1 where id=1;
+----+-----+------+
| id | num | name |
+----+-----+------+
|  1 |   1 | aa   |
+----+-----+------+
1 row in set (0.00 sec)


==================================


在这里插入图片描述
RR级别:防止幻读的演示
和锁有关。导致在这个行进行commit之前,都会有锁。如果此时有人在另外一个窗口进行插入操作,会导致卡住,不能进行修改。

在这里插入图片描述
防止幻读:前提是,1、where后的条件需要有辅助索引。如果没有辅助索引,就会出现行级锁升级为表级锁;2、RR级别才会有gap锁(键值范围)

功能上:
IS 不研究
S 读锁; select * from t1 lock in shared mode; 不研究
IX 意向排它锁 针对表 ; select * from t1 for update;
X 排它锁 ,写锁 针对行

IX 针对表 X 针对行 ;IX是X的前提,如果没法对该行的表进行 表的意向锁 则不能对行进行排他锁
加锁的行,不能进行并发处理了。

IX 针对表 X 针对行 ;IX是X的前提,如果没法对该行的表进行 表的意向锁 则不能对行 进行的排他锁

在这里插入图片描述

哪些锁不能同时进行,也就是锁的兼容性问题

在这里插入图片描述

MVCC:多版本并发控制(针对读操作)
每个事物都需要经历两个阶段:
读和写

不管是进行什么操作都需要:
读的步骤
写的步骤

MVCC是针对读的操作,进行并发控制,因为读是不需要加锁的。写的操作是由锁来控制的,不属于MVCC管理范围。

利用乐观锁机制,实现非锁定读取

什么是乐观锁
到时候后再说
读的时候就是乐观锁

什么是悲观锁
一开始就锁上
写的操作时,主要悲观锁

read view 版本号集合

trx1
begin;
dml1 —在做第一个查询的时候,当前事物,获取当前系统最新的;RV1版本快照
dml2 —生成一个RV2的版本快照
select 查询RV2快照的数据情况,当commit时 会被更新到系统的最新快照
commit;

先说一个redo view

RC级别
一个快照可以读取到另一个已经提交的事务的全新快照

RR级别
一个查询 生成一个快照,一直伴随着事务生命周期结束。
trx1: 不可重复读的现象

快照技术是由undo log来提供

总结:MVCC
1、MVCC采用乐观锁机制实现非锁定读取
2、MVCC在RC级别下,事务可以立即读取到另一个事务已经提交的最新的redo view
3、MVCC在RR级别下,事务中从第一次查询开始,生成了一个redo view(只有这一个版本) 一直伴随到事务结束

日志管理
错误日志
作用:记录数据库启动以来,状态、警告、报错。诊断数据库报错问题
默认:开启状态。存放在数据目录下(/data/3306/data/.err)

查询配置

mysql> select @@log_error;
+-------------+
| @@log_error |
+-------------+
| ./db01.err  |
+-------------+
1 row in set (0.00 sec)

mysql> select @@datadir;
+------------------+
| @@datadir        |
+------------------+
| /data/3306/data/ |
+------------------+
1 row in set (0.00 sec)

修改配置

修改配置: 
[root@db01 ~]# mkdir -p /data/3306/logs
[root@db01 ~]# chown -R mysql.mysql /data/*
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
#添加:
log_error=/data/3306/logs/mysql.err

[root@db01 logs]# cat /etc/my.cnf
[mysqld]
log_error=/data/3306/logs/mysql.err  这个日志文件的属主属组是mysql且是touch创建出来的,然后数据
# 重启报错 
[root@db01 ~]# /etc/init.d/mysqld restart
++++++++++++++++++++++
Shutting down MySQL.. SUCCESS! 
Starting MySQL.2020-05-09T06:51:36.457401Z mysqld_safe error: log-error set to '/data/3306/logs/mysql.err', however file don't exists. Create writable for user 'mysql'.
 ERROR! The server quit without updating PID file (/data/3306/data/db01.pid).
++++++++++++++++++++++
[root@db01 ~]# touch /data/3306/logs/mysql.err 
[root@db01 ~]# chown -R mysql.mysql /data/*
# 重新启动
[root@db01 ~]# /etc/init.d/mysqld restart

报错是因为touch的日志文件没有设置属主属组为mysql

查看日志

# 模拟故障 
[root@db01 ~]# chown -R root.root /data/3306/data/ibdata1 
[root@db01 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL.. ERROR! The server quit without updating PID file (/data/3306/data/db01.pid).
[root@db01 ~]# 

# 排查思路 : 
[ERROR]  行: 
2020-05-09T06:56:09.226056Z 0 [ERROR] InnoDB: The innodb_system data file 'ibdata1' must be writable

日志切割

[root@db01 logs]# ll
total 32
-rw-r--r-- 1 mysql mysql 31445 May  9 03:04 mysql.err
[root@db01 logs]# cp mysql.err mysql.err_`date +%F`
[root@db01 logs]# ll
total 64
-rw-r--r-- 1 mysql mysql 31445 May  9 03:04 mysql.err
-rw-r--r-- 1 root  root  31445 May  9 03:06 mysql.err_2020-05-09
[root@db01 logs]# > mysql.err

grep  -r  'ERROR'  mysql.err_2020-05-09

二进制日志(binlog)*****
作用:
1、用来做数据恢复 PTR 基于时间点的恢复
2、主从复制依赖于二进制日志

日志内容介绍:
记录数据库修改类的操作(逻辑日志)
DML:insert update delete
DDL:create drop alter trucate
DCL:grant revoke lock(锁表语句)

配置方法:

8.0版本之前默认不开启
mysql> select  @@log_bin;
mysql> select  @@log_bin_basename;
mysql> select  @@server_id;

配置基础参数

vim /etc/my.cnf
[mysqld]
server_id=6  主机ID  在主从复制会使用
log_bin=/data/3306/logs/mysql-bin   开关+文件路径+文件名前缀  最终格式:mysql-bin.001 002 003 

 重启生效 
[root@db01 logs]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL.. SUCCESS! 


bin log内容的记录格式
事件(event)的方式记录
最小的记录单元
每个事件:
1、事件描述 事件戳、server_id、加密方式、开始的位置(satrt_pos)、结束位置点(end_pos)
2、事件内容 修改类的操作(DDL、DML)SQL语句 或者 数据行变化。
重点关注:
开始位置点(satrt_pos)
结束位置点 (end_pos)
事件内容

二进制日志事件内容格式

mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.00 sec)

作用:
对于DDL、DCL语句 直接将SQL本身记录到binlog中
对于DML:insert update delete 受到binlog_format 参数控制
SBR:statement :语句模式,之前版本,默认模式
RBR: ROW 行记录模式。5.7之后,默认模式
MBR:miexd 混合模式

RBR和SBR的区别:
SBR:记录SQL语句本身 RBR:记录的是100个数据行的变化 记录的比较准确。
SBR 日志量比较少 RBR日志量比较多 并且SBR记录的不够准确,列如:使用now()函数,直接记录语句本身的话,时间就不一样了。

binlog的应用
1、日志文件情况查询
查看日志文件是否存在

mysql> show  binary logs;  查看所有的日志文件信息
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)

刷新日志(每刷新一次,会出现一个日志文件)

mysql> flush logs;产生一个新的日志

查看当前正在使用的日志文件

mysql> show  master  status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

内容查询

mysql> show  binlog  events in 'mysql-bin.000005';

关注黄色
在这里插入图片描述
ROW格式,所以需要使用这个看

查看binlog日志,也可以进行截取binlog日志

[root@db01 logs]# mysqlbinlog /data/3306/logs/mysql-bin.000005
# at 324
#200509  3:50:10 server id 6  end_log_pos 389 CRC32 0x2d401b39  Anonymous_GTID  last_committed=1     sequence_number=2        rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 389
#200509  3:50:10 server id 6  end_log_pos 487 CRC32 0x66e33e19  Query   thread_id=3     exec_time=0  error_code=0
use `ku`/*!*/;
SET TIMESTAMP=1589010610/*!*/;
create  table  biao (id int)
/*!*/;
# at 487

插入操作的两种方式

在这里插入图片描述
查看日志内容

[root@db01 logs]# mysqlbinlog /data/3306/logs/mysql-bin.000005 

#### create table 日志内容
# at 388
#200509 15:49:59 server id 6  end_log_pos 484 CRC32 0x8b05dfaf 	Query	thread_id=3	exec_time=0	error_code=0
use `ku`/*!*/;
create table biao (id int)
/*!*/;
# at 484

insert 操作的日志内容

# at 549
#200509 15:50:36 server id 6  end_log_pos 619 CRC32 0x515eec96 	Query	thread_id=3	exec_time=0	error_code=0
SET TIMESTAMP=1589010636/*!*/;
BEGIN
/*!*/;
# at 619
#200509 15:50:36 server id 6  end_log_pos 664 CRC32 0xedfb82fb 	Table_map: `ku`.`biao` mapped to number 108
# at 664
#200509 15:50:36 server id 6  end_log_pos 704 CRC32 0x5762132e 	Write_rows: table id 108 flags: STMT_END_F
BINLOG '
zGC2XhMGAAAALQAAAJgCAAAAAGwAAAAAAAEAAmt1AARiaWFvAAEDAAH7gvvt
zGC2Xh4GAAAAKAAAAMACAAAAAGwAAAAAAAEAAgAB//4BAAAALhNiVw=='
/*!*/;
# at 704
#200509 15:50:40 server id 6  end_log_pos 735 CRC32 0xb06a212b 	Xid = 24
COMMIT/*!*/;

[root@db01 logs]# mysqlbinlog --base64-output=decode-rows -vv  /data/3306/logs/mysql-bin.000005 

.....略。
BEGIN
/*!*/;
# at 619
#200509 15:50:36 server id 6  end_log_pos 664 CRC32 0xedfb82fb 	Table_map: `ku`.`biao` mapped to number 108
# at 664
#200509 15:50:36 server id 6  end_log_pos 704 CRC32 0x5762132e 	Write_rows: table id 108 flags: STMT_END_F
### INSERT INTO `ku`.`biao`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 704
#200509 15:50:40 server id 6  end_log_pos 735 CRC32 0xb06a212b 	Xid = 24
COMMIT/*!*/;

binlog日志翻译一下

[root@db01 logs]# mysqlbinlog  --base64-output=decode-rows  -vv /data/3306/logs/mysql-bin.000005

二进制日志的截取以及恢复演练

故障模拟

mysql> drop  database  ku;
Query OK, 1 row affected (0.14 sec)

binlog日志截取及恢复演练
故障模拟

mysql> drop database ku;
Query OK, 1 row affected (0.01 sec)

需要恢复ku的所有数据到删库之前
思路:
1、截取从建库以来到删除库之前的所有binlog
2、将截取的日志进行回放
思路:
1、截取从建库以来到删除库之前的所有binlog
起点:建库的位置点(position)
终点:删库的位置点(position)

在这里插入图片描述

2、将截取的日志进行回放

[root@db01 logs]# mysqlbinlog --start-position=219 --stop-position=707  /data/3306/logs/mysql-bin.000005 > /tmp/bin.sql
source /tmp/bin.sql;
mysql> set  sql_log_bin=0;关闭当前窗口的二进制binlog日志
Query OK, 0 rows affected (0.00 sec)

别忘记恢复完以后,在设置回来
mysql> set sql_log_bin=1;

如果是生产中会有什么痛点?
1、如果需要的日志在多文件中,怎么截取?
恢复方法:
方法一:多个文件 分段截取
–start-position 开始
–stop-position 结束
方法二:按照时间戳截取
起点:建库的时间戳

200509  5:12:49  
200509  5:15:43  

方法三:gtid 最靠谱的方法

1、找起点
2、找终点
3、截取日志

2、binlog日志属于全局日志,如果在对一个库进行操作时,其他的库的操作记录也会记录下来,怎么排除掉。
3、日志中有一百万行日志,怎么快速找到drop的位置点
4、如果删除的库是在两年前创建的,这种情况怎么办?

彩蛋:

思考一下:如果生产中会有什么痛点?
1. 需要的日志在多个文件中,怎么截取? 
# 场景模拟: 
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 |      886 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
mysql> create database tongdian charset=utf8mb4;
mysql> use tongdian 
mysql> create table t1 (id int);
mysql> flush logs;
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
mysql> insert into t1 values(1),(2),(3);
mysql> commit;
mysql> flush logs;
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
mysql> create table t2(id int);
mysql> insert into t2 values(1),(2),(3);
mysql> commit;
mysql> flush logs;
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000008 |      154 |              |                  |                   |

mysql> insert into t2 values(11),(22),(33);
mysql> commit;
mysql> drop database tongdian;


# 恢复方法: 
方法1: 分段截取
--start-position    --stop-position 

方法2: 时间戳截取

1. 找起点 :建库的时间戳 

(1) 起点:  postion 号
mysql> show binlog events in 'mysql-bin.000005';
| mysql-bin.000005 |  951 | Query          |         6 |        1073 | create database tongdian charset=utf8mb4 |

(2) 通过position 过滤时间戳
[root@db01 logs]# mysqlbinlog --start-position=951  --stop-position=1073 mysql-bin.000005 |grep -A 1 '^\#\ at\ 951'
# at 951
#200509 17:11:23 server id 6  end_log_pos 1073 CRC32 0x220759ef 	Query	thread_id=8	exec_time=0	error_code=0

2. 找终点

[root@db01 logs]# mysql -e "show binlog events in  'mysql-bin.000008'"
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000008 |   4 | Format_desc    |         6 |         123 | Server ver: 5.7.28-log, Binlog ver: 4 |
| mysql-bin.000008 | 123 | Previous_gtids |         6 |         154 |                                       |
| mysql-bin.000008 | 154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000008 | 219 | Query          |         6 |         295 | BEGIN                                 |
| mysql-bin.000008 | 295 | Table_map      |         6 |         344 | table_id: 112 (tongdian.t2)           |
| mysql-bin.000008 | 344 | Write_rows     |         6 |         394 | table_id: 112 flags: STMT_END_F       |
| mysql-bin.000008 | 394 | Xid            |         6 |         425 | COMMIT /* xid=114 */                  |
| mysql-bin.000008 | 425 | Anonymous_Gtid |         6 |         490 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| mysql-bin.000008 | 490 | Query          |         6 |         594 | drop database tongdian                |

 mysqlbinlog  mysql-bin.000008
 
[root@db01 logs]#  mysqlbinlog  mysql-bin.000008
#200509 17:13:52 

3. 截取日志
[root@db01 logs]# mysqlbinlog  --start-datetime="2020-05-09 17:11:23"  --stop-datetime="2020-05-09 17:14:01"   mysql-bin.000005 mysql-bin.000006 mysql-bin.000007 mysql-bin.000008 >/tmp/data.sql



遗留


方法3:gtid (后面讲)

	2. binlog属于全局日志,日志中有其他库的操作,怎么排除掉?
	3. binlog中100w个事件,怎么快速找到drop database的位置点? 
	4. 比如删除的库,建库是在2年前操作的。这种情况怎么办? 
   
   


3. 慢日志
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章