專職DBA-MySQL日誌管理2

專職DBA-MySQL日誌管理2

[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &
[root@db01 ~]# ps -ef | grep mysql
[root@db01 ~]# netstat -lnp | grep mysql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p


錯誤日誌(log_error): 文本形式記錄MySQL啓動,關閉,平常運行過程當中全部狀態信息,警告,錯誤。
錯誤日誌配置,默認就是開啓的:/數據目錄下/hostname.err
手工設定:
mysql> select @@log_error;
+----------------------------+
| @@log_error                |
+----------------------------+
| /data/mysql/3306/error.log |
+----------------------------+
1 row in set (0.01 sec)

mysql> show global variables like "log_error";

[root@db01 ~]# grep "log_error" /data/mysql/3306/my.cnf
log_error = /data/mysql/3306/error.log # /usr/local/mysql/data/localhost.localdomain.err
log_timestamps = system


日誌內容查看,主要關注[ERROR]看上下文
[root@db01 ~]# grep "ERROR" /data/mysql/3306/error.log


binlog(binary logs) 二進制日誌
二進制形式,記錄MySQL工做過程當中,全部變動類(除了select和show)的操做日誌。
能夠理解爲記錄的是SQL語句,邏輯性質日誌。
(1).數據恢復  備份恢復必須依賴binlog日誌。
(2).主從複製  主從環境必須依賴binlog日誌。

binlog配置 (5.7必須加server_id)
注意:MySQL默認是沒有開啓二進制日誌的。
基礎參數查看:
mysql> show global variables like "%log_bin%";
mysql> show global variables like "%binlog%";

開關
mysql> select @@log_bin;
+-----------+
| @@log_bin |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

日誌路徑及名字
mysql> select @@log_bin_basename;
+---------------------------------+
| @@log_bin_basename              |
+---------------------------------+
| /data/mysql/3306/logs/mysql-bin |
+---------------------------------+
1 row in set (0.00 sec)

服務ID號
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|      113306 |
+-------------+
1 row in set (0.00 sec)

二進制日誌格式
mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW             |
+-----------------+
1 row in set (0.00 sec)

雙一標準之二:
mysql> select @@sync_binlog;
+---------------+
| @@sync_binlog |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)


my.cnf配置文件
[root@db01 ~]# vim /data/mysql/3306/my.cnf
server_id = 113306
log_bin = /data/mysql/3306/logs/mysql-bin       # off
binlog_format = row
sync_binlog = 1  #雙1標準,每次事務提交當即刷寫binlog


參數說明
server_id=113306
主要是在主從複製過程當中必需要加的,可是在5.7版本中,要用如下參數(log_bin),開啓binlog日誌,即便是單機也是必加的。
log_bin = /data/mysql/3306/logs/mysql-bin
(1).開啓二進制日誌功能。
(2).設置二進制日誌目錄及名稱前綴
binlog_format = row
binlog的記錄格式??
binlog記錄了什麼?
binlog是SQL層的功能。記錄的是變動SQL語句,不記錄查詢語句。

記錄SQL語句種類
DDL原封不動的記錄當前DDL(statement語句方式)。
DCL原封不動的記錄當前DCL(statement語句方式)。
DML只記錄已經提交的事務DML.


DML三種記錄方式
binlog_format(binlog的記錄格式)參數影響
(1).statement(5.6默認) SBR(statement based replication) 語句模式原封不動的記錄當前DML的SQL語句自己。
(2).ROW(5.7 默認值) RBR(ROW based replication) 記錄數據行的變化(用戶看不懂,須要工具分析)
(3).mixed(混合)MBR (mixed based replication) 以上兩種模式的混合。

記錄模式:
STATEMENT(SBR): 語句模式 ,記錄的就是SQL語句自己.
ROW      (RBR): 行模式, 記錄的是數據行的變化.
Mixed    (MBR): 混合模式,自動判斷用什麼模式存儲日誌.
咱們的建議是:row(> = 5.7.7 默認ROW)

