1. 程式人生 > 資料庫 >基於MySQL的儲存引擎與日誌說明(全面講解)

基於MySQL的儲存引擎與日誌說明(全面講解)

1.1 儲存引擎的介紹

1.1.1 檔案系統儲存

檔案系統:作業系統組織和存取資料的一種機制。檔案系統是一種軟體。

型別:ext2 3 4 ,xfs 資料。 不管使用什麼檔案系統,資料內容不會變化,不同的是,儲存空間、大小、速度。

1.1.2 mysql資料庫儲存

MySQL引擎: 可以理解為,MySQL的“檔案系統”,只不過功能更加強大。

MySQL引擎功能: 除了可以提供基本的存取功能,還有更多功能事務功能、鎖定、備份和恢復、優化以及特殊功能。

1.1.3 MySQL儲存引擎種類

MySQL 提供以下儲存引擎:

InnoDB、MyISAM (最常用的兩種)
MEMORY、ARCHIVE、FEDERATED、EXAMPLE
BLACKHOLE、MERGE、NDBCLUSTER、CSV

除此之外還可以使用第三方儲存引擎。

1.1.4 innodb與myisam對比

InnoDb引擎

支援ACID的事務,支援事務的四種隔離級別;

支援行級鎖及外來鍵約束:因此可以支援寫併發;

不儲存總行數;

一個InnoDb引擎儲存在一個檔案空間(共享表空間,表大小不受作業系統控制,一個表可能分佈在多個檔案裡),也有可能為多個(設定為獨立表空,表大小受作業系統檔案大小限制,一般為2G),受作業系統檔案大小的限制;

主鍵索引採用聚集索引(索引的資料域儲存資料檔案本身),輔索引的資料域儲存主鍵的值;因此從輔索引查詢資料,需要先通過輔索引找到主鍵值,再訪問輔索引;最好使用自增主鍵,防止插入資料時,為維持B+樹結構,檔案的大調整。

Innodb的主索引結構如下:

MyISAM引擎

不支援事務,但是每次查詢都是原子的;

支援表級鎖,即每次操作是對整個表加鎖;

儲存表的總行數;

一個MYISAM表有三個檔案:索引檔案、表結構檔案、資料檔案;

採用菲聚集索引,索引檔案的資料域儲存指向資料檔案的指標。輔索引與主索引基本一致,但是輔索引不用保證唯一性。

MYISAM的主索引結構如下:

兩種索引資料查詢過程如下:

1.2 innodb儲存引擎

在MySQL5.5版本之後,預設的儲存引擎,提供高可靠性和高效能。

1.2.1 Innodb引擎的優點

a) 事務安全(遵從ACID)
b) MVCC(Multi-Versioning Concurrency Control,多版本併發控制)
c) InnoDB行級鎖
d) 支援外來鍵引用完整性約束
e) 出現故障後快速自動恢復(crash safe recovery)
f) 用於在記憶體中快取資料和索引的緩衝區池(buffer pool(data buffer page log buffer page) 、undo buffer page)
g) 大型資料捲上的最大效能
h) 將對錶的查詢與不同儲存引擎混合
i) Oracle樣式一致非鎖定讀取(共享鎖)
j) 表資料進行整理來優化基於主鍵的查詢(聚集索引)

1.2.2 Innodb功能總覽

功能 支援 功能 支援
儲存限制 64 TB 索引快取記憶體
MVCC 資料快取記憶體
B 樹索引 自適應雜湊索引
群集索引 複製
壓縮資料 更新資料字典
加密資料[b] 地理空間資料型別
查詢快取記憶體 地理空間索引
事務 全文搜尋索引
鎖定粒度 群集資料庫
外來鍵 備份和恢復
檔案格式管理 快速索引建立
多個緩衝區池 PERFORMANCE_SCHEMA
更改緩衝 自動故障恢復

1.2.3 查詢儲存引擎的方法

1、使用 SELECT 確認會話儲存引擎:
SELECT @@default_storage_engine;
或
show variables like '%engine%';

2、使用 SHOW 確認每個表的儲存引擎:

