删除对于job收缩日志失败547_MySQL中常见的几种日志
MySQL 中有六種日志文件,分別是:
重做日志(redo log)、回滾日志(undo log)、二進制日志(binlog)、錯誤日志(errorlog)、慢查詢日志(slow query log)、一般查詢日志(general log),中繼日志(relay log)。
之前沒認真學習過,上次去面試被問死了,痛定思痛整理下相關的知識。
binglog
最早接觸 binlog 是做數據庫主從同步的時候,知道是通過同步 binlog 實現的。binlog 是 沒有 MySQL sever 層維護的一種二進制日志,與 innodb 引擎中的 redo/undo log 是完全不同的日志。其主要是用來記錄對 MySQL 數據更新或潛在發生更新的 SQL 語句,并以 “事務”的形式保存在磁盤中。
binlog 主要有以下作用:
- 復制:MySQL 主從復制在 Master 端開啟 binlog,Master 把它的二進制日志傳遞給 slaves 并回放來達到 master-slave 數據一致的目的
- 數據恢復:通過 mysqlbinlog 工具恢復數據
- 增量備份
幾個知識點:
- binlog 不會記錄不修改數據的語句,比如Select或者Show
- binlog 會重寫日志中的密碼,保證不以純文本的形式出現
- MySQL 8 之后的版本可以選擇對 binlog 進行加密
- 具體的寫入時間:在事務提交的時候,數據庫會把 binlog cache 寫入 binlog 文件中,但并沒有執行fsync()操作,即只將文件內容寫入到 OS 緩存中。隨后根據配置判斷是否執行 fsync。
- 刪除時間:保持時間由參數expire_logs_days配置,也就是說對于非活動的日志文件,在生成時間超過expire_logs_days配置的天數之后,會被自動刪除。
管理
有這幾個常用的命令可以查看 binlog 的狀態:
binlog 的配置信息:show variables like '%log_bin%';
binlog 的格式:show variables like 'binlog_format';
日志的文件列表:show binary logs;
當前日志的寫入狀態:show master status;
清空 binlog 日志:reset master;
格式
binlog 日志有 Row、Statement、Mixed 三種格式。可以通過 my.cnf 配置文件及 set global binlog_format='ROW/STATEMENT/MIXED'進行修改,命令行 show variables like 'binlog_format' 命令查看 binglog 格式。
Row格式
Row 格式僅保存記錄被修改細節,不記錄 sql 語句上下文相關信息。新版本的 MySQL 默認是 Row 格式。
- 優點:能非常清晰的記錄下每行數據的修改細節,不需要記錄上下文相關信息,因此不會發生某些特定情況下的存儲過程、函數或者觸發器的調用觸發無法被正確復制的問題,任何情況都可以被復制,且能加快從庫重放日志的效率,保證從庫數據的一致性
- 缺點:由于所有的執行的語句在日志中都將以每行記錄的修改細節來記錄,因此,可能會產生大量的日志內容,干擾內容也較多。比如一條 update 語句,如修改多條記錄,則 binlog 中每一條修改都會有記錄,這樣造成 binlog 日志量會很大,特別是當執行alter table之類的語句的時候,由于表結構修改,每條記錄都發生改變,那么該表每一條記錄都會記錄到日志中,實際等于重建了表。
Statement格式
每一條會修改數據的 sql 都會記錄在 binlog 中。
- 優點:只需要記錄執行語句的細節和上下文環境,避免了記錄每一行的變化,在一些修改記錄較多的情況下相比 Row 格式能大大減少 binlog 日志量,節約 IO,提高性能。
另外還可以用于實時的還原。
主從版本可以不一樣,從服務器版本可以比主服務器版本高。
- 缺點:為了保證 sql 語句能在 slave 上正確執行,必須記錄上下文信息,以保證所有語句能在 slave 得到和在 master 端執行時候相同的結果。
另外,主從復制時,存在部分函數(如 sleep)及存儲過程在 slave 上會出現與 master 結果不一致的情況,而相比 Row 記錄每一行的變化細節,絕不會發生這種不一致的情況。
Mixed格式
以上兩種格式混合。
經過前面的對比,可以發現 Row 和 Statement 各有優勢,如果可以根據 sql 語句取舍可能會有更好地性能和效果。Mixed 便是以上兩種形式的結合。不過,新版本的 MySQL 對 Row 模式也做了優化,并不是所有的修改都會完全以 Row 形式來記錄,像遇到表結構變更的時候就會以 Statement 模式來記錄,如果 SQL 語句確實就是 update 或者 delete 等修改數據的語句,那么還是會記錄所有行的變更;因此,現在一般使用 Row 即可。
主從復制
復制是 MySQL 最重要的功能之一,MySQL 集群的高可用、負載均衡和讀寫分離都是基于復制來實現。復制步驟如下:
undo log 和 redo log
undo log 和 redo log 其實都不是 MySQL 數據庫層面的日志,而是 InnoDB 存儲引擎的日志。二者的作用聯系緊密,事務的隔離性由鎖來實現,原子性、一致性、持久性通過數據庫的 redo log 或 redo log 來完成。redo log 又稱為重做日志,用來保證事務的持久性,undo log 用來保證事務的原子性和 MVCC。
redo log
功能
和大多數關系型數據庫一樣,InnoDB 記錄了對數據文件的物理更改,并保證總是日志先行,也就是所謂的 WAL,即在持久化數據文件前,保證之前的 redo 日志已經寫到磁盤。由于 redo log 是順序整塊寫入,所以性能要更好。
重做日志兩部分組成:一是內存中的重做日志緩沖(redo log buffer),是易失的;二是重做日志文件(redo log file),是持久的。redo log 記錄事務操作的變化,記錄的是數據修改之后的值,不管事務是否提交都會記錄下來。
寫入過程
在一條語句進行執行的時候,InnoDB 引擎會把新記錄寫到 redo log 日志中,然后更新內存,更新完成后就算是語句執行完了,然后在空閑的時候或者是按照設定的更新策略將 redo log 中的內容更新到磁盤中。
更詳細的步驟,需要了解兩個關鍵詞:checkpoint 和 LSN(Log Sequence Number),前者檢查點簡單來說就是把臟頁刷到磁盤的時間點,這個時間點之前的數據都已經保存到了持久存儲。而 LSN 是 InnoDB 使用的一個版本標記的計數,它是一個單調遞增的值。數據頁和 redo log 都有各自的 LSN。每次把 redo log 中的內容寫入到實際的數據頁之后,就會把 LSN 也同步過去。如果發生了宕機,我們可以根據數據頁中的 LSN 值和 redo log 中 LSN 的值判斷需要恢復的 redo log 的位置和大小。redo log 同樣也有自己的緩存,所以也涉及到刷盤策略,是通過innodb_flush_log_at_trx_commit這個參數控制的。
當對應事務的臟頁寫入到磁盤之后,redo log 的使命也就完成了,重做日志占用的空間就可以重用(被覆蓋)。
存儲結構
這一塊應該就沒必要深入了,redo log 的存儲都是以塊(block)為單位進行存儲的,每個塊的大小為 512 字節。同磁盤扇區大小一致,可以保證塊的寫入是原子操作。
另外 redo log 占用的空間是固定的,會循環寫入。文件大小由innodb_log_file_size參數控制。
undo log
undo log 有兩個作用:提供回滾和多版本并發控制下的讀(MVCC),也即非鎖定讀
在數據修改的時候,不僅記錄了redo,還記錄了相對應的 undo,如果因為某些原因導致事務失敗或回滾了,可以借助該 undo 進行回滾。
undo log 和 redo log 記錄物理日志不一樣,它是邏輯日志。可以認為當 delete 一條記錄時,undo log 中會記錄一條對應的 insert 記錄,反之亦然,當 update 一條記錄時,它記錄一條對應相反的 update 記錄。
有時候應用到行版本控制的時候,也是通過 undo log 來實現的:當讀取的某一行被其他事務鎖定時,它可以從 undo log 中分析出該行記錄以前的數據是什么,從而提供該行版本信息,讓用戶實現非鎖定一致性讀取。
undo log 是采用段(segment)的方式來記錄的,每個 undo 操作在記錄的時候占用一個 undo log segment。
另外,undo log 也會產生 redo log,因為 undo log 也要實現持久性保護。
當事務提交的時候,InnoDB 不會立即刪除 undo log,因為后續還可能會用到 undo log,如隔離級別為 repeatable read 時,事務讀取的都是開啟事務時的最新提交行版本,只要該事務不結束,該行版本就不能刪除,即 undo log 不能刪除。
當事務提交之后,undo log 并不能立馬被刪除,而是放入待清理的鏈表,由 purge 線程判斷是否有其他事務在使用 undo 段中表的上一個事務之前的版本信息,決定是否可以清理 undo log 的日志空間。
在 MySQL 5.7 之前,undo log 存儲在共享表空間中,因此有可能大大增加表空間的占用,5.7 之后可以通過配置選擇存儲在獨立的表空間中。
三種日志總結
首先 InnoDB 完成一次更新操作的具體步驟:
慢查詢日志
幾個配置參數:
- slow_query_log 慢查詢開啟狀態
- slow_query_log_file 慢查詢日志存放的位置(這個目錄需要 MySQL 的運行帳號的可寫權限,一般設置為 MySQL 的數據存放目錄)
- long_query_time 查詢超過多少秒才記錄
- log_queries_not_using_indexes:未使用索引的查詢也被記錄到慢查詢日志中(可選項)
修改參數可以通過配置文件,也可以在數據庫中通過SET關鍵字來設置。
參考文章
騰訊工程師帶你深入解析 MySQL binlog
詳細分析MySQL事務日志(redo log和undo log)
MySQL中的重做日志(redo log),回滾日志(undo log),以及二進制日志(binlog)的簡單總結
MySQL innoDB——redo log/undo log
15.6.6撤消日志
15.6.5重做日志
總結
以上是生活随笔為你收集整理的删除对于job收缩日志失败547_MySQL中常见的几种日志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下安装FFmpeg
- 下一篇: MongDB集合文档操作符