面試題:
SBR與RBR模式的對比:
STATEMENT:可讀性較高,日誌量少,可是不夠嚴謹。
ROW:可讀性很低,日誌量大,足夠嚴謹。
update t1 set xxx=xxx where id>1000   ? -->一共500w行,row模式怎麼記錄的日誌
爲何row模式嚴謹?
id  name    intime
insert into t1 values(1,'zhang3',now());
咱們建議使用:row記錄模式。
MySQL一些新特性, 必需要基於ROW模式,GTID,GC MTS



event(事件)是什麼?
事件的簡介:binlog記錄的最小單元。
對於DDL,DCL,一個語句就是一個event。
對於DML語句來說,只記錄已提交的事務。
start  position (文件中的相對位置號)  開始位置
事件內容: DDL  DCL   DML 
stop   position (文件中的相對位置號)  結束位置
例如如下列子,就被分爲了4個event
begin;      120  - 340
DML1        340  - 460
DML2        460  - 550
commit;     550  - 760


event的組成
三部分構成:
(1).事件的開始標識
(2).事件內容
(3).事件的結束標識
Position:
開始標識: at 194
結束標識: end_log_pos 254
194? 254?
某個事件在binlog中的相對位置號。位置號的做用是什麼?爲了方便咱們截取事件。


日誌文件查看
查看日誌的開啓狀況
log_bin參數設置的路徑,能夠找到二進制日誌。
mysql> show variables like "%log_bin%";
+---------------------------------+---------------------------------------+
| Variable_name                   | Value                                 |
+---------------------------------+---------------------------------------+
| log_bin                         | ON                                    |
| log_bin_basename                | /data/mysql/3306/logs/mysql-bin       |
| log_bin_index                   | /data/mysql/3306/logs/mysql-bin.index |
| log_bin_trust_function_creators | OFF                                   |
| log_bin_use_v1_row_events       | OFF                                   |
| sql_log_bin                     | ON                                    |
+---------------------------------+---------------------------------------+
6 rows in set (0.00 sec)


查看一共多少個binlog
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)

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

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       201 |
| mysql-bin.000002 |       154 |
+------------------+-----------+
2 rows in set (0.00 sec)


查看mysql正在使用的binlog日誌文件
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
File:當前MySQL正在使用的文件名
Position:最後一個事件的結束位置號



查看binlog事件信息
mysql> show binlog events in 'mysql-bin.000002';
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000002 |   4 | Format_desc    |    113306 |         123 | Server ver: 5.7.26-log, Binlog ver: 4 |
| mysql-bin.000002 | 123 | Previous_gtids |    113306 |         154 |                                       |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)


Log_name:binlog文件名
Pos:事件開始的位置點position
Event_type:事件類型
Format_desc:格式描述,每個日誌文件的第一個事件,多用戶沒有意義,MySQL識別binlog必要信息
Server_id:mysql服務號標識
End_log_pos:事件的結束位置點position
Info:事件內容

mysql> help show binlog events;
Name: 'SHOW BINLOG EVENTS'
Description:
Syntax:
SHOW BINLOG EVENTS
   [IN 'log_name']
   [FROM pos]
   [LIMIT [offset,] row_count]

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show binlog events in 'mysql-bin.000002';" | grep drop


binlog文件內容詳細查看
[root@db01 ~]# mysqlbinlog /data/mysql/3306/logs/mysql-bin.000002
[root@db01 ~]# mysqlbinlog --base64-output=decode-rows -vvv /data/mysql/3306/logs/mysql-bin.000002
[root@db01 ~]# mysqlbinlog -d school /data/mysql/3306/logs/mysql-bin.000002
[root@db01 ~]# mysqlbinlog --start-datetime='2019-05-06 17:00:00' --stop-datetime='2019-05-06 17:01:00' /data/mysql/3306/logs/mysql-bin.000002


基於Position號進行日誌截取
核心就是找截取的起點和終點
--start-position=219
--stop-position=512
[root@db01 ~]# mysqlbinlog --start-position=219 --stop-position=512 /data/mysql/3306/logs/mysql-bin.000002 >/tmp/bin.sql