SHOW CREATE TABLE City\G
SHOW TABLE STATUS LIKE 'CountryLanguage'\G

3、使用 INFORMATION_SCHEMA 確認每個表的儲存引擎:

SELECT TABLE_NAME,ENGINE FROM 
INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'City'
AND TABLE_SCHEMA = 'world_innodb'\G 

4、從5.1版本,遷移到5.5版本以上版本

假如5.1版本資料庫所有生產表都是myisam的。

使用mysqldump備份後,一點要替換備份的檔案中的engine(引擎)欄位,從myisam替換為innodb(可以使用sed命令),否則遷移無任何意義。

資料庫升級時,要注意其他配套設施的相容性,注意程式碼能否相容新特性。

1.2.4 設定儲存引擎

1、在啟動配置檔案中設定伺服器儲存引擎:

[mysqld]
default-storage-engine=<Storage Engine>

2、使用 SET 命令為當前客戶機會話設定:

SET @@storage_engine=<Storage Engine>;

3、在 CREATE TABLE 語句指定:

CREATE TABLE t (i INT) ENGINE = <Storage Engine>;

1.3 InnoDB儲存引擎的儲存結構

1.3.1 InnoDB 系統表空間特性

預設情況下,InnoDB 元資料、撤消日誌和緩衝區儲存在系統“表空間”中。

這是單個邏輯儲存區域,可以包含一個或多個檔案。

每個檔案可以是常規檔案或原始分割槽。

最後的檔案可以自動擴充套件。

1.3.2 表空間的定義

表空間:MySQL資料庫儲存的方式

表空間中包含資料檔案

MySQl表空間和資料檔案是1:1的關係

共享表空間除外,是可以1:N關係

1.3.3 表空間型別

1、共享表空間:ibdata1~ibdataN,一般是2-3個

2、獨立表空間:存放在指定庫目錄下,例如data/world/目錄下的city.ibd

  表空間位置(datadir):

  data/目錄下

1.3.4 系統表空間的儲存內容

共享表空間(物理儲存結構)

ibdata1~N 通常被叫做系統表空間,是資料初始化生成的

系統元資料,基表資料,除了表內容資料之外的資料。

tmp 表空間(一般很少關注)

undo日誌 :資料--回滾資料(回滾日誌使用)

redo日誌 :ib_logfile0~N 存放系統的innodb表的一些重做日誌。

說明:undo日誌預設實在ibdata中的,在5.6以後是可以單獨定義的。

tmp 表空間在5.7版本之後被移出了ibdata1,變為ibtmp1

在5.5版本之前,所有的應用資料也都預設存放到了ibdata中。

獨立表空間(一個儲存引擎的功能)

在5.6之後,預設的情況下會單表單獨儲存到獨立表空間檔案

除了系統表空間之外,InnoDB 還在資料庫目錄中建立另外的表空間,用於每個 InnoDB 表的 .ibd 檔案。

InnoDB 建立的每個新表在資料庫目錄中設定一個 .ibd 檔案來搭配表的.frm 檔案。

可以使用 innodb_file_per_table 選項控制此設定,更改該設定僅會更改已建立的新表的預設值。。

1.3.5 設定共享表空間

檢視當前的共享表空間設定

mysql> show variables like 'innodb_data_file_path';
+-----------------------+------------------------+
| Variable_name | Value  |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:12M:autoextend |
+-----------------------+------------------------+
row in set (0.00 sec)

設定共享表空間:

一般是在初始搭建環境的時候就配置號,預設值一般為1G;且最後一個為自動擴充套件。

[root@db02 world]# vim /etc/my.cnf
[mysqld]
innodb_data_file_path=ibdata1:76M;ibdata2:100M:autoextend

重啟服務檢視當前的共享表空間設定

mysql> show variables like 'innodb_data_file_path';
+-----------------------+-------------------------------------+
| Variable_name | Value  |
+-----------------------+-------------------------------------+
| innodb_data_file_path | ibdata1:76M;ibdata2:100M:autoextend |
+-----------------------+-------------------------------------+
row in set (0.00 sec)

1.3.6 設定獨立表空間

