Mysql日誌相關

1、查詢日誌

        在 MySQL 中也稱爲通用日誌(general log),查詢日誌裏面記錄了數據庫執行的所有命令,不管語句是否正確,都會被記錄,原因如下:

  • insert 查詢爲了避免數據衝突,如果此前插入過數據,當前插入的數據如果跟主鍵或唯一鍵的數據重複那肯定會報錯;
  • update 時也會查詢因爲更新的時候很可能會更新某一塊數據;
  • delete 查詢,只刪除符合條件的數據;

       查詢日誌的開啓有助於幫助我們分析哪些語句執行密集,執行密集的 select 語句對應的數據是否能夠被緩存,同時也可以幫助我們分析問題,但是在併發操作非常多的場景下,查詢信息會非常多,若都記錄下來會導致 IO 非常大,影響了MySQL 性能,因此如果不是在調試環境下,是不建議開啓查詢日誌功能的。

查詢日誌模式默認是關閉的,可以通過以下命令開啓查詢日誌:

set global generallog=1 set global logoutput='table';

general_log=1 爲開啓查詢日誌,0 爲關閉查詢日誌,這個設置命令即時生效,不用重啓 MySQL 服務器。

2、慢日誌

        慢查詢會導致 CPU、IOPS、內存消耗過高,當數據庫遇到性能瓶頸時,大部分時間都是由於慢查詢導致的。

        開啓慢查詢日誌,可以讓 MySQL 記錄下查詢超過指定時間的語句,之後運維人員通過定位分析,能夠很好的優化數據庫性能。

        默認情況下,慢查詢日誌是不開啓的,只有手動開啓了,慢查詢纔會被記錄到慢查詢日誌中。使用如下命令記錄當前數據庫的慢查詢語句:

set global slowquerylog='ON';

上面的這個命令只是對當前數據庫有效,若 MySQL 數據庫重啓後就會失效。因此如果要永久生效,就要修改配置文件 my.cnf,設置 slowquerylog=1 並重啓 MySQL 服務器。

3、重做日誌(redo log)

       爲了最大程度的避免數據寫入時,因爲 IO 瓶頸造成的性能問題,MySQL 採用了這樣一種緩存機制,先將數據寫入內存中,再批量把內存中的數據統一刷回磁盤。爲了避免將數據刷回磁盤過程中,因爲掉電或系統故障帶來的數據丟失問題,InnoDB 採用 redo log 來解決此問題。

4、回滾日誌(undo log)

        用於存儲日誌被修改前的值,從而保證如果修改出現異常,可以使用 undo log 日誌來實現回滾操作。 undo log 和 redo log 記錄物理日誌不一樣,它是邏輯日誌,可以認爲當 delete 一條記錄時,undo log 中會記錄一條對應的 insert 記錄,反之亦然,當 update 一條記錄時,它記錄一條對應相反的 update 記錄,當執行 rollback 時,就可以從 undo log 中的邏輯記錄讀取到相應的內容並進行回滾。undo log 默認存放在共享表空間中,在 ySQL 5.6 中,undo log 的存放位置還可以通過變量 innodbundodirectory 來自定義存放目錄,默認值爲“.”表示 datadir 目錄。

5、錯誤日誌

        用來記錄 MySQL 服務器運行過程中的錯誤信息,比如,無法加載 MySQL 數據庫的數據文件,或權限不正確等都會被記錄在此,還有複製環境下,從服務器進程的信息也會被記錄進錯誤日誌。默認情況下,錯誤日誌是開啓的,且無法被禁止。默認情況下,錯誤日誌是存儲在數據庫的數據文件目錄中,名稱爲 hostname.err,其中 hostname 爲服務器主機名。在 MySQL 5.5.7 之前,數據庫管理員可以刪除很長時間之前的錯誤日誌,以節省服務器上的硬盤空間, MySQL 5.5.7 之後,服務器將關閉此項功能,只能使用重命名原來的錯誤日誌文件,手動沖洗日誌創建一個新的,命令爲:

mv hostname.err hostname.err.old mysqladmin flush-logs

6、二進制日誌(bin log)

        它是一個二進制文件,主要記錄所有數據庫表結構變更,比如,CREATE、ALTER TABLE 等,以及表數據修改,比如,INSERT、UPDATE、DELETE 的所有操作,bin log 中記錄了對 MySQL 數據庫執行更改的所有操作,並且記錄了語句發生時間、執行時長、操作數據等其它額外信息,但是它不記錄 SELECT、SHOW 等那些不修改數據的 SQL 語句。

