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. 慢日誌
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章