獨立表空間在5.6版本是預設開啟的。

獨立表空間注意事項:不開起獨立表空間,共享表空間會佔用很大

mysql> show variables like '%per_table%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+
row in set (0.00 sec)

在引數檔案/etc/my.cnf 可以控制獨立表空間

關閉獨立表空間 (0是關閉,1是開啟)

[root@db02 clsn]# vim /etc/my.cnf
[mysqld]
innodb_file_per_table=0

檢視獨立表空間配置

mysql> show variables like '%per_table%' ;
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
row in set (0.00 sec)

小結:

innodb_file_per_table=0 關閉獨立表空間
innodb_file_per_table=1 開啟獨立表空間,單表單儲存

1.4 MySQL中的事務

一組資料操作執行步驟,這些步驟被視為一個工作單元

用於對多個語句進行分組,可以在多個客戶機併發訪問同一個表中的資料時使用。

所有步驟都成功或都失敗

如果所有步驟正常,則執行,如果步驟出現錯誤或不完整,則取消。

簡單來說事務就是:保證工作單元中的語句同時成功或同時失敗。

事務處理流程示意圖

1.4.1 事務是什麼

與其給事務定義,不如說一說事務的特性。眾所周知,事務需要滿足ACID四個特性。

A(atomicity) 原子性。

一個事務的執行被視為一個不可分割的最小單元。事務裡面的操作,要麼全部成功執行,要麼全部失敗回滾,不可以只執行其中的一部分。

所有語句作為一個單元全部成功執行或全部取消。
updata t1 set money=10000-17 where id=wxid1
updata t1 set money=10000+17 where id=wxid2

C(consistency) 一致性。

一個事務的執行不應該破壞資料庫的完整性約束。如果上述例子中第2個操作執行後系統崩潰,保證A和B的金錢總計是不會變的。

如果資料庫在事務開始時處於一致狀態,則在執行該事務期間將保留一致狀態。
 updata t1 set money=10000-17 where id=wxid1
 updata t1 set money=10000+17 where id=wxid2
 在以上操作過程中,去查自己賬戶還是10000

I(isolation) 隔離性。

通常來說,事務之間的行為不應該互相影響。然而實際情況中,事務相互影響的程度受到隔離級別的影響。文章後面會詳述。

事務之間不相互影響。在做操作的時候,其他人對這兩個賬戶做任何操作,在不同的隔離條件下,可能一致性保證又不一樣

隔離級別

隔離級別會影響到一致性。
 read-uncommit X
 read-commit 可能會用的一種級別
 repeatable-read 預設的級別,和oracle一樣的
 SERIALIZABLE 嚴格的預設,一般不會用

此規則除了受隔離級別控制,還受鎖控制,可以聯想一下NFS的實現

D(durability) 永續性。

事務提交之後,需要將提交的事務持久化到磁碟。即使系統崩潰,提交的資料也不應該丟失。

保證資料落地,才算事務真正安全

1.4.2 事務的控制語句

常用的事務控制語句:

START TRANSACTION(或 BEGIN):顯式開始一個新事務
 COMMIT:永久記錄當前事務所做的更改(事務成功結束)
 ROLLBACK:取消當前事務所做的更改(事務失敗結束)

需要知道的事務控制語句:

 SAVEPOINT:分配事務過程中的一個位置,以供將來引用
 ROLLBACK TO SAVEPOINT:取消在 savepoint 之後執行的更改
 RELEASE SAVEPOINT:刪除 savepoint 識別符號
 SET AUTOCOMMIT:為當前連線禁用或啟用預設 autocommit模式

1.4.3 autocommit引數

在MySQL5.5開始,開啟事務時不再需要begin或者start transaction語句。並且,預設是開啟了Autocommit模式,作為一個事務隱式提交每個語句。

在有些業務繁忙企業場景下,這種配置可能會對效能產生很大影響,但對於安全性上有很大提高。將來,我們需要去權衡我們的業務需求去調整是否自動提交。

注意:在生產中,根據實際需求選擇是否可開啟,一般銀行類業務會選擇關閉。

檢視當前autocommit狀態:

mysql> show variables like '%autoc%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
row in set (0.00 sec)

修改配置檔案,並重啟

[root@db02 world]# vim /etc/my.cnf
[mysqld]
autocommit=0

再次檢視autocommit狀態

mysql> show variables like '%autoc%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
row in set (0.00 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
row in set (0.00 sec)

說明: autocommit設定為開啟的對比

優點:資料安全性好,每次修改都會落地

缺點:不能進行銀行類的交易事務、產生大量小的IO

1.4.4 導致提交的非事務語句:

DDL語句: (ALTER、CREATE 和 DROP)
DCL語句: (GRANT、REVOKE 和 SET PASSWORD)
鎖定語句:(LOCK TABLES 和 UNLOCK TABLES)

導致隱式提交的語句示例:

TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE

用於隱式提交的 SQL 語句:

START TRANSACTION
SET AUTOCOMMIT = 1

1.5 redo與undo

1.5.1 事務日誌undo

undo原理:

Undo Log的原理很簡單,為了滿足事務的原子性,在操作任何資料之前,首先將資料備份到一個地方(這個儲存資料備份的地方稱為Undo Log)。然後進行資料的修改。

如果出現了錯誤或者使用者執行了ROLLBACK語句,系統可以利用Undo Log中的備份將資料恢復到事務開始之前的狀態。

除了可以保證事務的原子性,Undo Log也可以用來輔助完成事務的持久化。

undo是什麼?

undo,顧名思義“回滾日誌”,是事務日誌的一種。

作用是什麼?

在事務ACID過程中,實現的是“A“原子性的作用。

用Undo Log實現原子性和持久化的事務的簡化過程

假設有A、B兩個資料,值分別為1,2。
 A.事務開始.
 B.記錄A=1到undo log.
 C.修改A=3.
 D.記錄B=2到undo log.
 E.修改B=4.
 F.將undo log寫到磁碟。
 G.將資料寫到磁碟。
 H.事務提交

這裡有一個隱含的前提條件:‘資料都是先讀到記憶體中,然後修改記憶體中的資料,最後將資料寫回磁碟之所以能同時保證原子性和持久化,是因為以下特點:

A. 更新資料前記錄Undo log。
B. 為了保證永續性,必須將資料在事務提交前寫到磁碟。只要事務成功提交,資料必然已經持久化。
C. Undo log必須先於資料持久化到磁碟。如果在G,H之間系統崩潰,undo log是完整的,可以用來回滾事務。
D. 如果在A-F之間系統崩潰,因為資料沒有持久化到磁碟。所以磁碟上的資料還是保持在事務開始前的狀態。

缺陷:

每個事務提交前將資料和Undo Log寫入磁碟,這樣會導致大量的磁碟IO,因此效能很低。如果能夠將資料快取一段時間,就能減少IO提高效能。但是這樣就會喪失事務的永續性。

因此引入了另外一種機制來實現持久化,即Redo Log.

1.5.2 事務日誌redo

redo原理:

和Undo Log相反,Redo Log記錄的是新資料的備份。在事務提交前,只要將Redo Log持久化即可,不需要將資料持久化。當系統崩潰時,雖然資料沒有持久化,但是Redo Log已經持久化。

系統可以根據Redo Log的內容,將所有資料恢復到最新的狀態。

Redo是什麼?

redo,顧名思義“重做日誌”,是事務日誌的一種。

作用是什麼?

在事務ACID過程中,實現的是“D”持久化的作用。

Undo + Redo事務的簡化過程

假設有A、B兩個資料,值分別為1,2.
 A.事務開始.
 B.記錄A=1到undo log.
 C.修改A=3.
 D.記錄A=3到redo log.
 E.記錄B=2到undo log.
 F.修改B=4.
 G.記錄B=4到redo log.
 H.將redo log寫入磁碟。
 I.事務提交

Undo + Redo事務的特點

 A. 為了保證永續性,必須在事務提交前將Redo Log持久化。
 B. 資料不需要在事務提交前寫入磁碟,而是快取在記憶體中。
 C. Redo Log 保證事務的永續性。
 D. Undo Log 保證事務的原子性。
 E. 有一個隱含的特點,資料必須要晚於redo log寫入持久儲存。

redo是否持久化到磁碟引數

innodb_flush_log_at_trx_commit=1/0/2

1.5.3 事務中的鎖

什麼是“鎖”?

“鎖”顧名思義就是鎖定的意思。

“鎖”的作用是什麼?

在事務ACID過程中,“鎖”和“隔離級別”一起來實現“I”隔離性的作用。

鎖的粒度:

1、MyIasm:低併發鎖——表級鎖

2、Innodb:高併發鎖——行級鎖

四種隔離級別:

READ UNCOMMITTED 許事務檢視其他事務所進行的未提交更改
READ COMMITTED 允許事務檢視其他事務所進行的已提交更改
REPEATABLE READ****** 確保每個事務的 SELECT 輸出一致; InnoDB 的預設級別
SERIALIZABLE 將一個事務的結果與其他事務完全隔離

開銷、加鎖速度、死鎖、粒度、併發效能

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

從上述特點可見,很難籠統地說哪種鎖更好,只能就具體應用的特點來說哪種鎖更合適!

僅從鎖的角度來說:表級鎖更適合於以查詢為主,只有少量按索引條件更新資料的應用,如Web應用;而行級鎖則更適合於有大量按索引條件併發更新少量不同資料,同時又有併發查詢的應用,如一些線上事務處理(OLTP)系統。

1.6 MySQL 日誌管理

1.6.1 MySQL日誌型別簡介

日誌的型別的說明:

日誌檔案 選項 檔名 程式 N/A
表名稱
錯誤 --log-error host_name.err N/A
常規 --general_log host_name.log mysqldumpslow mysqlbinlog
general_log
慢速查詢 --slow_query_log --long_query_time host_name-slow.log N/A 程式
slow_log
二進位制 --log-bin --expire-logs-days host_name-bin.000001 N/A
審計 --audit_log --audit_log_file audit.log N/A

1.6.2 配置方法

狀態錯誤日誌:

[mysqld]
log-error=/data/mysql/mysql.log

檢視配置方式:

mysql> show variables like '%log%error%';

作用:

記錄mysql資料庫的一般狀態資訊及報錯資訊,是我們對於數

據庫常規報錯處理的常用日誌。

mysql> show variables like '%log%err%';
+---------------------+----------------------------------+
| Variable_name | Value  |
+---------------------+----------------------------------+
| binlog_error_action | IGNORE_ERROR  |
| log_error | /application/mysql/data/db02.err |
+---------------------+----------------------------------+
rows in set (0.00 sec)

1.6.3 一般查詢日誌

配置方法:

[mysqld]
general_log=on
general_log_file=/data/mysql/server2.log

檢視配置方式:

show variables like '%gen%';

作用:

記錄mysql所有執行成功的SQL語句資訊,可以做審計用,但是我們很少開啟

mysql> show variables like '%gen%';
+------------------+----------------------------------+
| Variable_name | Value  |
+------------------+----------------------------------+
| general_log | OFF  |
| general_log_file | /application/mysql/data/db02.log |
+------------------+----------------------------------+
rows in set (0.00 sec)

1.7 二進位制日誌

二進位制日誌不依賴與儲存引擎的。

依賴於sql層,記錄和sql語句相關的資訊

binlog日誌作用:

1、提供備份功能

2、進行主從複製

3、基於時間點的任意恢復

記錄在sql層已經執行完成的語句,如果是事務,則記錄已完成的事務。

功能作用: 時間點備份 和 時間點恢復、 主從

二進位制日誌的“總閘”

作用:

1、是否開啟
2、二進位制日誌路徑/data/mysql/
3、二進位制日誌檔名字首mysql-bin 
4、檔名以"字首".000001~N
log-bin=/data/mysql/mysql-bin 

二進位制日誌的“分開關”:

只有總閘開啟才有意義,預設是開啟狀態。
我們在有些時候會臨時關閉掉。
隻影響當前會話。
sql_log_bin=1/0

1.7.1 二進位制日誌的格式

statement,語句模式:

記錄資訊簡潔,記錄的是SQL語句本身。但是在語句中出現函式操作的話,有可能記錄的資料不準確。

5.6中預設模式,但生產環境中慎用,建議改成row。

row,行模式

表中行資料的變化過程。
記錄資料詳細,對IO效能要求比較高
記錄資料在任何情況下都是準確的。
生產中一般是這種模式。
5.7以後預設的模式。

mixed,混合模式

經過判斷,選擇row+statement混合的一種記錄模式。(一般不用)

1.7.2 開啟二進位制日誌

mysql> show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name  | Value |
+---------------------------------+-------+
| log_bin  | OFF |
| log_bin_basename | |
| log_bin_index  | |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin  | ON |
+---------------------------------+-------+
rows in set (0.00 sec)

修改配置檔案開啟二進位制日誌

[root@db02 tmp]# vim /etc/my.cnf
[mysqld]
log-bin=/application/mysql/data/mysql-bin

命令列修改的方法

mysql> SET GLOBAL binlog_format = 'STATEMENT'
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';

檢視檔案二進位制日誌的型別

[root@db02 data]# file mysql-bin.*
mysql-bin.000001: MySQL replication log
mysql-bin.index: ASCII text

檢視MySQL的配置:

mysql> show variables like '%log_bin%';
+---------------------------------+-----------------------------------------+
| Variable_name  | Value   |
+---------------------------------+-----------------------------------------+
| log_bin  | ON   |
| log_bin_basename | /application/mysql/data/mysql-bin |
| log_bin_index  | /application/mysql/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF   |
| log_bin_use_v1_row_events | OFF   |
| sql_log_bin  | ON   |
+---------------------------------+-----------------------------------------+
rows in set (0.00 sec)

1.7.3 定義記錄方式

檢視現在的格式

mysql> show variables like '%format%';
+--------------------------+-------------------+
| Variable_name | Value |
+--------------------------+-------------------+
| binlog_format | STATEMENT |
| date_format | %Y-%m-%d |
| datetime_format | %Y-%m-%d %H:%i:%s |
| default_week_format | 0  |
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
| time_format | %H:%i:%s |
+--------------------------+-------------------+
rows in set (0.00 sec)

修改格式

[root@db02 data]# vim /etc/my.cnf
[mysqld]
binlog_format=row

改完之後檢視

mysql> show variables like '%format%';
+--------------------------+-------------------+
| Variable_name | Value |
+--------------------------+-------------------+
| binlog_format | ROW |
| date_format | %Y-%m-%d |
| datetime_format | %Y-%m-%d %H:%i:%s |
| default_week_format | 0  |
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
| time_format | %H:%i:%s |
+--------------------------+-------------------+
rows in set (0.00 sec)

1.8 二進位制日誌的操作

1.8.1 檢視

作業系統層面檢視

[root@db02 data]# ll mysql-bin.*
-rw-rw---- 1 mysql mysql 143 Dec 20 20:17 mysql-bin.000001
-rw-rw---- 1 mysql mysql 120 Dec 20 20:17 mysql-bin.000002
-rw-rw---- 1 mysql mysql 82 Dec 20 20:17 mysql-bin.index

重新整理日誌

mysql> flush logs;

重新整理完成後的日誌目錄

[root@db02 data]# ll mysql-bin.*
-rw-rw---- 1 mysql mysql 143 Dec 20 20:17 mysql-bin.000001
-rw-rw---- 1 mysql mysql 167 Dec 20 20:24 mysql-bin.000002
-rw-rw---- 1 mysql mysql 120 Dec 20 20:24 mysql-bin.000003
-rw-rw---- 1 mysql mysql 123 Dec 20 20:24 mysql-bin.index
[root@db02 data]#

檢視當前使用的二進位制日誌檔案

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

檢視所有的二進位制日誌檔案

mysql> show binary logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 143 |
| mysql-bin.000002 | 167 |
| mysql-bin.000003 | 120 |
+------------------+-----------+
rows in set (0.00 sec)

1.8.2 檢視二進位制日誌內容

名詞說明:

1、events 事件

二進位制日誌如何定義:命令的最小發生單元

2、position

每個事件在整個二進位制檔案中想對應的位置號就是position號

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 120 | |  |  |
+------------------+----------+--------------+------------------+-------------------+
row in set (0.00 sec)
[root@db02 data]# mysqlbinlog mysql-bin.000003 >/tmp/aa.ttt

匯出所有的資訊

[root@db02 data]# mysqlbinlog mysql-bin.000003 >/tmp/aa.ttt

binlog的檢視方式:

1、檢視binlog原始資訊

mysqbin mysql-bin.000002 

2、在row模式下,翻譯成語句

mysqlbinlog --base64-output='decode-rows' -v mysql-bin.000002

3、檢視binlog事件

show binary logs; 所有在使用的binlog資訊
show binlog events in '日誌檔案'

4、如何擷取binlog內容,按需求恢復(常規思路)

(1)、show binary logs; show master status;

(2)、show binlog events in '' 從後往前看,找到誤操作的事務,判斷事務開始position和結束position

(3)、把誤操作的剔除掉,留下正常操作到2個sql檔案中

(4)、先測試庫恢復,把誤操作的資料匯出,然後生產恢復。

使用上述方法遇到的問題:

恢復事件較長

對生產資料有一定的影響,有可能會出現冗餘資料

較好的解決方案。

1、flashback閃回功能

2、通過備份,延時從庫

1.8.3 mysqlbinlog擷取二進位制日誌的方法

mysqlbinlog常見的選項有以下幾個:

引數 引數說明
--start-datetime 從二進位制日誌中讀取指定等於時間戳或者晚於本地計算機的時間
--stop-datetime 從二進位制日誌中讀取指定小於時間戳或者等於本地計算機的時間取值和上述一樣
--start-position 從二進位制日誌中讀取指定position 事件位置作為開始。
--stop-position 從二進位制日誌中讀取指定position 事件位置作為事件截至

二進位制日誌檔案示例: mysqlbinlog --start-position=120 --stop-position=結束號

1.8.4 刪除二進位制日誌

預設情況下,不會刪除舊的日誌檔案。 根據存在時間刪除日誌:
SET GLOBAL expire_logs_days = 7;
或
PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day;

根據檔名刪除日誌:

PURGE BINARY LOGS TO 'mysql-bin.000010';

重置二進位制日誌計數,從1開始計數,刪除原有的二進位制日誌。

reset master 

1.9 mysql的慢查詢日誌(slow log)

1.9.1 這是什麼呢?

slow-log 記錄所有條件內的慢的sql語句

優化的一種工具日誌。能夠幫我們定位問題。

1.9.2 慢查詢日誌

是將mysql伺服器中影響資料庫效能的相關SQL語句記錄到日誌檔案

通過對這些特殊的SQL語句分析,改進以達到提高資料庫效能的目的。慢日誌設定

long_query_time : 設定慢查詢的閥值,超出次設定值的SQL即被記錄到慢查詢日誌,預設值為10s
slow_query_log : 指定是否開啟慢查詢日誌
slow_query_log_file : 指定慢日誌檔案存放位置,可以為空,系統會給一個預設的檔案host_name-slow.log
min_examined_row_limit:查詢檢查返回少於該引數指定行的SQL不被記錄到慢查詢日誌
log_queries_not_using_indexes: 不使用索引的慢查詢日誌是否記錄到索引

慢查詢日誌配置

[root@db02 htdocs]# vim /etc/my.cnf
slow_query_log=ON
slow_query_log_file=/tmp/slow.log
long_query_time=0.5 # 控制慢日誌記錄的閾值
log_queries_not_using_indexes

配置完成後重啟服務...

檢視慢查詢日誌是否開啟,及其位置。

mysql> show variables like '%slow%'
 -> ;
+---------------------------+---------------+
| Variable_name | Value |
+---------------------------+---------------+
| log_slow_admin_statements | OFF |
| log_slow_slave_statements | OFF |
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | /tmp/slow.log |
+---------------------------+---------------+
rows in set (0.00 sec)

1.9.3 mysqldumpslow命令

/path/mysqldumpslow -s c -t 10 /database/mysql/slow-log

這會輸出記錄次數最多的10條SQL語句,其中:

引數 說明
-s 是表示按照何種方式排序,c、t、l、r分別是按照記錄次數、時間、查詢 時間、返回的記錄數來排序,ac、at、al、ar,表示相應的倒敘;
-t 是top n的意思,即為返回前面多少條的資料;
-g 後邊可以寫一個正則匹配模式,大小寫不敏感的;
例子: /path/mysqldumpslow -s r -t 10 /database/mysql/slow-log 得到返回記錄集最多的10個查詢。 /path/mysqldumpslow -s t -t 10 -g “left join”/database/mysql/slow-log 得到按照時間排序的前10條裡面含有左連線的查詢語句。

1.9.4 怎麼保證binlog和redolog已提交事務的一致性

在沒有開啟binlog的時候,在執行commit,認為redo日誌持久化到磁碟檔案中,commit命令就成功。 寫binlog引數:
mysql> show variables like '%sync_binlog%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog | 0 | #控制binlog commit 階段
+---------------+-------+
row in set (0.00 sec)

sync_binlog 確保是否每個提交的事務都寫到binlog中。

1.9.5 mysql中的雙一標準:

innodb_flush_log_at_trx_commit和sync_binlog 兩個引數是控制MySQL 磁碟寫入策略以及資料安全性的關鍵引數。

引數意義說明:

innodb_flush_log_at_trx_commit=1

如果innodb_flush_log_at_trx_commit設定為0,log buffer將每秒一次地寫入log file中,並且log file的flush(刷到磁碟)操作同時進行.該模式下,在事務提交的時候,不會主動觸發寫入磁碟的操作。

如果innodb_flush_log_at_trx_commit設定為1,每次事務提交時MySQL都會把log buffer的資料寫入log file,並且flush(刷到磁碟)中去.

如果innodb_flush_log_at_trx_commit設定為2,每次事務提交時MySQL都會把log buffer的資料寫入log file.但是flush(刷到磁碟)操作並不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁碟)操作。