案例:使用binlog日誌進行數據恢復
模擬
mysql> create database binlog charset=utf8mb4;
mysql> use binlog;
mysql> create table t1(id int);
mysql> insert into t1 values(1);
mysql> commit;
mysql> insert into t1 values(2);
mysql> commit;
mysql> drop database binlog;

恢復
mysql> show master status;
mysql> show binlog events in 'mysql-bin.000002';
[root@db01 ~]# mysqlbinlog --skip-gtids --start-position=219 --stop-position=1176 /data/mysql/3306/logs/mysql-bin.000002 >/tmp/bin.sql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
mysql> set sql_log_bin=0;
mysql> source /tmp/bin.sql;
mysql> set sql_log_bin=1;

面試案例:
1.備份策略天天全備,有全量的二進制日誌。
2.業務中一共10個庫,其中一個被誤drop了。
3.須要在其餘9個庫正常工做過程當中進行數據恢復。

補充:
200G天天(23:00)全備,天天備份binlog,週三上午10誤刪的表t1.
恢復思路:
1.停業務,掛維護頁.
2.找臨時庫,恢復全備.
3.截取全備以後,一直到刪表以前的全部binlog
4.導出表,導入到生產.


binlog日誌的GTID新特性。
GTID 介紹
5.6版本新加的特性,5.7中作了增強。
5.6中不開啓,沒有這個功能。
5.7中的GTID即便不開也會有自動生成。
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'


GTID(Global Transaction ID) (MySQL5.6.9版本)
是對於一個已提交事務的編號,而且是一個全局惟一的編號。每次累加數字。
在傳統模式的基礎上,加入對於每一個事務惟一的編號. 
DDL,DCL ,一條語句就是一個事務.會分配一個惟一的GTID號碼 
DML, begin;xxx;commit做爲一個完整的事務,分配一個惟一的GTID號
這些號碼,惟一的,連續的,具有冪等性的.
它的官方定義以下:
GTID = source_id:transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29

mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 6f02ba92-d1b7-11e9-bf6f-000c29ca1344 |
+--------------------------------------+
1 row in set (0.00 sec)

mysql> show global variables like '%gtid%';
mysql> show variables like '%gtid%';

重要參數介紹:
[root@db01 ~]# vim /data/mysql/3306/my.cnf
gtid_mode = on
enforce_gtid_consistency = on


create database gtid charset utf8mb4;
use gtid
create table t1(id int);
create table t2(id int);
create table t3(id int);
begin;
insert into t1 values(1);
commit;
begin;
insert into t2 values(1);
commit;

mysql> show master status;



基於GTID進行查看binlog
具有GTID後,截取查看某些事務日誌:
--include-gtids 包含
--exclude-gtids 排除
[root@db01 ~]# mysqlbinlog --include-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:1-6' --exclude-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:5' /data/mysql/3306/logs/mysql-bin.000002


GTID的冪等性:開啓GTID後,MySQL恢復Binlog時,重複GTID的事務不會再執行了。
就想恢復?怎麼辦?
--skip-gtids
[root@db01 ~]# mysqlbinlog --skip-gtids --include-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:1-6' --exclude-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:5' /data/mysql/3306/logs/mysql-bin.000002 > /tmp/1.sql
set sql_log_bin=0;
source /tmp/binlog.sql
set sql_log_bin=1;
結論:在開啓GTID模式的binlog截取時,都要加--skip-gtids.

使用二進制日誌恢復數據案例
故障環境介紹
建立了一個庫db,導入了表t1,t1表中錄入了不少數據。
一個開發人員,drop database db;
沒有備份,日誌都在,怎麼恢復?
思路:找到建庫語句到刪庫以前全部的日誌,進行恢復(開啓了GTID模式)
故障案例模擬:
drop database if exists db;
create database db charset utf8mb4;     
use db;
create table t1(id int);
insert into t1 values(1),(2),(3);
insert into t1 values(4),(5),(6);
commit
update t1 set id=30 where id=3;
commit;
delete from t1 where id=4;
commit;
insert into t1 values(7),(8),(9);
commit;
drop database db;
=============================================
運行以上語句,模擬故障場景
需求:將數據庫恢復到如下狀態(提示第10步和第14步是誤操做,其餘都是正常操做)


