前言
MySQL日誌記錄了MySQL數據庫日常操作和錯誤信息。MySQL有不同類型的日誌文件(各自存儲了不同類型的日誌),從日誌當中可以查詢到MySQL數據庫的運行情況、用戶的操作、錯誤的信息等。
MySQL的日誌分爲以下四大類:
- 錯誤日誌:記錄mysql服務的啓動,運行或停止mysql服務時出現的問題;
- 查詢日誌:記錄建立的客戶端的連接和執行的語句;
- 二進制日誌:記錄所有更改數據的語句,可以用於數據的複製;
- 慢查詢日誌:記錄所有執行的時間超過long_query_time的所有查詢或不使用索引的查詢。
默認情況下,所有日誌創建於MySQL數據目錄中,通過刷新日誌,可以強制MySQL關閉和重新打開日誌文件,Flush logs刷新日誌或者執行mysqladmin flush-logs 如果正使用MySQL複製功能,在複製服務器上可以維護更多日誌文件,這種日誌我們稱爲接替日誌。啓動日誌功能會降低MySQL數據庫的性能。
1)查看系統設置
<!--查看全局的系統狀態-->
mysql> show global variables\G
mysql> show global variables like '%log%';
<!--查看當前會話的系統狀態-->
mysql> show session variables\G
mysql> show session variables like '%log%';
若要修改上面查看出來的參數,可以在MySQL的主配置文件中的mysqld字段中寫入即可,如:binlog_cache_size = 1M。又或者可以在MySQL數據庫中進行臨時修改:set global binlog_cache_size = 1048576,這種臨時修改在MySQL重啓後就會失效。
2)查看運行狀態
<!--查看全局的運行狀態-->
mysql> show global status\G
<!--查看當前會話的運行狀態-->
mysql> show session status;
<!--查看MySQL的版本-->
[root@mysql ~]# mysql -V
mysql> status;
mysql> select version();
1、錯誤日誌
在mysql數據庫中,錯誤日誌功能是默認開啓的。默認情況下,錯誤日誌存儲在mysql數據庫的數據目錄中。錯誤日誌文件通常的名稱爲hostname.err。其中,hostname表示服務器主機名。 錯誤日誌信息可以自己進行配置的,錯誤日誌所記錄的信息是可以通過log-error和log-warnings來定義的,其中log-error是定義是否啓用錯誤日誌的功能和錯誤日誌的存儲位置,log-warnings是定義是否將警告信息也定義至錯誤日誌中。默認情況下錯誤日誌大概記錄以下幾個方面的信息:服務器啓動和關閉過程中的信息(未必是錯誤信息,如mysql如何啓動InnoDB的表空間文件的、如何初始化自己的存儲引擎的等等)、服務器運行過程中的錯誤信息、事件調度器運行一個事件時產生的信息、在從服務器上啓動服務器進程時產生的信息,MySQL有很多系統變量可以設置,系統變量設置不同,會導致系統運行狀態的不同。因此mysql提供兩組命令,分別查看系統設置和運行狀態。
一般而言,日誌級別的定義沒有會話變量都只是在全局級別下定義錯誤日誌的狀態:
mysql> show global variables like '%log_error%';
+---------------------+----------------------------------+
| Variable_name | Value |
+---------------------+----------------------------------+
| binlog_error_action | ABORT_SERVER |
| log_error | /usr/local/mysql/data/mysqld.err |
| log_error_verbosity | 3 |
+---------------------+----------------------------------+
3 rows in set (0.01 sec)
其中 log_error定義爲錯誤日誌文件路徑 ,log_error_verbosity值得含義如下:
Verbosity | Message |
---|---|
1 | Error only |
2 | Error and warnings |
3 | Errors, warnings,and notes(default) |
錯誤日誌的存放路徑在my.cnf的主配置文件中指定,如下:
爲了方便維護需要,有時候會希望將錯誤日誌中的內容做備份並重新開始記錄,這時候就可以利用MySQL 的FLUSH LOGS 命令來告訴MySQL 備份舊日誌文件並生成新的日誌文件。備份文件名以“.old”結尾。
刪除錯誤日誌
在mysql5.5.7之前:數據庫管理員可以刪除很長時間之前的錯誤日誌,以保證mysql服務器上的硬盤空間。mysql數據庫中,可以使用mysqladmin命令開啓新的錯誤日誌。mysqladmin命令的語法如下:mysqladmin –u root –p flush-logs也可以登錄mysql數據庫中使用FLUSH LOGS語句來開啓新的錯誤日誌。 在mysql5.5.7之後:服務器將關閉此項功能。只能使用重命名原來的錯誤日誌文件,手動沖洗日誌創建一個新的,方式如下:
[root@mysql ~]# cd /usr/local/mysql/data/
[root@mysql data]# mv mysqld.err{,.old}
[root@mysql data]# mysqladmin -uroot -p flush-logs
Enter password:
2、二進制日誌
二進制日誌主要記錄MySQL數據庫的變化,二進制日誌以一種有效的格式,並且是事務安全的方式包含更新日誌中可用的信息。二進制日誌包含了所有更新了數據或者已經潛在更新了數據。還包含關於每個更新數據庫的語句的執行時間,它不包含沒有修改任何數據的語句。使用二進制日誌的主要目的是最大可能地恢復數據庫。
1)啓動二進制日誌(默認情況下二進制日誌是關閉的)
[root@mysql data]# vim /etc/my.cnf #編輯主配置文件
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
server_id=1
socket=/usr/local/mysql/mysql.sock
log-error=/usr/local/mysql/data/mysqld.err
log-bin=/usr/local/mysql/data/binary_log #指定二進制日誌的路徑及名稱
expire_logs_days=10 #清除日誌的天數
max_binlog_size=100M #單個日誌文件的大小限制,超出會新建一個日誌文件
[root@mysql data]# systemctl restart mysqld #重啓MySQL使配置生效
[root@mysql data]# ll | grep binary #會在指定的路徑下生成以下兩個文件
-rw-r----- 1 mysql mysql 154 12月 30 20:59 binary_log.000001
-rw-r----- 1 mysql mysql 40 12月 30 20:59 binary_log.index
登錄到數據庫中也可以查看到,如下:
2)查看二進制日誌
MySQL二進制日誌存儲了所有的變更信息,MySQL二進制日誌經常使用。當MySQL創建二進制日誌文件時,首先創建一個以’filename’爲名稱,以’.index’爲後綴的文件;在創建一個以’filename’爲名稱,以’.000001’爲後綴的文件。當MySQL服務重啓一次,以’.000001’爲後綴的文件會增加一個,並且後綴名加1
遞增。如果日誌長度超過max_binlog_size的上限,也會創建一個新的日誌。 Show binary logs;可以查看當前的二進制日誌文件個數及其文件名。二進制日誌並不能直接查看,如果想要查看日誌內容,
可以通過mysqlbinlog命令查看:
mysql> show binary logs; <!---->
+-------------------+-----------+
| Log_name | File_size |
+-------------------+-----------+
| binary_log.000001 | 154 |
+-------------------+-----------+
1 row in set (0.00 sec)
也可以退出MySQL在命令行使用mysqlbinlog命令查看:
[root@mysql data]# mysqlbinlog binary_log.000001
3)刪除二進制日誌
MySQL的二進制文件可以配置自動刪除,同時MySQL提供了手動刪除二進制文件的方法:
RESET MASTER:刪除所有的二進制日誌文件;
PURGE MASTER LOGS:只刪除部分二進制日誌文件;
Reset master:刪除所有二進制日誌 ;
Purge master logs to ‘二進制名’ :刪除單個二進制日誌之前的。
mysql> purge master logs to "binary_log.000003"; <!--刪除...03之前的二進制日誌文件-->
mysql> purge master logs before '20180101'; <!--刪除2018-01-01之前的日誌文件-->
4)通過二進制日誌還原MySQL數據
關於通過二進制日誌還原的具體過程,還是參考我之前的博文吧!如下:
MySQL的備份與恢復詳解
3、事務日誌
事務日誌(InnoDB特有的日誌,因爲只有Innodb支持事務)可以幫助提高事務的效率。使用事務日誌,存儲引擎在修改表的數據時只需要修改其內存拷貝,再把修改行爲記錄到持久在硬盤上的事務日誌中,而不用每次都將修改的數據本身持久到磁盤。事務日誌採用追加的方式,因此寫日誌的操作是磁盤上一小塊區域內的順序I/O,而不像隨機I/O需要在磁盤的多個地方移動磁頭,所以採用事務日誌的方式相對來說要快得多。事務日誌持久以後,內存中被修改的數據在後臺可以慢慢的刷回到磁盤。目前大多數的存儲引擎都是這樣實現的。 如果數據的修改已經記錄到事務日誌並持久化,但數據本身還沒有寫回磁盤,此時系統崩潰,存儲引擎在重啓時能夠自動恢復這部分修改的數據。具有的恢復方式則視存儲引擎而定。
1)查看事務日誌的定義
mysql> show global variables like 'innodb_lo%';
在上述指令輸出的部分內容解釋如下:
| innodb_flush_log_at_trx_commit | 1 #在事務提交時innodb是否同步日誌從緩衝區到文件
中,當這個值爲1(默認值)之時,在每個事務提交時,日誌緩衝被寫到日誌文件,對日誌文件做到磁盤操作的刷新,性能會很差造成大量的磁盤I/O但這種方式最安全;如果設爲2,每次提交事務都會寫日誌,但並不會執行刷的操作。每秒定時會刷到日誌文件。要注意的是,並不能保證100%每秒一定都會刷到磁盤,這要取決於進程的調度。每次事務提交的時候將數據寫入事務日誌,而這裏的寫入僅是調用了文件系統的寫入操作,而文件系統是有緩存的,所以這個寫入並不能保證數據已經寫入到物理磁盤。設置爲0,日誌緩衝每秒一次地被寫到日誌文件,並且對日誌文件做到磁盤操作的刷新,但是在一個事務提交不做任何操作。
注:刷寫的概念
刷寫其實是兩個操作,刷(flush)和寫(write),區分這兩個概念是很重要的。在大多數的操作系統中,把Innodb的log buffer(內存)寫入日誌(調用系統調用write),只是簡單的把數據移到操作系統緩存中,操作系統緩存同樣指的是內存。並沒有實際的持久化數據。
所以,通常設爲0和2的時候,在崩潰或斷電的時候會丟失最後一秒的數據,因爲這個時候數據只是存在於操作系統緩存。之所以說“通常”,可能會有丟失不只1秒的數據的情況,比如說執行flush操作的時候阻塞了。 總結 設爲1當然是最安全的,但性能頁是最差的(相對其他兩個參數而言,但不是不能接受)。如果對數據一致性和完整性要求不高,完全可以設爲2,如果只最求性能,例如高併發寫的日誌服務器,設爲0來獲得更高性能。 |
innodb_locks_unsafe_for_binlog | OFF | innodb_log_buffer_size | 16777216 | innodb_log_checksums | ON | |||
---|---|---|---|---|---|---|---|---|---|
innodb_log_compressed_pages | ON | ||||||||
innodb_log_file_size | 50331648 #日誌文件大小 | ||||||||
innodb_log_files_in_group | 2 # DB中設置幾組事務日誌,默認是2 | ||||||||
innodb_log_group_home_dir | ./ #定義innodb事務日誌組的位置,此位置設置默認爲MySQL的datadir 。 |
每個事務日誌都是大小爲50兆的文件(不同版本的mysql有差異): 在mysql中默認以ib_logfile0,ib_logfile1名稱存在。
<!---->