注意:

由於程序排程策略問題,這個“每秒執行一次 flush(刷到磁碟)操作”並不是保證100%的“每秒”。

引數意義說明:

sync_binlog=1

sync_binlog 的預設值是0,像作業系統刷其他檔案的機制一樣,MySQL不會同步到磁碟中去而是依賴作業系統來重新整理binary log。

當sync_binlog =N (N>0) ,MySQL 在每寫 N次 二進位制日誌binary log時,會使用fdatasync()函式將它的寫二進位制日誌binary log同步到磁碟中去。

注:

如果啟用了autocommit,那麼每一個語句statement就會有一次寫操作;否則每個事務對應一個寫操作。

安全方面說明

當innodb_flush_log_at_trx_commit和sync_binlog 都為 1 時是最安全的,在mysqld 服務崩潰或者伺服器主機crash的情況下,binary log 只有可能丟失最多一個語句或者一個事務。但是魚與熊掌不可兼得,雙11 會導致頻繁的io操作,因此該模式也是最慢的一種方式。

當innodb_flush_log_at_trx_commit設定為0,mysqld程序的崩潰會導致上一秒鐘所有事務資料的丟失。

當innodb_flush_log_at_trx_commit設定為2,只有在作業系統崩潰或者系統掉電的情況下,上一秒鐘所有事務資料才可能丟失。

雙1適合資料安全性要求非常高,而且磁碟IO寫能力足夠支援業務,比如訂單,交易,充值,支付消費系統。雙1模式下,當磁碟IO無法滿足業務需求時 比如11.11 活動的壓力。推薦的做法是 innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N為500 或1000) 且使用帶蓄電池後備電源的快取cache,防止系統斷電異常。

系統性能和資料安全是業務系統高可用穩定的必要因素。我們對系統的優化需要尋找一個平衡點,合適的才是最好的,根據不同的業務場景需求,可以將兩個引數做組合調整,以便是db系統的效能達到最優化。

以上這篇基於MySQL的儲存引擎與日誌說明(全面講解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。