將 MySQL 錯誤和慢日誌重定向到另一個數據庫
我正在執行多個 MySQL 伺服器作為從屬伺服器和主伺服器。在每台伺服器中查找緩慢的日誌和錯誤非常煩人,因此我想將所有錯誤記錄到外部數據庫中。
DB1 DB2 DBn ... \ | / \ | / <-- error logs and slow logs \ | / [MySQL error & slow log database]
有一些簡單的方法嗎?
或者我確實需要寫一些腳本和東西?
PS 我希望你欣賞我精湛的 ASCII 繪圖技巧
你有沒有考慮過將慢日誌轉換成 MyISAM 表?
對於 MySQL 5.1.30,您可以通過log_output選項選擇慢日誌和普通日誌的格式為 TABLE 或 FILE。它在 MySQL 5.5 中也可用。
為了支持 log_output 的 TABLE 選項,MySQL 提供了兩個表:
mysql.slow_log
mysql.general_log
為了這個問題,我只討論
mysql.slow_log
預設情況下,這是
mysql.slow_log
:mysql> show create table mysql.slow_log\G *************************** 1. row *************************** Table: slow_log Create Table: CREATE TABLE `slow_log` ( `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, `query_time` time NOT NULL, `lock_time` time NOT NULL, `rows_sent` int(11) NOT NULL, `rows_examined` int(11) NOT NULL, `db` varchar(512) NOT NULL, `last_insert_id` int(11) NOT NULL, `insert_id` int(11) NOT NULL, `server_id` int(10) unsigned NOT NULL, `sql_text` mediumtext NOT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log' 1 row in set (0.10 sec) mysql>
slow_log 表使用 CSV 儲存引擎。請注意,CSV 表不能被索引。這對於按日期和時間進行分析不是很有用。好消息:您可以將其轉換為 MyISAM 表。
為了促進基於 MyISAM 的慢日誌,請執行以下操作:
Step01) 將 mysql.slow_log 設為 MyISAM 表
ALTER TABLE mysql.slow_log ENGINE-MyISAM;
Step02) 呼叫時間戳列的索引
start_time
ALTER TABLE mysql.slow_log ADD INDEX (start_time);
Step03) 將以下行添加到 my.cnf (或 my.ini)
[mysqld] slow-query-log log-output=TABLE
Step04) 重啟 MySQL
對於 Linux
service mysql restart
或對於 Windows
net stop mysql net start mysql
Step05) 在 MySQL 中執行以下命令
mysql> SHOW VARIABLES LIKE 'long_query_time';
預設情況下long_query_time是 10 秒
Step06) 執行此命令
mysql> SELECT SLEEP(15);
如果 long_query_time 是 10 秒,這個 SELECT 應該故意放在 mysql.slow_log 中。
Step07) 執行此命令
mysql> SELECT sql_text FROM mysql.slow_log;
如果您在表格中看到任何帶有 的行
SELECT SLEEP(15);
,恭喜!您現在可以執行 SELECT 查詢
mysql.slow_log
以將部分或全部行複製到其他表或其他數據庫。我已經發布了與該主題相關的過去答案:
Mar 30, 2012
: MySQL慢日誌配置Nov 18, 2011
:在 MySQL 中創建自定義日誌表Jun 30, 2011
:如何將 MySQL 日誌輸出到 syslog?更新 2012-11-12 17:00 EDT
平心而論,這個問題確實詢問了錯誤日誌。我沒有明確包括任何關於它的內容。我將包含一些程式碼來解決如何
假設錯誤日誌在任何數據庫伺服器上定義如下:
[mysqld] log-error=/var/log/mysqld.log
您可以創建這樣的腳本:
ERROR_LOG=/var/log/mysqld.log LOG_LINES=/tmp/general-log-lines.txt ERROR_FOLDER=<folder where to copy logs> ERROR_TARGET=${ERROR_FOLDER}/`hostname`-DB-Errors.txt NEWCOUNT=`wc -l < ${ERROR_LOG}` if [ -f ${LOG_LINES} ] then OLDCOUNT=`cat ${LOG_LINES} | awk '{print $1}'` if [ ${OLDCOUNT} -lt ${NEWCOUNT} ] then (( DIFF = NEWCOUNT - OLDCOUNT )) tail -${DIFF} < ${ERROR_LOG} >> ${ERROR_TARGET} echo ${NEWCOUNT} > ${LOG_LINES} fi fi
或者,如果您想在不重啟 mysql 的情況下收集和重置錯誤日誌(僅限 Linux),您可以使用此方法(此技術在 Windows 中永遠無法完成,因為 Windows 作業系統會鎖定錯誤日誌文件以防止外部寫入):
ERROR_LOG=/var/log/mysqld.log LOG_LINES=/tmp/general-log-lines.txt ERROR_FOLDER=<folder where to copy logs> ERROR_TARGET=${ERROR_FOLDER}/`hostname`-DB-Errors.txt NEWCOUNT=`wc -l < ${ERROR_LOG}` if [ -f ${LOG_LINES} ] then OLDCOUNT=`cat ${LOG_LINES} | awk '{print $1}'` if [ ${OLDCOUNT} -lt ${NEWCOUNT} ] then (( DIFF = NEWCOUNT - OLDCOUNT )) tail -${DIFF} < ${ERROR_LOG} >> ${ERROR_TARGET} echo -n > ${ERROR_LOG} echo 0 > ${LOG_LINES} fi fi
將此腳本放在每個數據庫伺服器上。為該腳本設置一個 crontab,使其每 5 分鐘關閉一次。確保
ERROR_FOLDER
設置為公共共享文件夾。更新 2012-11-12 17:24 EDT
為了澄清,執行 MySQL
FLUSH LOGS;
是不夠的,因為……
對於所有基於文本的日誌,
FLUSH LOGS;
關閉並重新打開。mysqld 不提供輪換對於二進制日誌,
FLUSH LOGS;
將…
- 關閉目前二進制日誌
- 輪換到新的二進制日誌
- 打開新的二進制日誌
對於 MySQL 5.5,
FLUSH ERROR LOGS;
關閉並重新打開錯誤日誌。不提供旋轉這就是為什麼一些腳本是必要的