binlog 的作用如下:

  • 恢復(recovery):某些數據的恢復需要二進制日誌。比如,在一個數據庫全備文件恢復後,用戶可以通過二進制日誌進行 point-in-time 的恢復;
  • 複製(replication):其原理與恢復類似,通過複製和執行二進制日誌使一臺遠程的MySQL數據庫(一般稱爲 slave 或者 standby)與一臺 MySQL 數據庫(一般稱爲 master 或者 primary)進行實時同步;
  • 審計(audit):用戶可以通過二進制日誌中的信息來進行審計,判斷是否有對數據庫進行注入攻擊。

        除了上面幾個作用外,binlog 對於事務存儲引擎的崩潰恢復也有非常重要的作用,在開啓 binlog 的情況下,爲了保證 binlog 與 redo 的一致性,MySQL 將採用事務的兩階段提交協議。當 MySQL 系統發生崩潰時,事務在存儲引擎內部的狀態可能爲 prepared(準備狀態)和 commit(提交狀態)兩種,對於 prepared 狀態的事務,是進行提交操作還是進行回滾操作,這時需要參考 binlog,如果事務在 binlog 中存在,那麼將其提交;如果不在 binlog 中存在,那麼將其回滾,這樣就保證了數據在主庫和從庫之間的一致性。

binlog 默認是關閉狀態,可以在 MySQL 配置文件(my.cnf)中通過配置參數 log-bin = [base-name] 開啓記錄 binlog 日誌,如果不指定 base-name,則默認二進制日誌文件名爲主機名,並以自增的數字作爲後綴,比如:mysql-bin.000001,所在目錄爲數據庫所在目錄(datadir)。

通過以下命令來查詢 binlog 是否開啓:

show variables like 'log_%';

binlog 格式分爲: STATEMENT、ROW 和 MIXED 三種:

  • STATEMENT 格式的 binlog 記錄的是數據庫上執行的原生 SQL 語句。這種格式的優點是簡單,簡單地記錄和執行這些語句,能夠讓主備保持同步,在主服務器上執行的 SQL 語句,在從服務器上執行同樣的語句。另一個好處是二進制日誌裏的時間更加緊湊,所以相對而言,基於語句的複製模式不會使用太多帶寬,同時也節約磁盤空間。並且通過 mysqlbinlog 工具容易讀懂其中的內容。缺點就是同一條 SQL 在主庫和從庫上執行的時間可能稍微或很大不相同,因此在傳輸的二進制日誌中,除了查詢語句,還包括了一些元數據信息,如當前的時間戳。即便如此,還存在着一些無法被正確複製的 SQL。比如,使用 INSERT INTO TB1 VALUE(CUURENT_DATE()) 這一條使用函數的語句插入的數據複製到當前從服務器上來就會發生變化,存儲過程和觸發器在使用基於語句的複製模式時也可能存在問題;另外一個問題就是基於語句的複製必須是串行化的,比如:InnoDB 的 next-key 鎖等,並不是所有的存儲引擎都支持基於語句的複製;

  • ROW 格式是從 MySQL 5.1 開始支持基於行的複製,也就是基於數據的複製,基於行的更改。這種方式會將實際數據記錄在二進制日誌中,它有其自身的一些優點和缺點,最大的好處是可以正確地複製每一行數據,一些語句可以被更加有效地複製,另外就是幾乎沒有基於行的複製模式無法處理的場景,對於所有的 SQL 構造、觸發器、存儲過程等都能正確執行;它的缺點就是二進制日誌可能會很大,而且不直觀,所以,你不能使用 mysqlbinlog 來查看二進制日誌,也無法通過看二進制日誌判斷當前執行到那一條 SQL 語句。現在對於 ROW 格式的二進制日誌基本是標配了,主要是因爲它的優勢遠遠大於缺點,並且由於 ROW 格式記錄行數據,所以可以基於這種模式做一些 DBA 工具,比如數據恢復,不同數據庫之間數據同步等;

  • MIXED 也是 MySQL 默認使用的二進制日誌記錄方式,但 MIXED 格式默認採用基於語句的複製,一旦發現基於語句的無法精確的複製時,就會採用基於行的複製。比如用到 UUID()、USER()、CURRENTUSER()、ROWCOUNT() 等無法確定的函數。

redo log 和 binlog 有什麼區別?

redo log(重做日誌)和 binlog(歸檔日誌)都是 MySQL 的重要的日誌,它們的區別如下:

  • redo log 是物理日誌,記錄的是“在某個數據頁上做了什麼修改”。
  • binlog 是邏輯日誌,記錄的是這個語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ”。
  • redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實現的,所有引擎都可以使用。
  • redo log 是循環寫的,空間固定會用完;binlog 是可以追加寫入的。“追加寫”是指 binlog 文件寫到一定大小後會切換到下一個,並不會覆蓋以前的日誌。

       剛開始 MySQL 裏並沒有 InnoDB 引擎,MySQL 自帶的引擎是 MyISAM,但是 MyISAM 沒有 crash-safe 的能力,binlog 日誌只能用於歸檔。而 InnoDB 是另一個公司以插件形式引入 MySQL 的,既然只依靠 binlog 是沒有 crash-safe 能力的,所以 InnoDB 使用另外一套日誌系統,也就是 redo log 來實現 crash-safe 能力。

注:crash-safe 是指發生宕機等意外情況下,服務器重啓後數據依然不會丟失的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章