1. 程式人生 > 資料庫 >MySQL日誌功能詳解

MySQL日誌功能詳解

一.查詢日誌

  它是用來儲存所有跟查詢相關的日誌,這種日誌型別預設是關閉狀態的,因為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  mysql
3>.檢視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)來提供這種保障。事務日誌不能幫助我們恢復資料,它的作用在於當作業系統崩潰時(比如異常斷電)它能夠保障已經提交的事物不丟失,而未提交的事物能回滾。如果想要恢復日誌還得依賴於二進位制日誌。