天天看點

MySQL(十一)之日志功能

一、MySQL日志

   日志是mysql資料庫的重要組成部分。日志檔案中記錄着mysql資料庫運作期間發生的變化;也就是說用來記錄mysql資料庫的用戶端連接配接狀況、SQL語句的執行情況和錯誤資訊等。當資料庫遭到意外的損壞時,可以通過日志檢視檔案出錯的原因,并且可以通過日志檔案進行資料恢複。 主要包含:錯誤日志、查詢日志、慢查詢日志、事務日志、二進制日志、中繼日志; 

1、查詢日志

   預設情況下查詢日志是關閉的。由于查詢日志會記錄使用者的所有操作,其中還包含增删查改等資訊,在并發操作大的環境下會産生大量的資訊進而導緻不必要的磁盤IO,會影響mysql的性能的。如若不是為了調試資料庫的目的建議不要開啟查詢日志。

檢視查詢日志是否開啟參數:

MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE '%log%'\G;
*************************** 16. row ***************************
Variable_name: general_log
        Value: OFF
*************************** 17. row ***************************
Variable_name: general_log_file
        Value: example.log
*************************** 41. row ***************************
Variable_name: log_output
        Value: FILE      
  • general_log:是否啟用查詢日志;
  • general_log_file:定義一般查詢日志儲存的檔案;
  • log_output:日志的輸出方式,定義時一般有三個值:{TABLE|FILE|NONE}

   日志的輸出方式一般有三種方式:file(檔案),table(表),none(不儲存);其中前兩個輸出位置可以同時定義,用逗号分隔即可。none表示是開啟日志功能但是不記錄日志資訊。file所在位置就是通過general_log_file參數定義的,而輸出位置定義為表時檢視日志的内容方式為:

舉例:

開啟查詢日志,記錄形式為表和檔案:

MariaDB [mysql]> SET GLOBAL general_log='ON';
Query OK, 0 rows affected (0.08 sec)

MariaDB [mysql]> SET GLOBAL log_output='file,table';
Query OK, 0 rows affected (0.02 sec)

[[email protected] ~]# cat /data/mydata/example.log
/usr/local/mysql/bin/mysqld, Version: 10.0.21-MariaDB-log (Source distribution). started with:
Tcp port: 3306  Unix socket: /tmp/mysql.sock
Time                 Id Command    Argument
150831 14:19:56	    4 Query	SET GLOBAL log_output='file,table'
150831 14:20:06	    4 Query	SHOW GLOBAL VARIABLES LIKE '%log%'
150831 14:21:14	    4 Query	SELECT DATABASE()
    4 Init DB	hellodb
150831 14:21:25	    4 Query	SHOW TABLES
150831 14:21:42	    4 Query	SELECT * FROM classes
150831 14:21:48	    4 Query	SELECT * FROM students
150831 14:22:00	    4 Query	SELECT * FROM courses
MariaDB [mysql]> SELECT * FROM general_log;
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------------+
| event_time                 | user_host                 | thread_id | server_id | command_type | argument                           |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------------+
| 2015-08-31 14:20:06.648747 | root[root] @ localhost [] |         4 |         1 | Query        | SHOW GLOBAL VARIABLES LIKE '%log%' |
| 2015-08-31 14:21:14.432517 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT DATABASE()                  |
| 2015-08-31 14:21:14.432695 | root[root] @ localhost [] |         4 |         1 | Init DB      | hellodb                            |
| 2015-08-31 14:21:25.196230 | root[root] @ localhost [] |         4 |         1 | Query        | SHOW TABLES                        |
| 2015-08-31 14:21:42.338430 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT * FROM classes              |
| 2015-08-31 14:21:48.701132 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT * FROM students             |
| 2015-08-31 14:22:00.563751 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT * FROM courses              |
| 2015-08-31 14:42:19.030252 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT DATABASE()                  |
| 2015-08-31 14:42:19.030429 | root[root] @ localhost [] |         4 |         1 | Init DB      | mysql                              |
| 2015-08-31 14:42:27.950684 | root[root] @ localhost [] |         4 |         1 | Query        | SHOW TABLES                        |
| 2015-08-31 14:42:54.122161 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT * FROM general_log          |
| 2015-08-31 14:42:59.459797 | root[root] @ localhost [] |         4 |         1 | Query        | SELECT * FROM general_log          |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------------+      

