【1】 错误日志简介
【1.1】. Windows事件日志与SQL Server 错误日志
【1.2】. 如何理解SQL Server的Error message?
【1.3】. SQL Server 错误日志包含哪些信息
【1.4】. SQL Server 错误日志存放在哪里
【1.5】. SQL Server 错误日志目录下的其他文件
【2】错误日志维护
【2.0】维护SQL汇总
-- 查看错误日志URL路径 SELECT SERVERPROPERTY('ErrorLogFileName') -- 查看所有错误日志文件名即文件大小 EXEC master..xp_enumerrorlogs -- 查看错误日志文件具体内容 exec dbo.xp_readerrorlog 文件编号,文件类型,N'检索string1',N'and检索string2',开始时间,结束时间,N'结果排序desc' -- 轮转错误日志 与 代理Agent日志 EXEC master..sp_cycle_errorlog; --DBCC ERRORLOG 亦可 EXEC msdb.dbo.sp_cycle_agent_errorlog;--SQL Agent 服务需在启动状态下才有效
【2.1】错误日志文件个数
-- 查看所有错误日志文件名即文件大小 EXEC master..xp_enumerrorlogs
查看最大错误日志个数
通过T-SQL查看最大错误日志个数
USE [master] GO EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'SoftwareMicrosoftMSSQLServerMSSQLServer', N'NumErrorLogs', REG_DWORD, 50 GO --Check current errorlog amout USE [master] GO DECLARE @i int EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SoftwareMicrosoftMSSQLServerMSSQLServer', N'NumErrorLogs', @i OUTPUT SELECT @i
【2.2】SQL Server Agent错误日志
如何查看?Agent错误日志位置?
【2.3】错误日志归档
(1) 为什么要归档错误日志?
假设SQL Server实例从来没被重启过,也没有手动归档过错误日志,那么错误日志文件可能会变得很大,尤其是有内部错误时会DUMP很多信息,一来占空间,更重要的是:想要查看分析也会不太方便。
SQL Server/SQL Server Agent 错误日志有2种归档方式,即:创建一个新的日志文件,并将最老的日志删除。
(1) 自动归档:在SQL Server/ SQL Server Agent服务重启时;
(2) 手动归档:定期运行如下系统存储过程
EXEC master..sp_cycle_errorlog; --DBCC ERRORLOG 亦可 EXEC msdb.dbo.sp_cycle_agent_errorlog;--SQL Agent 服务需在启动状态下才有效
【2.4】错误日志的查看 与告警
错误日志以文本方式记录,记事本就可以查看,如果错误日志很大,可以选择Gvim/UltraEdit /DOS窗口type errorlog等,这些方式都会“分页”加载,不会卡住。
(1)错误日志查看
SQL Server提供了以下2种方式查看:
(1) 日志查看器 (log viewer),除了可以查看SQL Server 与SQL Server Agent的错误日志,还可以查看操作系统日志、数据库邮件日志。不过当日志文件太大时,图形界面非常慢;
(2) 未记载的扩展存储过程xp_readerrorlog,另外还有一个名为sp_readerrorlog的存储过程,它是对xp_readerrorlog的简单封装,并且只提供了4个参数,直接使用xp_readerrorlog即可:
在SQL Server 2005及以后版本里,支持多达7个参数,说明如下:
exec dbo.xp_readerrorlog 1,1,N'string1',N'string2',null,null,N'desc'
参数1.日志文件号: 0 = 当前, 1 = Archive #1, 2 = Archive #2, etc...
参数2.日志文件类型: 1 or NULL = SQL Server 错误日志, 2 = SQL Agent 错误日志
参数3.检索字符串1: 用来检索的字符串
参数4.检索字符串2: 在检索字符串1的返回结果之上再做过滤
参数5.日志开始时间
参数6.日志结束时间
参数7.结果排序: N'asc' = 升序, N'desc' = 降序
--sql server 2005 read error log 包含某内容的信息 if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog select * from #tmp_error_log where info like '%18456%'
(2)获取错误日志告警信息
可以通过对某些关键字做检索:错误(Error),警告(Warn),失败(Fail),停止(Stop),而进行告警 (database mail),以下脚本检索24小时内的错误日志:
--检索24小时内出现的错误日志
declare@start_time datetime,@end_time datetime set @start_time = CONVERT(char(10),GETDATE() - 1,120) set @end_time = GETDATE() if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog 0,1,NULL,NULL,@start_time,@end_time,N'desc' select COUNT(1) as num, MAX(logdate) as logdate,info from #tmp_error_log where (info like '%ERROR%' or info like '%WARN%' or info like '%FAIL%' or info like '%STOP%') and info not like '%CHECKDB%' and info not like '%Registry startup parameters%' and info not like '%Logging SQL Server messages in file%' and info not like '%previous log for older entries%' group by info
当然,还可以添加更多关键字:kill, dead, victim, cannot, could, not, terminate, bypass, roll, truncate, upgrade, recover, IO requests taking longer than,但当中有个例外,就是DBCC CHECKDB,它的运行结果中必然包括Error字样,如下:
DBCC CHECKDB (xxxx) executed by sqladmin found 0 errors and repaired 0 errors.
所以对0 errors要跳过,只有在发现非0 errors时才作告警。
(3)小结
如果没有监控工具,那么可选择扩展存储过程,结合数据库邮件的方式,作自动检查及告警,并定期归档错误日志文件以避免文件太大。大致步骤如下 :
(1) 部署数据库邮件;
(2) 部署作业:定时检查日志文件,如检索到关键字,发邮件告警;
(3) 部署作业:定期归档错误日志,可与步骤(2) 合并作为两个step放在一个作业里。
【3】根据警报监控错误日志
该部分转自:https://www.cnblogs.com/kerrycode/p/4056491.html
SQL Server的错误消息(Error Message)按照消息的严重级别一共划分25个等级,级别越高,表示严重性也越高。但是如果你统计sys.messages,你会发现,实际上只有16(SQL SERVER 2008/2012)或17个(SQL SERVER 2005)个级别。猜测应该是一些留作扩展用,一些留作用户自定义错误消息的级别。
sys.messages中有个字段is_event_logged,取值为1时表示出现错误时将消息记入事件日志。 对于 message_id 中的所有消息语言,此参数都是相同的。所以也就是说有些错误信息(Error Message)会写入事件日志,有些就不会写入错误日志。因此监控错误日志时,我们只能监控那些写入错误日志的错误信息。一般而言,我们应该监控严重级别在16~25之间的错误信息,另外严重级别14的也应该监控(主要是Error: 18456, Severity: 14)。
监控错误日志有很多方式,下面介绍一种非常简单、有效的监控错误日志的方法.我们可以通过sp_add_alert创建一个警报(Alerts),如下所示,我们创建一个名称为SQL Server Severity Event 14的警报(配置前需要配置邮件、ProfileName,Operators,下面脚本也要根据具体情况调整)。关于创建警报的具体信息,可以参考http://msdn.microsoft.com/zh-cn/library/ms189531.aspx
USE [msdb]
GO
IF NOT EXISTS(SELECT 1 FROM msdb.dbo.syscategories WHERE NAME='DBA_MONITORING' AND category_class=2)
BEGIN
EXEC msdb.dbo.sp_add_category
@class=N'ALERT',
@type=N'NONE',
@name=N'DBA_MONITORING' ;
END
GO
IF EXISTS (SELECT name FROM msdb.dbo.sysalerts WHERE name = N'SQL Severity Event 14')
EXEC msdb.dbo.sp_delete_alert @name=N'SQL Server Severity Event 14'
GO
USE [msdb]
GO
EXEC msdb.dbo.sp_add_alert @name=N'SQL Server Severity Event 14',
@message_id=0,
@severity=14,
@enabled=1,
@delay_between_responses=60,
@include_event_description_in=1,
@category_name=N'DBA_MONITORING',
@job_id=N'00000000-0000-0000-0000-000000000000'
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N'SQL Server Severity Event 14', @operator_name=N'YourSQLDba_Operator', @notification_method = 1
GO
如下所示,在UAT服务器,我故意用dw账号错误密码登录数据库,一分钟后,我立马回收到一封告警邮件
DATE/TIME: ; 2014/10/28 9:21:42
DESCRIPTION: ; Login failed for user 'dw'. Reason: Password did not match that for the login provided. [CLIENT: 192.xxx.xxx.xxx]
COMMENT: ; (None)
JOB ;RUN: (None)
SQL Server 错误日志
Windows事件日志
我们依次建立16-25级别的告警来监控数据库错误日志的错误信息。如下所示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
执行完上面脚本后,就会建立下面几个告警。当数据库的错误日志出现这些级别的错误信息时,就会收到告警邮件。相当的方便、简单、高效。
【4】根据T-SQL监控错误日志
--检索24小时内出现的错误日志
declare@start_time datetime,@end_time datetime set @start_time = CONVERT(char(10),GETDATE() - 1,120) set @end_time = GETDATE() if OBJECT_ID('tempdb..#tmp_error_log') is not null drop table #tmp_error_log create table #tmp_error_log ( logdate datetime, processinfo varchar(100), info varchar(8000) ) insert into #tmp_error_log exec dbo.xp_readerrorlog 0,1,NULL,NULL,@start_time,@end_time,N'desc' select COUNT(1) as num, MAX(logdate) as logdate,info from #tmp_error_log where (info like '%ERROR%' or info like '%WARN%' or info like '%FAIL%' or info like '%STOP%') and info not like '%CHECKDB%' and info not like '%Registry startup parameters%' and info not like '%Logging SQL Server messages in file%' and info not like '%previous log for older entries%' group by info