[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