2、慢查詢日志

   慢查詢日志是用來記錄執行時間超過指定時間的查詢語句。通過慢查詢日志,可以查找出哪些查詢語句的執行效率很低,以便進行優化。一般建議開啟,它對伺服器性能的影響微乎其微,但是可以記錄mysql伺服器上執行了很長時間的查詢語句。可以幫助我們定位性能問題的。

慢查詢日志的相關參數:

MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'long%';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)

MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE '%log%'\G;
*************************** 58. row ***************************
Variable_name: slow_query_log
        Value: OFF
*************************** 59. row ***************************
Variable_name: slow_query_log_file
        Value: example-slow.log      

參數說明:

long_query_time: 10.000000:慢查詢的時長,超出此時間均會記錄為慢查詢;

slow_query_log={ON|OFF}:設定是否啟用慢查詢日志;其為全局變量,它的輸出形式也取決log_output={TABLE|FILE|NONE};

slow_query_log_file=example-slow.log:定義日志檔案路徑及名稱;

還有幾個相關參數:

log_slow_filter=admin,filesort,***********,tmp_table_on_disk :過濾器。

log_slow_queries=ON:是否啟用慢查詢日志,此為會話變量,隻是對目前使用者有效。           log_slow_rate_limit=1:記錄慢查詢日志的速率。                               log_slow_verbosity :是否記錄詳細的慢查詢日志。

啟用慢查詢日志:

MariaDB [mysql]> SET GLOBAL slow_query_log='ON';
Query OK, 0 rows affected (0.11 sec)      

将慢查詢日志的輸出形式定義為檔案和表:

MariaDB [mysql]> SET GLOBAL log_output='FILE,TABLE';
Query OK, 0 rows affected (0.00 sec)      

若有慢查詢日志可在下面兩個表和檔案中查詢:

MariaDB [hellodb]> SELECT * FROM mysql.slow_log;
Empty set (0.00 sec)
[[email protected] ~]# cat /data/mydata/example-slow.log      

3、錯誤日志

   在mysql資料庫中,錯誤日志功能是預設開啟的。并且,錯誤日志無法被禁止。預設情況下,錯誤日志存儲在mysql資料庫的資料檔案中。錯誤日志檔案通常的名稱為hostname.err。其中,hostname表示伺服器主機名。

   預設情況下錯誤日志大概記錄以下幾個方面的資訊:伺服器啟動和關閉過程中的資訊(未必是錯誤資訊,如mysql如何啟動InnoDB的表空間檔案的、如何初始化自己的存儲引擎的等等)、伺服器運作過程中的錯誤資訊、事件排程器運作一個事件時産生的資訊、在從伺服器上啟動伺服器程序時産生的資訊。

相關參數說明:

log_error = /path/to/error_log_file :錯誤日志所在的位置;

log_warnings = {1|0}:是否記錄警告資訊于錯誤日志中;

由于錯誤日志是預設自動開啟的,是以就可以查詢錯誤日志的内容:

