- 工信部備案號 滇ICP備05000110號-1
- 滇公安備案 滇53010302000111
- 增值電信業務經營許可證 B1.B2-20181647、滇B1.B2-20190004
- 云南互聯網協會理事單位
- 安全聯盟認證網站身份V標記
- 域名注冊服務機構許可:滇D3-20230001
- 代理域名注冊服務機構:新網數碼
MySQL 的日志記錄了運行的各種信息,是 MySQL 事務、性能、數據容災、異常排查等的基礎。本文將介紹 MySQL 一些關鍵日志的作用和原理。
MySQL InnoDB 引擎重要的三個日志:
Binlog
一、簡介
概述:binlog記錄DDL 和 DML語句,但不包括SELECT、SHOW 等語句,簡單說只要發上了表結構變化或表數據更新,都會產生binlog日志。
特點:undo log是二進制邏輯日志,記錄內容是語句的原始邏輯,屬于Server層,和引擎無關。只在事務提交時才寫入,適用于數據備份和主從復制。
作用:
災難時的數據恢復;
MySQL 的主從復制。
所在位置:通常默認的MySQL數據目錄為/var/lib/mysql。
二、記錄格式
三、寫入機制
事務執行過程中,先把日志寫到binlog cache
。
事務提交的時候,再把binlog cache
寫到binlog
文件中。
“ binlog cache: 1. 為了保證一個事務的所有操作能夠不被拆開,一次性寫入 2. 大小受 3. 寫入策略受bin log
binlog_cache_size
參數控制。sync_binlog
參數控制。
四、日志操作命令
查看啟動情況
show variables like'%log_bin%';
日志查看
命令:日志是二進制存儲的,無法直接讀取,需要通過mysqlbinlog
命令查看。
語法:mysqlbinlog[參數選項]logfilename
選項含義:
-d
:指定數據庫名稱,只列出指定的數據庫相關操作。;
-o
:忽略掉日志中的前n行命令;
-v
:將行事件(數據變更)重構為SQL語句;
-w
:將行事件(數據變更)重構為SQL語句,并輸出注樣信息;
日志刪除
對于比較繁忙的業務系統,每天生成的binlog
數據巨大,如果長時間不清除,將會占用大量磁盤空間。可以通過以下幾種方式清理日志:
redo log
一、簡介
概述:redo log
,重做日志,記錄的是事務提交時數據頁的物理修改。
特點:物理日志,InnoDB存儲引擎獨有的,保證數據的持久性與完整性。記錄內容是“在某個數據頁上做了什么修改”,在事務過程中是不斷寫入。
大小是固定的,前面的內容會被覆蓋。
二、寫入機制
當客戶端提交數據修改時,會先去Buffer Pool
獲取數據,若沒有則查詢出來放入Buffer Pool
;
生成redo log
放入Redolog Buffer
,記錄數據頁的物理變化,此時redo log
的狀態是prepare
;
事務提交后,將Redolog Buffer
中的redo log
刷新到磁盤持久化存儲,此時redo log
的狀態是commit
。
這樣即使Buffer Pool
中的臟頁刷新到磁盤時出錯,恢復時也可以通過redo log
日志進行重新刷新。
臟頁:當內存數據頁跟磁盤數據頁內容不一致的時候,我們稱這個內存頁為“臟頁”。
WAL:先寫日志,再寫磁盤的思想,叫做WAL(Write Ahead Logging)
。
三、對比Binlog
四、兩階段提交
了解了上面的binlog
和redo log
以后,你會發現, MySQL在執行更新操作的過程中,一次事務的完成均會記錄著兩個文件,區別見上面的對比表格。
那么問題來了,兩個文件到底是哪個先存?以及寫入的時機有什么不同?
回答這兩個問題之前,需要先考慮另外一個問題,這兩個文件能否各存各的,會出問題嗎?
答案是:不可以,會出現兩個文件中數據不一致的問題,可能導致主從數據庫數據不一致。
根據redo log
的特點,在事務過程中是不斷寫入,而binlog
只在事務提交時才寫入。
如果我們對某條數據執行了age 更改為 18
的操作,此時原 age
為 17,redo log
已經寫入了數據,而undolog
還沒寫入之前數據庫崩潰了。
緊接著數據庫重啟后進行恢復,主數據庫根據redo log
恢復數據為age = 18
,而從數據庫根據binlog
日志進行同步age = 17
,這時就出現了不一致問題。
緊接著我們回答一下開始的兩個問題,為了避免上述問題的產生,InnoDB存儲引擎使用兩階段提交方案:
生成redo log
放入Redolog Buffer
,記錄數據頁的物理變化,此時redo log
的狀態是prepare
;
事務提交后,并且,binlog
寫入成功后,再將Redolog Buffer
中的redo log
刷新到磁盤持久化存儲,此時redo log
的狀態是commit
;
進行數據恢復時,若redo log
的狀態是prepare
,則有兩種情況:
binlog
為空則進行數據回滾;
binlog
不為空,代表事務已commit
,進行數據恢復,這個一般發生在binlog
寫入成功,但是redo log
更改狀態失敗時。
undo log
一、簡介
概述:undo log
,回滾日志,事務執行時,用于記錄數據被修改前的信息,在異常發生時,會對已經執行的操作進行回滾。
作用:
異常回滾,保證事務的原子性;
版本鏈用于MVCC
機制中;
特點:
當delete
一條數據時,它會插入一條對應的insert
記錄;
當update
一條記錄時,它會插入一條對象相反的記錄。
當執行回滾時,就可以讀取其中的記錄進行操作。
分類:
二、版本鏈
不同事務或者相同事務對同一條記錄進行修改,會使該記錄的undo log
生成一條記錄版本的鏈表,鏈表頭部是最新的舊記錄,鏈表尾部是最早的舊記錄。
上述事務能夠看到的版本鏈上的哪條歷史數據,是由MVCC
的ReadView來決定。
錯誤日志
最重要的日志之一,記錄了當mysqld.log
啟動和停止時,以及服務器在運行過程中發生任何嚴重錯誤時的相關信息,當數據庫出現故障無法使用時,建議先看此日志。
日志默認打開,默認存放目錄/var/log/
,默認文件名mysqld.log
。
如果找不到,可執行show variables like '%log_error%'
查看。
查詢日志
該日志記錄了客戶端所有的操作語句,默認關閉,開啟需做以下配置:
修改/etc/my.cnf
文件;
設置general_log = 1
,1 表示開啟,0 表示關閉;
設置日志的文件名,general_log_file = mysql_query.log
,未指定默認為host_name.log
。
慢查詢日志
該日志記錄了所有執行時間超過參數long_query_time
,且所記錄數不小于min_examined_row_limit
的所有 SQL 語句。
默認關閉,開啟需以下配置(根據所需):
修改/etc/my.cnf
文件;
設置show_query_log = 1
,1 表示開啟,0 表示關閉;
設置long_query_time = 2
,未指定默認為 10 秒;
設置long_show_admin_statements = 1
,開啟記錄執行慢的管理語句;
設置long_queries_not_using_indexes = 1
,開啟記錄執行較慢且未使用索引的語句;
通過對 MySQL 各類關鍵日志的深入了解,我們清晰認識到它們在數據庫運行的各個環節發揮的關鍵作用。無論是數據的持久保存、事務的正確執行,還是問題的排查解決,日志都不可或缺。在今后的 MySQL 使用和管理中,合理運用這些日志知識,能讓數據庫運行更加穩定高效。
想了解更多相關技術小分享可以上藍隊云官網查閱,更多技術問題,也可以直接咨詢。同時,藍隊云整理了運維必備的工具包免費分享給大家使用,需要的朋友可以直接咨詢。
售前咨詢
售后咨詢
備案咨詢
二維碼
TOP