標籤:mysql 慢查詢 日誌 mysql日誌 普通查詢
假如你是一名 web 開發人員,如果你想調試你的應用或提升其效能的話,那你需要去參考各種記錄檔。日誌是開始故障排除最好的選擇。就著名的 MySql 資料庫伺服器而言,你需要參考以下記錄檔:
- 錯誤記錄檔:它包含了伺服器運行時(當然也包括服務啟動和停止時)所發生的錯誤資訊
- 普通查詢日誌:這是一個記錄 mysqld 在做什麼(串連,斷開,查詢)的通用日誌
- 慢查詢日誌:正如其名,它記錄了 "慢" 的查詢 SQL 陳述式
本文未涉及到二進位日誌。二進位日誌要求非常高的伺服器硬體設定,而且只是在特定情境下(比如,主從複製,主從安裝,某些資料的恢複操作)有用。否則的話,它就是一名實實在在的 "效能殺手"。
關於 MySql 日誌的官方文檔參考 http://dev.mysql.com/doc/refman/5.7/en/server-logs.html。
通過 MySql 配置啟用日誌日誌相關參數位於
[mysqld] 部分。
編輯 MySql 設定檔:
nano /etc/mysql/my.cnf
以上是 Debian 下的預設安裝目錄,其他 Linux 發布版可能不太一樣,這個檔案中 MySql 伺服器的參數如下:
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf.
#
# Here you can see queries with especially long duration
#log_slow_queries = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
#server-id = 1
#log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
MySql 安裝預設是不啟用所有記錄檔的(Windows 平台下的 error 日誌除外)。Debian 安裝 MySql 預設是將 error 日誌發送給 syslog。
error 日誌根據 /etc/mysql/conf.d/mysqld_safe_syslog.cnf 配置,error 日誌推送給 syslog:
[mysqld_safe]
syslog
這是推薦的做法。如果你由於某種原因,不想講 error 日誌推給 syslog,將 /etc/mysql/conf.d/mysqld_safe_syslog.cnf 檔案中的上述行注掉,或者直接刪除掉這個檔案,然後在 /etc/mysql/my.cnf 中添加以下行:
[mysqld_safe]
log_error=/var/log/mysql/mysql_error.log
[mysqld]
log_error=/var/log/mysql/mysql_error.log
一般查詢日誌要啟用一般查詢日誌,將相關行取消注釋(或者添加)即可:
general_log_file = /var/log/mysql/mysql.log
general_log = 1
慢查詢日誌要啟用慢查詢日誌,將相關行取消注釋(或者添加)即可:
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
配置修改後重啟 MySql 伺服器以上方法要求服務重啟才會生效:
service mysql restart
或者使用 systemd:
systemctl restart mysql.service
運行時啟用日誌MySql 5.1 之後我們可以在運行時啟用或者禁用日誌。
運行時啟用日誌,登入 MySql 用戶端(mysql -u root -p)然後執行:
SET GLOBAL general_log = ‘ON‘;
SET GLOBAL slow_query_log = ‘ON‘;
運行時禁用日誌,登入 Mysql 用戶端(mysql -u root -p)後執行:
SET GLOBAL general_log = ‘OFF‘;
SET GLOBAL slow_query_log = ‘OFF‘;
這種方式適用於所有平台並且不需要重啟服務。
顯示日誌結果error 日誌按以上辦法設定以後,你可以通過以下命令顯示 error 日誌:
tail -f /var/log/syslog
備忘:如果你沒有配置 error 記錄檔,MySql 將把 error 日誌儲存在資料目錄(通常是 /var/lib/mysql)下的一個名為 {host_name}.err 的檔案中。
普通查詢日誌按以上辦法設定以後,你可以通過使用以下命令來顯示普通日誌:
tail -f /var/log/mysql/mysql.log
備忘:如果你沒有配置普通記錄檔,MySql 將把普通日誌儲存在資料目錄(通常是 /var/lib/mysql)下的一個名為 {host_name}.log 的檔案中。
慢查詢日誌按以上辦法設定以後,你可以通過使用以下命令來顯示慢查詢日誌:
tail -f /var/log/mysql/mysql-slow.log
備忘:如果你沒有配置慢查詢記錄檔,MySql 將把普通日誌儲存在資料目錄(通常是 /var/lib/mysql)下的一個名為 {host_name}-slow.log 的檔案中。
迴圈日誌別忘了滾動日誌,否則的話記錄檔可能會變得很龐大。
在 Debian(以及 Debian 派生系列諸如 Ubuntu 等)系統,MySql 初始安裝之後,迴圈日誌就已經使用了 logrotate:
nano /etc/logrotate.d/mysql-server
對於其他 Linux 發行版,可能需要做一些改動:
# - I put everything in one block and added sharedscripts, so that mysql gets# flush-logs‘d only once.# Else the binary logs would automatically increase by n times every day.# - The error log is obsolete, messages go to syslog now./var/log/mysql.log /var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log { daily rotate 7 missingok create 640 mysql adm compress sharedscripts postrotate test -x /usr/bin/mysqladmin || exit 0 # If this fails, check debian.conf! MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf" if [ -z "`$MYADMIN ping 2>/dev/null`" ]; then # Really no mysqld or rather a missing debian-sys-maint user? # If this occurs and is not a error please report a bug. #if ps cax | grep -q mysqld; then if killall -q -s0 -umysql mysqld; then exit 1 fi else $MYADMIN flush-logs fi endscript}
檢驗伺服器配置使用 show variables like ‘%log%‘; 來檢查伺服器和記錄檔相關的變數:
[email protected] ~ #
mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 144332
Server version: 5.5.31-0+wheezy1 (Debian)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;‘ or ‘\h‘ for help. Type ‘\c‘ to clear the current input statement.
mysql>
show variables like ‘%log%‘;
+-----------------------------------------+--------------------------------+
| Variable_name | Value |
+-----------------------------------------+--------------------------------+
| back_log | 50 |
| binlog_cache_size | 32768 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_format | STATEMENT |
| binlog_stmt_cache_size | 32768 |
| expire_logs_days | 10 |
| general_log | OFF |
| general_log_file | /var/lib/mysql/cosmos.log |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_buffer_size | 8388608 |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_mirrored_log_groups | 1 |
| log | OFF |
| log_bin | OFF |
| log_bin_trust_function_creators | OFF |
| log_error | |
| log_output | FILE |
| log_queries_not_using_indexes | OFF |
| log_slave_updates | OFF |
| log_slow_queries | OFF |
| log_warnings | 1 |
| max_binlog_cache_size | 18446744073709547520 |
| max_binlog_size | 104857600 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| max_relay_log_size | 0 |
| relay_log | |
| relay_log_index | |
| relay_log_info_file | relay-log.info |
| relay_log_purge | ON |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
| slow_query_log | OFF |
| slow_query_log_file | /var/lib/mysql/cosmos-slow.log |
| sql_log_bin | ON |
| sql_log_off | OFF |
| sync_binlog | 0 |
| sync_relay_log | 0 |
| sync_relay_log_info | 0 |
+-----------------------------------------+--------------------------------+
41 rows in set (0.00 sec)
伺服器變數相關官方文檔參考 http://dev.mysql.com/doc/refman/5.7/en/server-options.html。
何時啟用日誌MySql 預設安裝的話,所有的記錄檔都不會被啟用的(除了 Windows 平台上的 error 日誌)。Debian 上安裝預設將 error 日誌發給 syslog。
實際上,在很多情況下記錄檔都可以提供關鍵問題的解決辦法:
- 總是啟用 error 日誌
- 在這些情況下開啟普通查詢日誌(最好在運行時):檢查你的應用是否正確處理了 MySql 資料庫連接(一個常見的錯誤就是從一個單一指令碼多次串連到 MySql);監控來自你的應用的查詢的執行情況;測試 memcached(或者類似的軟體),檢查某查詢是被 db 執行還是被 memcached 處理
- 當你的應用由於某些原因造成效能下降而你想找到這些慢查詢時,啟用慢查詢日誌(MySql 最好是在短期內這樣配置,比如 2-3 天)
樣本以下是一個 MySql 普通日誌的樣本:
131021 17:43:50 43 Connect [email protected] as anonymous on pnet_blog
43 Init DB pnet_blog
43 Query SELECT count(id) as total_posts FROM posts WHERE date_published is not null AND date_published <= ‘20131021144350‘
43 Query SELECT * FROM posts WHERE date_published is not null AND date_published <= ‘20131021144350‘ ORDER BY date_published DESC LIMIT 0,10
44 Connect [email protected] as anonymous on pnet_blog
44 Query SELECT id, title, impressions FROM tips WHERE date_published IS NOT NULL AND date_published <= ‘20131021144350‘ ORDER BY date_published DESC LIMIT 0, 10
44 Quit
43 Quit
131021 17:44:28 45 Connect [email protected] as anonymous on pnet_blog
45 Init DB pnet_blog
45 Query SELECT * FROM posts WHERE url=‘how-and-when-to-enable-mysql-logs‘
45 Query UPDATE posts SET impressions=impressions+1 WHERE id=‘41‘
45 Query SELECT url, post_title FROM posts WHERE date_published IS NOT NULL AND date_published < ‘20131020150000‘ ORDER BY date_published DESC LIMIT 0,1
45 Query SELECT url, post_title FROM posts WHERE date_published IS NOT NULL AND date_published > ‘20131020150000‘ ORDER BY date_published ASC LIMIT 0,1
45 Query SELECT * FROM posts WHERE date_published is not null AND date_published <= ‘20131021144428‘ AND date_published >= ‘20130421144428‘ ORDER BY impressions DESC LIMIT 0,10
46 Connect [email protected] as anonymous on pnet_blog
46 Query SELECT id, title, impressions FROM tips WHERE date_published IS NOT NULL AND date_published <= ‘20131021144428‘ ORDER BY date_published DESC LIMIT 0, 10
46 Quit
45 Quit
原文連結:http://www.pontikis.net/blog/how-and-when-to-enable-mysql-logs。
何時、如何開啟 MySql 日誌?