MySQL日誌功能詳解
阿新 • • 發佈:2020-11-24
一.查詢日誌
它是用來儲存所有跟查詢相關的日誌,這種日誌型別預設是關閉狀態的,因為MySQL的使用者有很多,如果將每個使用者的查詢操作都記錄下來的話,對伺服器的資源開銷也是一件令人煩惱的事情。查詢日誌常見的幾個引數:mysql> show global variables like 'log%'; #檢視是否記錄所有語句的日誌資訊於一般查詢日誌檔案(general_log),預設是關閉狀態 +----------------------------------------+---------------------+ | 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 | | log_error | /var/log/mysqld.log | | log_output | FILE | #它有三個值,即{TABLE|FILE|NONE},分別表示記錄在表中(table),檔案(file)中或是不記錄(none)。注意,只有og_output的值等於 FILE時,general_log_file的引數才會有意義。且 table和file 可以同時出現,用逗號分隔即可 | log_queries_not_using_indexes | OFF | | log_slave_updates | OFF | | log_slow_admin_statements | OFF | | log_slow_slave_statements | OFF | | log_throttle_queries_not_using_indexes | 0 | | log_warnings | 1 | +----------------------------------------+---------------------+ 13 rows in set (0.01 sec) mysql> show global variables like 'general_log' #檢視是否啟用查詢日誌功能 -> ; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | general_log | OFF | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'general_log'; #定義了一般查詢日誌儲存的檔案 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | general_log | OFF | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'general_log_file'; +------------------+----------------------------+ | Variable_name | Value | +------------------+----------------------------+ | general_log_file | /var/lib/mysql/iso-all.log | +------------------+----------------------------+ 1 row in set (0.00 sec)
mysql> set global log_output='table'; Query OK, 0 rows affected (0.00 sec) mysql> set global general_log='on'; Query OK, 0 rows affected (0.00 sec) mysql> show tables from mysql; +---------------------------+ | Tables_in_mysql | +---------------------------+ | columns_priv | | db | | event | | func | | general_log | | help_category | | help_keyword | | help_relation | | help_topic | | innodb_index_stats | | innodb_table_stats | | ndb_binlog_index | | plugin | | proc | | procs_priv | | proxies_priv | | servers | | slave_master_info | | slave_relay_log_info | | slave_worker_info | | slow_log | | tables_priv | | time_zone | | time_zone_leap_second | | time_zone_name | | time_zone_transition | | time_zone_transition_type | | user | +---------------------------+ 28 rows in set (0.00 sec) mysql> select * from mysql.general_log; +---------------------+---------------------------+-----------+-----------+--------------+---------------------------------+ | event_time | user_host | thread_id | server_id | command_type | argument | +---------------------+---------------------------+-----------+-----------+--------------+---------------------------------+ | 2020-11-21 10:59:01 | root[root] @ localhost [] | 45 | 0 | Query | select * from mysql.general_log | +---------------------+---------------------------+-----------+-----------+--------------+---------------------------------+ 1 row in set (0.01 sec)
三.錯誤日誌
顧名思義,這是用來記錄錯誤的日誌,但是不僅僅是記錄錯誤資訊,還包括MySQL啟動,關閉,複製執行緒(指的是從伺服器)的資訊喲。錯誤日誌預設是開啟的。它主要記錄的資訊如下: 1>.伺服器啟動和關閉過程中的資訊; 2>.伺服器執行過程中的錯誤資訊 3>.事件排程器執行一個事件時產生的資訊 4>.在複製架構中的從伺服器上啟動從伺服器執行緒時產生的資訊 常見引數如下:mysql> show global variables like 'log_error'; #指定錯誤日誌檔案位置 +---------------+---------------------+ | Variable_name | Value | +---------------+---------------------+ | log_error | /var/log/mysqld.log | +---------------+---------------------+ 1 row in set (0.00 sec) mysql> show global variables like 'log_warnings'; #是否將經過日誌也記錄在錯誤日誌檔案中去 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_warnings | 1 | +---------------+-------+ 1 row in set (0.00 sec)
四.二進位制日誌
1>.什麼是二進位制檔案只記錄修改相關的操作,記錄了當前伺服器的資料修改和有潛在可能性影響資料修改的語句。它用來實現複製的基本憑據。也就是說,你可以將生成環境中的MySQL的二進位制檔案拿到線下的伺服器上執行一下,理論上你會拿到和生成環境中一樣的資料喲,因此,二進位制日誌也叫複製日誌。二進位制日誌檔案預設在資料目錄下,通常情況下為mysql-bin#(例如:mysql-bin.000001,mysql-bin000002)2>.開啟二進位制日誌
[root@iso-all ~]# cat /etc/my.cnf|grep -v ^# [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES log-bin=mysql-bin # 新新增放[mysql]下 binlog_format=mixed #新新增放[mysql]下 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid [root@iso-all ~]# systemctl stop mysql [root@iso-all ~]# systemctl start mysql3>.檢視MySQL日誌檔案 由於二進位制檔案格式是二進位制型別的,我們不能用cat等檢視普通文字類命令去檢視這些二進位制日誌,我們可以通過mysqlbinlog來檢視。注意“show master status; ”檢視當前使用的二進位制日誌和下一個事件開始時的基於的位置。
mysql> show binlog events\G #檢視mysql的日誌 *************************** 1. row *************************** Log_name: mysql-bin.000001 Pos: 4 Event_type: Format_desc #事件型別 Server_id: 1 #指定伺服器的唯一標識 End_log_pos: 120 Info: Server ver: 5.6.50-log, Binlog ver: 4 1 row in set (0.00 sec)4>.日誌滾動 為了避免一個檔案過大,我們可以適當的將檔案的內容分開儲存,這就是日誌滾動,比如:當超過1G,日誌會滾動。當然,你也可以按照檔案大小自定義, 時間定義。想要手動滾動日誌,執行“flush logs;”即可。 5>.檢視當前正在使用的log日誌
mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 120 | +------------------+-----------+ 1 row in set (0.00 sec)
6>.二進位制的主要兩個功能是:
時間點恢復;(它的功能不亞於事務日誌!) 複製;7>.清除日誌 不要手動去刪除,而是用專業的工具去幹這件事情,即purge工具
mysql> help PURGE Many help items for your request exist. To make a more specific request, please type 'help <item>', where <item> is one of the following topics: PURGE BINARY LOGS PURGE MASTER LOGS
8>.Mysql 記錄二進位制日誌的格式
基於語句(statement): 只把語句伺服器執行的SQL語句記錄下來,但是可能存在不精準的情況。例如:“INSERT INTO t1 value(current_date())”,明銳的你可能發現有"current_date()"這個引數,如果從伺服器執行了想用的語句,如果存在網路延遲的情況,就會導致主從同步存在誤差! 基於行(row): 可以更精確的記錄資料,但是會面臨記錄的資料量過大的情況,可能一個語句的操作,匹配了1w多行,那麼這1w多行資料的修改都會記錄在這個二進位制檔案中去的。 混合模式(mixed): 既有了statement的模型,也用了mixed的特點。這種模式據反映不是很好,建議還是用基於行的模式,因為它能夠保證資料更加精確,換來更加精確的同時,可能對你的儲存空間和I/O的使用率會有所提高喲。 複製程式碼
9>.指定從那個位置開始讀取
mysqlbinlog的常用的[options]: a>--start-time #起始時間 b>.--stop-time #結束時間 c>.--start-position #基於起始位置來顯示資訊 d>.--stop-position #指定結束位置來顯示 命令列查詢方式如下(可以將讀取的內容儲存下來,在另一臺伺服器上可以情景再現): [root@iso-all ~]# mysqlbinlog --start-position=120 mysql-bin.000001 >/yanhuihuang/backup.sql SQL命令查詢方法如下: MariaDB [(none)]> show binlog events in 'mysql-bin.000001' from 120\G
10>.二進位制日誌檔案內容格式
事件發生的日期和時間(會在關鍵字“at”) 伺服器ID(server id) 事件結束位置(end_log_pos) 事件的型別(如:Query,Stop等等) 原伺服器生成此事件時的執行緒ID號(thead_id,可以通過“show processlist;”進行查詢) 語句時間戳和寫入二進位制檔案的時間差,單位為秒(exec_time,表示記錄日誌所用的時間戳,當他等於0時表示沒有用到1秒鐘。) 錯誤程式碼,0表示正常執行(error_code,排查方法就得檢視官方文件。) 事件內容(修改的SQL語句) 事件位置(相當於下一事件的開始位置,還是用“at”關鍵字標誌)
11>.二進位制日誌檔案常用的相關引數詳解
mysql> show global variables like 'log_bin'; #檢視是否開啟二進位制日誌功能,當然我們可以在MySQL的配置檔案(my.cnf)中指定檔案路徑(如:log_bin=/yinzhengjie/log/mysql-bin); +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'log_bin_trust_function_creators'; #不阻止任何儲存函式,存在一定風險,預設關閉即可; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | log_bin_trust_function_creators | OFF | +---------------------------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'sql_log_bin'; #當前會話是否將二進位制檔案進入進二進位制檔案,預設為ON; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'sql_log_off'; #是否將一般查詢日誌記入查詢日誌 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_log_off | OFF | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'sync_binlog'; #同步緩衝中的二進位制到硬碟的時間,0不基於時間同步,只在事件提交時同步 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sync_binlog | 0 | +---------------+-------+ 1 row in set (0.00 sec) mysql> show global variables like 'binlog_format'; #指定記錄二進位制日誌的格式 有三種格式:基於語句(statement),基於行(row),混合模式(mixed) +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | MIXED | +---------------+-------+ 1 row in set (0.01 sec) mysql> show global variables like 'max_binlog_cache_size'; #mysql二進位制日誌的緩衝區大小,僅用於快取事務類的語句 +-----------------------+----------------------+ | Variable_name | Value | +-----------------------+----------------------+ | max_binlog_cache_size | 18446744073709547520 | +-----------------------+----------------------+ 1 row in set (0.00 sec) mysql> show global variables like 'max_binlog_size'; #二進位制日誌檔案的上限,單位為位元組 +-----------------+------------+ | Variable_name | Value | +-----------------+------------+ | max_binlog_size | 1073741824 | +-----------------+------------+ 1 row in set (0.00 sec)MySQL的很多預設設定並不適合生成環境,我們需要調整很多東西。給出兩點提示: a>.切勿將二進位制日誌與資料檔案放在同一裝置; b>.可以臨時通過sql_log_bin來控制二進位制的寫入;
五.中繼日誌
從伺服器上的二進位制日誌。說白了中繼日誌其實就是從主伺服器上的二進位制日誌中取資料,然後寫入中級之日裡面,在從伺服器上,執行中繼日誌的sql資訊,這樣從伺服器就會得到和主伺服器一樣的內容,與此同時每次執行之後從伺服器的二進位制日誌也會記錄,聰明的你可能也會想到,這個從伺服器的二進位制日誌內容應該是和主伺服器是一致的,所以我們通常採取的操作就是將從伺服器的二進位制日誌關閉掉。 對於非從伺服器的中繼日誌並沒有啟用,可能會用到以下兩個引數: relay_log_purge = {ON|OFF} # 是否自動清理不在需要的中繼日誌 relay_log_space_limit #中繼(空間)大小是否限制
六.事務日誌.
先暫存事物提交的資料而後在同步到資料檔案中去的一種日誌。它的主要目的是將隨機I/O轉換為順序I/O並保證事物的相容性的。(順序I/O是早期提升寫入的速度一個不錯的解決方案,它比隨機I/O的效能可能會高出100倍呢!不過後來固態硬碟的出現順序I/O起到的作用就不是很明顯。) 事務日誌我們也稱之為日誌檔案組,它至少要存在兩個日誌檔案以實現輪詢。我們知道,MySQL的innodb是支援事物的,當啟動一個事務時,修改的資料是儲存在innodb的快取(innodb_buffer)中的,當這個快取儲存不下之後,它就會將資料寫入到日誌檔案組(事務日誌)中的一個檔案,當其中的一個檔案寫滿之後,又開始寫第二個檔案,與此同時,第一個檔案的內容開始網磁碟中寫,已達事務持久化的特性之一。這也就意味著當事務回滾時,很可能會將已經寫入磁碟中的資料進行刪除操作,這樣效能就會降低,而如果事務較小的話,也就不會存在將資料寫入到磁碟中,甚至不用寫入事務日誌中,直接在innodb的快取中就將問題解決,因此,儘可能使用小事務來替代大事務來提升事務引擎的效能。
當儲存事務日誌的磁碟壞掉是,資料是無法恢復的喲!因此選擇一個可靠的磁碟還是相當有必要的,比如我們可以給我們的資料做raid10或者raid1(推薦使用raid10)來提供這種保障。事務日誌不能幫助我們恢復資料,它的作用在於當作業系統崩潰時(比如異常斷電)它能夠保障已經提交的事物不丟失,而未提交的事物能回滾。如果想要恢復日誌還得依賴於二進位制日誌。