[[email protected] ~]# tail /data/mydata/example.com.err 
150831  9:25:34 [Note] InnoDB: Initializing buffer pool, size = 128.0M
150831  9:25:34 [Note] InnoDB: Completed initialization of buffer pool
150831  9:25:35 [Note] InnoDB: Highest supported file format is Barracuda.
150831  9:25:35 [Note] InnoDB: 128 rollback segment(s) are active.
150831  9:25:35 [Note] InnoDB: Waiting for purge to start
150831  9:25:35 [Note] InnoDB:  Percona XtraDB (
http://www.percona.com)
 5.6.25-73.1 started; log sequence number 1803679      

更改錯誤日志位置可以使用log_error來設定形式如下:

[[email protected] ~]#  vim /etc/my.cnf

[mysqld]

Log_error=DIR/[filename]

   說明:其中,DIR參數指定錯誤日志的路徑filename參數是錯誤日志的名稱,沒有指定該參數時預設為主機名。重新開機mysql伺服器即可生效。

删除錯誤日志:

   由于錯誤日志長時間記錄會導緻其檔案的 增大,是以下面就使用日志滾動來将錯誤日志更新:

檢視系統原來的錯誤日志檔案内容:

[[email protected] ~]# ls -lh /data/mydata/example.com.err 
-rw-r----- 1 mysql root 7.5K 8月  31 09:25 /data/mydata/example.com.err
[[email protected] ~]# mv /data/mydata/example.com.err{,.old}
[[email protected] ~]# ls /data/mydata/example.com.err.old 
/data/mydata/example.com.err.old      

登入伺服器,執行日志滾動指令:

MariaDB [hellodb]> FLUSH LOGS;
Query OK, 0 rows affected (0.01 sec)      

這樣就可以看到錯誤日志檔案已經更新:

[[email protected] ~]# ls -lh /data/mydata/example.com.err*
-rw-rw---- 1 mysql mysql    0 8月  31 15:35 /data/mydata/example.com.err
-rw-r----- 1 mysql root  7.5K 8月  31 09:25 /data/mydata/example.com.err.old      

4、二進制日志

   二進制日志也叫作變更日志,主要用于記錄修改資料或有可能引起資料改變的mysql語句,并且記錄了語句發生時間、執行時長、操作的資料等等。是以說通過二進制日志可以查詢mysql資料庫中進行了哪些變化。一般大小體積上限為1G。實際中二進制日志可以根據實際的需求做出日志滾動,可以在達到1G滾動,還可以根據時間需要進行手動滾動日志,同時伺服器在重新開機後也會發生日志滾動。

mysql二進制日志說明:

安裝時預設路徑是在資料目錄内,檔案名可以在配置檔案中更改,建議在初始化時就定義好日志的名字,不建議其和資料放在同一塊實體裝置上。

[[email protected] ~]# ls /data/mydata/mysql-bin.*
/data/mydata/mysql-bin.000001  /data/mydata/mysql-bin.000004
/data/mydata/mysql-bin.000002  /data/mydata/mysql-bin.000005
/data/mydata/mysql-bin.000003  /data/mydata/mysql-bin.index      

日志的格式屬于二進制,故不能用文本方式來打開檔案,需要用專門的指令mysqlbinlog來檢視該檔案。

[[email protected] ~]# file /data/mydata/mysql-bin.000001 
/data/mydata/mysql-bin.000001: MySQL replication log      

說明:二進制日志記錄的方法有兩種即:位置 position和時間time。二進制日志的功用:即時點恢複和複制;

幾個關于日志的指令:

檢視目前系統所在記錄的二進制檔案:

MariaDB [hellodb]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 |      365 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.02 sec)      

手動執行滾動日志,執行此指令會滾動二進制日志和中繼日志:

MariaDB [hellodb]> FLUSH LOGS;
Query OK, 0 rows affected (0.01 sec)      

檢視目前伺服器中能被mysql所使用的二進制日志檔案

MariaDB [hellodb]> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |      2361 |
| mysql-bin.000002 |     13752 |
| mysql-bin.000003 |      2103 |
| mysql-bin.000004 |      1153 |
| mysql-bin.000005 |       365 |
+------------------+-----------+
5 rows in set (0.00 sec)      

基于shell指令行檢視

[[email protected] ~]# cat /data/mydata/mysql-bin.index 
./mysql-bin.000001
./mysql-bin.000002
./mysql-bin.000003
./mysql-bin.000004
./mysql-bin.000005      

檢視二進制檔案所記錄的内容:

MariaDB [hellodb]> SHOW BINLOG EVENTS IN 'log_file';      

基于指定位置之後查詢:

MariaDB [hellodb]> SHOW BINLOG EVENTS IN 'log_file'  FROM "End_log_pos";      

檢視二進制檔案除了可以在mysql的互動視窗進行檢視外還可以使用mysqlbinlog指令在shell環境進行檢視。

