MS SQL的日志信息/日志記錄,可能對你來說,既熟悉又陌生,熟悉是因為你可能一直都在使用,查看、關注一些日志信息/記錄,例如,作業歷史記錄;陌生是因為你可能從不關注日志信息/記錄的管理,這里我一直用日志信息/記錄這個詞,而沒有用日志文件這個詞來闡述,是想讓大家把它和事務日志文件(ldf)區分開來,網上你用日志文件做搜索關鍵詞,可能搜出來的都是事務日志相關的信息。其實它真的也叫日志文件,這篇文章我大概從日志記錄分類、如何查看日志記錄、日志記錄的位置、日志記錄的設置、為什么錯誤日志會暴增、如何清除日志記錄等方面來講述。
日志記錄分類
按日志文件查看器,習慣將錯誤日志歸為SQL SERVER、 SQL SERVER 代理, Windows應用程序日志,數據庫郵件等四類錯誤日志記錄。如果還考慮維護計划、遠程維護計划、作業歷史記錄日志信息,總共是7類日志信息文件。
其中Windows應用程序日志類型又分為系統日志(System)、安全日志(Security)、應用程序日志(Application), PatchLink日志等幾種,我在服務器(Windows Server 2008 R2 Standard)上打開SSMS,居然發現又多了HardwareEvents, Internet Explorer、Windows PowerShell等日志文件。這些都是系統的日志文件。你不必太糾結有多少種。
日志記錄位置
SQL SERVER日志記錄、 SQL SERVER代理記錄的位置如下所示, SQL SERVER日志記錄一般存儲在ERRORLOG.n(n為數字)文件里, SQL SERVER代理日志記錄位於SQLAGENT.n這類的文件里。當然這跟數據庫的版本也有關系:
版本 |
路徑 |
SQL SERVER 2005 |
Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG |
SQL SERVER 2008 |
Program Files\Microsoft SQL Server\MSSQL10.實例名\MSSQL\LOG |
SQL SERVER 2008 R2 |
Program Files\Microsoft SQL Server\MSSQL10_50.實例名\MSSQL\LOG |
SQL SERVER 2005,默認情況下,錯誤日志位於 Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\ERRORLOG 和 ERRORLOG.n 文件中。其中MSSQL.n的區分為:
MSSQL.1:SQLSERVER
MSSQL.2:SSAS
MSSQL.3:SQLExpress
MSSQL.4:SSRS
所以,一般情況下,你只需要關注MSSSQL.1目錄下的日志文件
那么,數據庫郵件日志記錄位於哪里呢?作業歷史記錄日志信息、Windows應用程序日志又位於哪里呢?是不是從沒考慮過這些?
數據庫郵件日志記錄信息可以從視圖msdb.dbo.sysmail_event_log查詢得到,實質保存在[dbo].[sysmail_log]表里面。
- SELECT log_id ,
- CASE event_type
- WHEN 0 THEN 'success'
- WHEN 1 THEN 'information'
- WHEN 2 THEN 'warning'
- ELSE 'error'
- END AS event_type ,
- log_date ,
- description ,
- process_id ,
- sl.mailitem_id ,
- account_id ,
- sl.last_mod_date ,
- sl.last_mod_user
- FROM[dbo].[sysmail_log] sl
- WHERE ( ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0) = 1 )
- OR( EXISTS( SELECT mailitem_id
- FROM [dbo].[sysmail_allitems] ai
- WHERE sl.mailitem_id = ai.mailitem_id ) )
作業歷史記錄日志信息都保存在msdb.dbo.sysjobhistory的表里面,其中run_status字段代表作業執行狀態
0 = 失敗
1 = 成功
2 = 重試
3 = 已取消
4= 正在進行
所有Windows應用程序日志其實都位於同一位置%SystemRoot%\System32\Winevt\Log。像Application日志文件位於%SystemRoot%\System32\Winevt\Logs\Application.evtx,如下所示,
查看日志記錄
查看日志記錄可以確保進程(例如,備份和還原操作、批處理命令或其他腳本和進程)成功完成。此功能可用於幫助檢測任何當前或潛在的問題領域,包括自動恢復消息(尤其是在 SQL Server 實例已停止並重新啟動時)、內核消息或其他服務器級錯誤消息。
方式1: 查看錯誤日志文件
對SQL SERVER、SQL SERVER AGENT日志記錄信息,你可以直接去log目錄下找到ERRORLOG、SQLAGENT日志文件,直接打開查看;而像Windows應用程序日志記錄,去到%SystemRoot%\System32\Winevt\Log目錄,找到對應的日志文件,直接打開查看。
方式2:通過SSMS來查看日志記錄
查看與常規 SQL Server 活動相關的日志
- 在對象資源管理器中,依次展開“管理”和“SQL Server 日志”,再雙擊“當前<日期/時間>”,將顯示 SQL Server、“SQL 代理”和“Windows 事件”日志。
查看與作業相關的日志
- 在對象資源管理器中,展開“SQL Server 代理”,右鍵單擊“作業”,再單擊“查看歷史記錄”,此時將顯示“作業歷史記錄”和“SQL 代理”日志。
查看與維護計划相關的日志
- 在對象資源管理器中,展開“管理”,右鍵單擊“維護計划”,再單擊“查看歷史記錄”,此時將顯示“維護計划”、“作業歷史記錄”和“SQL 代理”日志。
方式3:用腳本查看
3.1 對於SQL SERVER日志文件,可以通過下面腳本查看:
--查看日志文件的存檔號
EXEC master.dbo.sp_enumerrorlogs
用這個命令可以查看日志文件的大小,這個非常有用,你可以把大小異常的文件給排查出來。
--根據存檔號查看該檔日志內容
EXEC master.dbo.xp_readerrorlog 1
--根據job_id查看SQL SERVER日志記錄
SELECT * FROM msdb.dbo.sysjobhistory WHERE job_id='36E9232B-CD5B-4646-9BED-B8242090FFF9'
3.2 對於作業歷史記錄日志信息,你既可以通過下面存儲過程查看,也可以直接查詢對應的表。
例如,我要查看作業“ServerDiskCapacityCheck”的歷史記錄
- USE msdb ;
- GO
- EXEC dbo.sp_help_jobhistory
- @job_name = N'ServerDiskCapacityCheck' ;
- GO
- »ò
- SELECT j.name AS [JOB_NAME] ,
- h.step_id AS [Step] ,
- h.step_name AS [STEP_NAM] ,
- h.MESSAGE AS [Message] ,
- [Status] = CASE WHEN h.run_status = 0 THEN 'Failed'
- WHEN h.run_status = 1 THEN 'Succeeded'
- WHEN h.run_status = 2 THEN 'Retry'
- WHEN h.run_status = 3 THEN 'Canceled'
- END,
- h.run_date AS [RunDate] ,
- h.run_time AS [RunTime] ,
- h.run_duration AS [RunDuration]
- FROM sysjobs j
- INNER JOIN sysjobhistory h ON h.job_id = j.job_id
- WHERE h.run_date>=CONVERT(CHAR(8),GETDATE()-1,112) AND h.run_status<>1
- /* WHERE j.name = 'Job_Name' */
- ORDER BYh.run_date, h.run_time
3.3數據庫郵件記錄查看
SELECT * FROM msdb.dbo.sysmail_event_log;
日志記錄管理
設置最大錯誤日志文件數
1:在對象資源管理器中,連接到 SQL Server 數據庫引擎實例,再展開該實例。
2:在”管理“選項,選擇”SQL SERVER日志”,單擊右鍵選擇配置。 順便說一下,很多網上資料說,SQL SERVER默認保留前6個日志文件,但是我查看了SQL SERVER 2005和SQL SERVER 2008,都是默認保留30個,有時候需要自己去驗證、實驗,不要人人亦雲。估計這個說法是SQL SERVER 2000時的配置了。
當然,你也可以用命令設置:
USE [master]
GO
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 10
GO
設置錯誤日志文件存放目錄
1:在對象資源管理器中,連接到 SQL Server 數據庫引擎實例,再展開該實例。
2:展開“SQL SERVER”代理。
3:右鍵單擊”錯誤日志“,然后選擇配置選項,如下所示:
4:在”錯誤日志文件“選項中,輸入新的路徑和文件名,或使用瀏覽(...)按鈕進行查找。重新啟動SQL SERVER代理服務后,SQL SERVER代理才寫入到新的日志文件。
設置作業歷史記錄日志
- 在對象資源管理器中,連接到 SQL Server 數據庫引擎 實例,再展開該實例。
- 右鍵單擊“SQL Server 代理”,再單擊“屬性”。
- 在“SQL Server 代理屬性”對話框中,選擇“歷史記錄”頁。
- 從下列選項中選擇:
為什么錯誤日志文件暴增?
這里我說的不僅僅指某個錯誤日志記錄文件暴增,也指目錄Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG所占空間暴增,如果你平時都不關注這些錯誤日志,也從不維護錯誤日志記錄文件,那么很有可能它所占的空間非常大,大到讓你吃驚的地步。幾十G的我也見過,那么具體原因可能有以下種(如果大家還碰到過其它情況,歡迎補充):
1:SQL 內部錯誤的時候會產生非常多的DUMP文件,如下所示
2:高可用的數據庫服務器可能很少停機,而你又沒有定期清理、清空這些錯誤日志信息,那么ERRORLOG.n/SQLAGENT.n文件增長會非常大。這樣對於DBA使用錯誤日志查找信息就會比較困難,而且日志大了加載、寫入以后性能也會受到影響。
3:其實還有一個情況,如果你數據庫IP地址曝露在外網時,會遭到大量嘗試登錄sa的攻擊,也會產生大量的審核失敗日志信息。
4:就是一些SQL SERVER PROFILE文件沒有刪除,當然,這個本質跟日志文件暴增沒啥關系,但是跟LOG文件夾的大小有些關系。
如何清理錯誤日志:
對於SQL SERVER日志、SQL SERVER AGENT日志記錄,微軟提供了一個存儲過程sp_cycle_errorlog可以實現日志的循環。 這個存儲過程的作用是關閉當前的錯誤日志文件,並循環錯誤日志擴展編號(就像重新啟動服務器)。每次啟動SQL Server 時,都會將當前錯誤日志重命名為errorlog.1;errorlog.1 變為errorlog.2,errorlog.2 變為errorlog.3,依次類推。最后一個errorlog.n將會被刪除。sp_cycle_errorlog 可使您循環訪問錯誤日志文件,而不必停止和啟動服務器。
另外:日志過大說明你沒有截斷錯誤日志,錯誤日志是可以截斷的,進入你的數據庫輸入DBCC ERRORLOG
每執行一次,當前的錯誤日志退出,讓后建立新的錯誤日志,你只能刪除 ERRORLOGn的錯誤日志沒有號碼的是正在使用的日志,刪除會報錯,如果它比較大,就DBCC ERRORLOG,而后他會變成ERRORLOG+編號,你就可以刪除了,另外建議你把這些ERRORLOG 放到其他盤符,比較好管理。
對於 Windows應用程序日志,一般都有默認的大小設置,以及按需要覆蓋。這些配置一般也是最優的配置。所以這塊除非你有特殊需求,否則不用你操心。
對於郵件日志記錄,存儲過程sysmail_delete_log_sp提供從數據庫郵件日志中刪除事件。刪除日志中的所有事件或刪除符合某一日期或類型條件的那些事件 sysmail_delete_log_sp [ [ @logged_before = ] 'logged_before' ] [, [ @event_type = ] 'event_type' ] |
刪除參數指定的所有 SQL Server 代理作業步驟日志。使用此存儲過程可維護 msdb 數據庫中的 sysjobstepslogs 表。
sp_delete_jobsteplog { [ @job_id = ] 'job_id' | [ @job_name = ] 'job_name' }
[ , [ @step_id = ] step_id | [ @step_name = ] 'step_name' ]
[ , [ @older_than = ] 'date' ]
[ , [ @larger_than = ] 'size_in_bytes' ]
刪除作業的歷史記錄
刪除特定作業YourSQLDba_LogBackups的歷史記錄。
USE msdb ;
GO
EXEC dbo.sp_purge_jobhistory
@job_name = N'YourSQLDba_LogBackups' ;
GO
以下示例將不帶參數執行此過程以刪除所有的歷史記錄。
USE msdb ;
GO
EXEC dbo.sp_purge_jobhistory ;
GO
刪除參數指定的所有 SQL Server 代理作業步驟日志。使用此存儲過程可維護 msdb 數據庫中的 sysjobstepslogs 表。如果你想好好維護日志記錄,那么你可以整合上面的思想方法到一個存儲過程,然后配置一個作業來定期清理日志記錄,接下來我們看看YourSQLDba的方法吧
- USE [YourSQLDba]
- GO
- /****** Object: StoredProcedure [yMaint].[LogCleanup] Script Date: 05/28/2013 18:36:21 ******/
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- -----------------------------------------------------------------------------
- -- yMaint.LogCleanup (for entries older than 30 days)
- -- Mail logs
- -- Backup history logs
- -- Job history
- -- Cycle SQL Server error log
- -----------------------------------------------------------------------------
- create proc [yMaint].[LogCleanup]
- @jobNo Int
- as
- Begin
- declare @d nvarchar(8)
- declare @lockResult int
- declare @sql nvarchar(max)
- Begin try
- exec yMaint.LockMaintDb@jobNo=@jobNo, @lockType='C', @DbName = 'LogCleanUpStep', @Result = @lockResult output
- If @lockResult > 0
- Return;
- Set @sql = 'Exec msdb.dbo.sysmail_delete_log_sp @logged_before = "<d>";'
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Cleanup log entries older than 30 days, begins with mail'
- , @sql = @sql
- , @JobNo = @JobNo
- Set @sql = 'EXECUTE msdb.dbo.sysmail_delete_mailitems_sp @sent_before = "<d>";'
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Cleanup log entries older than 30 days, for mailitems'
- , @sql = @sql
- , @JobNo = @JobNo
- -- clean backup history
- Set @sql = 'exec Msdb.dbo.sp_delete_backuphistory @oldest_date = "<d>" '
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Cleanup log entries older than 30 days, for backup history'
- , @sql = @sql
- , @JobNo = @JobNo
- -- clean sql agent job history
- Set @sql = 'EXECUTE Msdb.dbo.sp_purge_jobhistory @oldest_date = "<d>"'
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Cleanup log entries older than 30 days, for job history'
- , @sql = @sql
- , @JobNo = @JobNo
- -- clean job maintenance job history (SQL Server own maintenance)
- Set @sql = 'EXECUTE Msdb.dbo.sp_maintplan_delete_log null,null,"<d>"'
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Cleanup log entries older than 30 days, for SQL Server job maintenace plans'
- , @sql = @sql
- , @JobNo = @JobNo
- -- archive current log, and start a new one
- Set @sql = 'Execute sp_cycle_errorlog'
- Set @sql = replace(@sql, '<d>', convert(nvarchar(8), dateadd(dd, -30, getdate()), 112))
- Set @sql = replace(@sql, '"', '''')
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @info = 'Recycle Sql Server error log, start a new one'
- , @sql = @sql
- , @JobNo = @JobNo
- Delete H
- From
- (
- Select distinct JobNo --
- From Maint.JobHistory
- Where JobStart < dateadd(dd, -30, getdate())
- ) as T
- join
- Maint.JobHistory H
- On H.JobNo = T.JobNo
- End try
- Begin catch
- exec yMaint.UnLockMaintDb@jobNo=@jobNo, @DbName = 'LogCleanUpStep'
- Exec yExecNLog.LogAndOrExec
- @context = 'yMaint.LogCleanup'
- , @Info = 'Error caught in proc'
- , @err = '?'
- , @JobNo = @JobNo
- End Catch
- exec yMaint.UnLockMaintDb@jobNo=@jobNo, @DbName = 'LogCleanUpStep'
- End -- yMaint.LogCleanup
- GO
參考資料:
http://msdn.microsoft.com/zh-cn/library/ms187885(v=sql.105).aspx
http://www.jb51.net/article/26988.htm
http://groundsel.itpub.net/post/1284/494264
http://www.canway.net/Lists/CanwayOriginalArticels/DispForm.aspx?ID=291
http://technet.microsoft.com/zh-cn/library/ms191202(v=SQL.105).aspx
http://support.microsoft.com/kb/157804/zh-cn
http://support.microsoft.com/kb/115519/zh-cn
http://blog.csdn.net/smithliu328/article/details/7843724
http://blog.csdn.net/claro/article/details/5660524
http://www.cnblogs.com/lyhabc/archive/2013/02/12/2910623.html