恢復過程(無GTID時的恢復)
查看當前使用的 binlog文件
mysql> show master status;
查看事件
mysql> show binlog events in 'mysql-bin.000002';
截取第一段
[root@db01 ~]# mysqlbinlog --start-position=219 --stop-position=512 /data/mysql/3306/logs/mysql-bin.000002 >/tmp/bin1.sql
截取第二段
[root@db01 ~]# mysqlbinlog --start-position=768 --stop-position=1025 /data/mysql/3306/logs/mysql-bin.000002 >/tmp/bin2.sql

恢復
mysql> set sql_log_bin=0;
mysql> source /tmp/bin1.sql
mysql> source /tmp/bin2.sql
mysql> set sql_log_bin=1;
mysql> select * from t1;


有GTID的截取
mysqlbinlog --skip-gtids --include-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:1-18' --exclude-gtids='dff98809-55c3-11e9-a58b-000c2928f5dd:9' /data/mysql/3306/logs/mysql-bin.000002 > /tmp/bin3.sql


恢復
mysql> set sql_log_bin=0;
mysql> source /tmp/bin3.sql
mysql> set sql_log_bin=1;
mysql> select * from t1;



二進制日誌其餘操做
自動清理日誌,binlog刪除,何時能夠刪除binlog?
保證有一份可用的全備.看全備週期.
自動清理:
mysql> show global variables like "%days%";
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 7     |
+------------------+-------+
1 row in set (0.00 sec)

自動清理時間,是要按照全備週期+1
mysql> set global expire_logs_days=8;

永久生效寫入配置文件/data/mysql/3306/my.cnf
expire_logs_days = 15
企業建議至少保留兩個全備週期+1天的binlog
7+7+1=15

手工清理
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;
PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';
PURGE BINARY LOGS TO 'mysql-bin.000010';
注意:不要手工rm -rf binlog文件
1.my.cnf  binlog關閉掉,啓動數據庫。
2.把數據庫關閉,開啓binlog,啓動數據庫。
刪除全部binlog,並從000001開始從新記錄日誌。

mysql> reset master; 主從關係中,主庫執行此操做,主從環境必崩。


binlog文件是怎麼滾動切割
1.flush logs;
2.重啓mysql也會自動滾動一個新的。
3.日誌文件達到1G大小(max_binlog_size)
mysql> show global variables like "%binlog_size%";
+-----------------+------------+
| Variable_name   | Value      |
+-----------------+------------+
| max_binlog_size | 1073741824 |
+-----------------+------------+
1 row in set (0.00 sec)
4.數據備份時加入參數也能夠自動滾動



slow_log 慢日誌
以文本格式追加記錄慢SQL語句的日誌,定位低效SQL語句的工具日誌。
輔助咱們排查SQL性能問題的工具日誌.
mysql> show variables like '%slow%';
mysql> show variables like '%index%';

slow_query_log = on                                    # off
slow_query_log_file = /data/mysql/3306/slow.log             # hostname.log

開啓慢日誌(默認沒開啓) /data/mysql/3306/my.cnf
開關
slow_query_log = on                                    # off

文件位置及名字
slow_query_log_file = /data/mysql/3306/slow.log             # hostname.log

設定慢查詢時間
long_query_time=0.1

沒走索引的語句也記錄
log_queries_not_using_indexes=on



mysqldumpslow 分析慢日誌
[root@db01 ~]# mysqldumpslow -s c -t 3 /data/mysql/3306/slow.log

第三方分析工具(本身擴展)
https://www.percona.com/downloads/percona-toolkit/LATEST/
[root@db01 ~]# yum install perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL perl-Digest-MD5

percona-toolkit工具包中的命令:
[root@db01 ~]# pt-query-diagest /data/mysql/3306/slow.log

還有一個是Anemometer基於pt-query-digest將MySQL慢查詢可視化

推薦分析工具:
pt-digest + Anemometer
ELK
相關文章
相關標籤/搜索