常用選項:

  • --start-time:起始時間
  • --stop-time:結束時間
  • --start-position:起始位置
  • --stop-position:結束位置

下面兩種方法均可檢視的指定位置之後的二進制檔案:

[[email protected] ~]# mysqlbinlog --start-position 2015 /data/mydata/mysql-bin.000001
MariaDB [hellodb]> SHOW BINLOG EVENTS IN 'mysql-bin.000001' FROM 2015;      

MySQL記錄二進制日志的格式:

  • 基于語句:預設的記錄格式;
  • 基于行:定義的并非資料本身而是這一行的資料是什麼;
  • 混合模式:交替使用行和語句、由mysql伺服器自行判斷。

注意:其中基于行的定義格式資料量會大一些但是可以保證資料的精确性。

二進制日志檔案内容格式:

  • 事件發生的日期和時間
  • 伺服器ID:server id 1
  • 事件的結束位置:end_log_pos
  • 事件的類型:Query
  • 原伺服器生成此事件時的線程ID:thread_id=26
  • 語句的時間戳和寫入二進制日志檔案的時間差:exec_time=1 
  • 錯誤代碼:error_code=0
  • 事件内容
  • 事件位置,相當于下一事件的開始位置

 伺服器參數:

  • log_bin = {ON|OFF}:是否啟用二進制日志,如果為mysqld設定了--log-bin選項,則其值為ON,否則則為OFF。
  • log_bin_trust_function_creators:用于控制建立存儲函數時如果會導緻不安全的事件記錄二進制日志條件下是否禁止建立存儲函數。
  • sql_log_bin = {ON|OFF}:用于控制二進制日志資訊是否記錄進日志檔案。預設為ON,表示啟用記錄功能。
  • sync_binlog:設定多久同步一次二進制日志至磁盤檔案中,0表示不同步,任何正數值都表示對二進制每多少次寫操作之後同步一次。
  • binlog_format = {statement|row|mixed}:指定二進制日志的類型,預設為STATEMENT。
  • max_binlog_cache_size : 二進制日志緩沖空間大小,僅用于緩沖事務類的語句;
  • max_binlog_stmt_cache_size:非事務的與事務語句緩沖的共用大小。
  • max_binlog_size :二進制日志檔案上限。

 建議:切勿将二進制日志與資料檔案放在一同裝置。

5、中繼日志

   主要是在mysql伺服器的中從架構中的從伺服器上用到的,當從伺服器想要和主伺服器進行資料的同步時,從伺服器将主伺服器的二進制日志檔案拷貝到己的主機上放在中繼日志中,然後調用SQL線程按照拷中繼日志檔案中的二進制日志檔案執行以便就可達到資料的同步。

配置參數:(隻在從伺服器上開啟)

  • relay-log=  指定中繼日志的位置和名字 
  • relay-log-index=  指定中繼日志的名字的索引檔案的位置和名字 
  • relay_log_purge={ON|OFF}:是否自動清理不再需要中繼日志

6、事務日志

   詳細的記錄了在什麼時間發生了什麼事,在哪個時間對哪些資料進行了改變,能後實作事件的重放,一般隻記錄對資料進行改變的操作,對于讀操作一般不進行記錄 

事務日志為資料庫伺服器實作以下功能:

  • 将随機IO轉換為順序IO,大大的提高了資料庫的性能,存儲的資料可能存在在磁盤的不同位置,降低了資料的讀取和操作性能。轉換為順序IO的原理為,先将資料存放在日志檔案中,然後由RDBSM的背景将日志中的資料存放到磁盤上,這樣就保證了存儲的資料是連續的。 
  • 為事件重放提供基礎,事務日志詳細的記錄了時間發生的時間以及操作的資料對象,事務程序可以根據這些資訊進行時間重放 預設的事務日志檔案有兩個,位于資料目錄下以ibdata+number結尾的數字,我們可以對事務日志的位置、檔案大小、增長方式進行定義,定義的方法如下: 

這裡以使用支援事務的Innodb存儲引擎為例 ,其相關參數:

  • innodb_data_home_dir = /innodata  定義存放事務日志的目錄