|
3173 | 3173 | AND cTotal.counter_name = N'Total Server Memory (KB) ' |
3174 | 3174 | WHERE cFree.object_name LIKE N'%Memory Manager%' |
3175 | 3175 | AND cFree.counter_name = N'Free Memory (KB) ' |
3176 | | - AND CAST(cTotal.cntr_value AS BIGINT) > 4000 |
| 3176 | + AND CAST(cTotal.cntr_value AS BIGINT) > 20480000000 |
3177 | 3177 | AND CAST(cTotal.cntr_value AS BIGINT) * .3 <= CAST(cFree.cntr_value AS BIGINT) |
3178 | 3178 | AND CAST(SERVERPROPERTY('edition') AS VARCHAR(100)) NOT LIKE '%Standard%' |
3179 | 3179 |
|
@@ -3835,6 +3835,251 @@ IF @ProductVersionMajor >= 10 |
3835 | 3835 |
|
3836 | 3836 | END; |
3837 | 3837 |
|
| 3838 | +/*Begin: checking default trace for odd DBCC activity*/ |
| 3839 | + |
| 3840 | + --Grab relevant event data |
| 3841 | + SELECT UPPER( |
| 3842 | + REPLACE( |
| 3843 | + SUBSTRING(CONVERT(NVARCHAR(MAX), t.TextData), 0, |
| 3844 | + ISNULL( |
| 3845 | + NULLIF( |
| 3846 | + CHARINDEX('(', CONVERT(NVARCHAR(MAX), t.TextData)), |
| 3847 | + 0), |
| 3848 | + LEN(CONVERT(NVARCHAR(MAX), t.TextData)) + 1 )) --This replaces everything up to an open paren, if one exists. |
| 3849 | + , SUBSTRING(CONVERT(NVARCHAR(MAX), t.TextData), |
| 3850 | + ISNULL( |
| 3851 | + NULLIF( |
| 3852 | + CHARINDEX(' WITH ',CONVERT(NVARCHAR(MAX), t.TextData)) |
| 3853 | + , 0), |
| 3854 | + LEN(CONVERT(NVARCHAR(MAX), t.TextData)) + 1), |
| 3855 | + LEN(CONVERT(NVARCHAR(MAX), t.TextData)) + 1 ) |
| 3856 | + , '') --This replaces any optional WITH clause to a DBCC command, like tableresults. |
| 3857 | + ) AS [dbcc_event_trunc_upper], |
| 3858 | + UPPER( |
| 3859 | + REPLACE( |
| 3860 | + CONVERT(NVARCHAR(MAX), t.TextData), SUBSTRING(CONVERT(NVARCHAR(MAX), t.TextData), |
| 3861 | + ISNULL( |
| 3862 | + NULLIF( |
| 3863 | + CHARINDEX(' WITH ',CONVERT(NVARCHAR(MAX), t.TextData)) |
| 3864 | + , 0), |
| 3865 | + LEN(CONVERT(NVARCHAR(MAX), t.TextData)) + 1), |
| 3866 | + LEN(CONVERT(NVARCHAR(MAX), t.TextData)) + 1 ), '')) AS [dbcc_event_full_upper], |
| 3867 | + MIN(t.StartTime) OVER (PARTITION BY CONVERT(NVARCHAR(128), t.TextData)) AS min_start_time, |
| 3868 | + MAX(t.StartTime) OVER (PARTITION BY CONVERT(NVARCHAR(128), t.TextData)) AS max_start_time, |
| 3869 | + t.NTUserName AS [nt_user_name], |
| 3870 | + t.NTDomainName AS [nt_domain_name], |
| 3871 | + t.HostName AS [host_name], |
| 3872 | + t.ApplicationName AS [application_name], |
| 3873 | + t.LoginName [login_name], |
| 3874 | + t.DBUserName AS [db_user_name] |
| 3875 | + INTO #dbcc_events_from_trace |
| 3876 | + FROM sys.fn_trace_gettable( @base_tracefilename, DEFAULT) AS t |
| 3877 | + WHERE t.EventClass = 116 |
| 3878 | + OPTION(RECOMPILE); |
| 3879 | + |
| 3880 | + /*Overall count of DBCC events excluding silly stuff*/ |
| 3881 | + IF NOT EXISTS ( SELECT 1 |
| 3882 | + FROM #SkipChecks |
| 3883 | + WHERE DatabaseName IS NULL AND CheckID = 199 ) |
| 3884 | + BEGIN |
| 3885 | + INSERT INTO [#BlitzResults] |
| 3886 | + ( [CheckID] , |
| 3887 | + [Priority] , |
| 3888 | + [FindingsGroup] , |
| 3889 | + [Finding] , |
| 3890 | + [URL] , |
| 3891 | + [Details] ) |
| 3892 | + SELECT 199 AS CheckID , |
| 3893 | + 50 AS Priority , |
| 3894 | + 'DBCC Events' AS FindingsGroup , |
| 3895 | + 'Overall Events' AS Finding , |
| 3896 | + '' AS URL , |
| 3897 | + CAST(COUNT(*) AS NVARCHAR(100)) + ' DBCC events have taken place between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 3898 | + '. This does not include CHECKDB and other usually benign DBCC events.' |
| 3899 | + AS Details |
| 3900 | + FROM #dbcc_events_from_trace d |
| 3901 | + WHERE d.[dbcc_event_trunc_upper] NOT IN ( |
| 3902 | + N'DBCC CHECKCB', N' DBCC CHECKALLOC' , N'DBCC CHECKTABLE', N'DBCC CHECKCATALOG', N'DBCC CHECKFILEGROUP', --CHECKDB related |
| 3903 | + N'DBCC TRACEON', N'DBCC TRACEOFF', N'DBCC DBINFO', N'DBCC LOGINFO', N'DBCC INPUTBUFFER', N'DBCC TRACESTATUS', --Usually monitoring tool related |
| 3904 | + N'DBCC CHECKIDENT', N'DBCC SHOW_STATISTICS', N'DBCC CHECKCONSTRAINTS', --Probably rational |
| 3905 | + N'DBCC CLEANTABLE', N'DBCC CHECKPRIMARYFILE', N'DBCC OPENTRAN', 'DBCC SHOWFILESTATS' --Weird but okay |
| 3906 | + ) |
| 3907 | + AND d.dbcc_event_full_upper NOT IN('DBCC SQLPERF(NETSTATS)', 'DBCC SQLPERF(LOGSPACE)') |
| 3908 | + HAVING COUNT(*) > 0 |
| 3909 | + |
| 3910 | + END |
| 3911 | + |
| 3912 | + /*Check for someone running drop clean buffers*/ |
| 3913 | + IF NOT EXISTS ( SELECT 1 |
| 3914 | + FROM #SkipChecks |
| 3915 | + WHERE DatabaseName IS NULL AND CheckID = 200 ) |
| 3916 | + BEGIN |
| 3917 | + INSERT INTO [#BlitzResults] |
| 3918 | + ( [CheckID] , |
| 3919 | + [Priority] , |
| 3920 | + [FindingsGroup] , |
| 3921 | + [Finding] , |
| 3922 | + [URL] , |
| 3923 | + [Details] ) |
| 3924 | + SELECT 200 AS CheckID , |
| 3925 | + 50 AS Priority , |
| 3926 | + 'DBCC Events' AS FindingsGroup , |
| 3927 | + 'DBCC DROPCLEANBUFFERS' AS Finding , |
| 3928 | + '' AS URL , |
| 3929 | + 'The user ' + COALESCE(d.nt_user_name, d.login_name) + ' has run DBCC DROPCLEANBUFFERS ' + CAST(COUNT(*) AS NVARCHAR(100)) + ' times between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 3930 | + '. If this is a production box, know that you''re clearing all data out of memory when this happens. What kind of monster would do that?' |
| 3931 | + AS Details |
| 3932 | + FROM #dbcc_events_from_trace d |
| 3933 | + WHERE d.dbcc_event_full_upper = N'DBCC DROPCLEANBUFFERS' |
| 3934 | + GROUP BY COALESCE(d.nt_user_name, d.login_name) |
| 3935 | + HAVING COUNT(*) > 0 |
| 3936 | + |
| 3937 | + END |
| 3938 | + |
| 3939 | + /*Check for someone running free proc cache*/ |
| 3940 | + IF NOT EXISTS ( SELECT 1 |
| 3941 | + FROM #SkipChecks |
| 3942 | + WHERE DatabaseName IS NULL AND CheckID = 201 ) |
| 3943 | + BEGIN |
| 3944 | + INSERT INTO [#BlitzResults] |
| 3945 | + ( [CheckID] , |
| 3946 | + [Priority] , |
| 3947 | + [FindingsGroup] , |
| 3948 | + [Finding] , |
| 3949 | + [URL] , |
| 3950 | + [Details] ) |
| 3951 | + SELECT 201 AS CheckID , |
| 3952 | + 50 AS Priority , |
| 3953 | + 'DBCC Events' AS FindingsGroup , |
| 3954 | + 'DBCC FREEPROCCACHE' AS Finding , |
| 3955 | + '' AS URL , |
| 3956 | + 'The user ' + COALESCE(d.nt_user_name, d.login_name) + ' has run DBCC FREEPROCCACHE ' + CAST(COUNT(*) AS NVARCHAR(100)) + ' times between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 3957 | + '. This has bad idea jeans written all over its butt, like most other bad idea jeans.' |
| 3958 | + AS Details |
| 3959 | + FROM #dbcc_events_from_trace d |
| 3960 | + WHERE d.dbcc_event_full_upper = N'DBCC FREEPROCCACHE' |
| 3961 | + GROUP BY COALESCE(d.nt_user_name, d.login_name) |
| 3962 | + HAVING COUNT(*) > 0 |
| 3963 | + |
| 3964 | + END |
| 3965 | + |
| 3966 | + /*Check for someone clearing wait stats*/ |
| 3967 | + IF NOT EXISTS ( SELECT 1 |
| 3968 | + FROM #SkipChecks |
| 3969 | + WHERE DatabaseName IS NULL AND CheckID = 202 ) |
| 3970 | + BEGIN |
| 3971 | + INSERT INTO [#BlitzResults] |
| 3972 | + ( [CheckID] , |
| 3973 | + [Priority] , |
| 3974 | + [FindingsGroup] , |
| 3975 | + [Finding] , |
| 3976 | + [URL] , |
| 3977 | + [Details] ) |
| 3978 | + SELECT 202 AS CheckID , |
| 3979 | + 50 AS Priority , |
| 3980 | + 'DBCC Events' AS FindingsGroup , |
| 3981 | + 'DBCC SQLPERF(''SYS.DM_OS_WAIT_STATS'',CLEAR)' AS Finding , |
| 3982 | + '' AS URL , |
| 3983 | + 'The user ' + COALESCE(d.nt_user_name, d.login_name) + ' has run DBCC SQLPERF(''SYS.DM_OS_WAIT_STATS'',CLEAR) ' + CAST(COUNT(*) AS NVARCHAR(100)) + ' times between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 3984 | + '. Why are you clearing wait stats? What are you hiding?' |
| 3985 | + AS Details |
| 3986 | + FROM #dbcc_events_from_trace d |
| 3987 | + WHERE d.dbcc_event_full_upper = N'DBCC SQLPERF(''SYS.DM_OS_WAIT_STATS'',CLEAR)' |
| 3988 | + GROUP BY COALESCE(d.nt_user_name, d.login_name) |
| 3989 | + HAVING COUNT(*) > 0 |
| 3990 | + |
| 3991 | + END |
| 3992 | + |
| 3993 | + /*Check for someone writing to pages. Yeah, right?*/ |
| 3994 | + IF NOT EXISTS ( SELECT 1 |
| 3995 | + FROM #SkipChecks |
| 3996 | + WHERE DatabaseName IS NULL AND CheckID = 203 ) |
| 3997 | + BEGIN |
| 3998 | + INSERT INTO [#BlitzResults] |
| 3999 | + ( [CheckID] , |
| 4000 | + [Priority] , |
| 4001 | + [FindingsGroup] , |
| 4002 | + [Finding] , |
| 4003 | + [URL] , |
| 4004 | + [Details] ) |
| 4005 | + SELECT 203 AS CheckID , |
| 4006 | + 50 AS Priority , |
| 4007 | + 'DBCC Events' AS FindingsGroup , |
| 4008 | + 'DBCC WRITEPAGE' AS Finding , |
| 4009 | + '' AS URL , |
| 4010 | + 'The user ' + COALESCE(d.nt_user_name, d.login_name) + ' has run DBCC WRITEPAGE ' + CAST(COUNT(*) AS NVARCHAR(100)) + ' times between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 4011 | + '. So, uh, are they trying to fix corruption, or cause corruption?' |
| 4012 | + AS Details |
| 4013 | + FROM #dbcc_events_from_trace d |
| 4014 | + WHERE d.dbcc_event_trunc_upper = N'DBCC WRITEPAGE' |
| 4015 | + GROUP BY COALESCE(d.nt_user_name, d.login_name) |
| 4016 | + HAVING COUNT(*) > 0 |
| 4017 | + |
| 4018 | + END |
| 4019 | + |
| 4020 | + IF NOT EXISTS ( SELECT 1 |
| 4021 | + FROM #SkipChecks |
| 4022 | + WHERE DatabaseName IS NULL AND CheckID = 204 ) |
| 4023 | + BEGIN |
| 4024 | + INSERT INTO [#BlitzResults] |
| 4025 | + ( [CheckID] , |
| 4026 | + [Priority] , |
| 4027 | + [FindingsGroup] , |
| 4028 | + [Finding] , |
| 4029 | + [URL] , |
| 4030 | + [Details] ) |
| 4031 | + |
| 4032 | + SELECT 204 AS CheckID , |
| 4033 | + 50 AS Priority , |
| 4034 | + 'DBCC Events' AS FindingsGroup , |
| 4035 | + 'DBCC SHRINK%' AS Finding , |
| 4036 | + '' AS URL , |
| 4037 | + 'The user ' + COALESCE(d.nt_user_name, d.login_name) + ' has run file shrinks ' + CAST(COUNT(*) AS NVARCHAR(100)) + ' times between ' + CONVERT(NVARCHAR(30), MIN(d.min_start_time)) + ' and ' + CONVERT(NVARCHAR(30), MAX(d.max_start_time)) + |
| 4038 | + '. So, uh, are they trying to fix corruption, or cause corruption?' |
| 4039 | + AS Details |
| 4040 | + FROM #dbcc_events_from_trace d |
| 4041 | + WHERE d.dbcc_event_trunc_upper LIKE N'DBCC SHRINK%' |
| 4042 | + GROUP BY COALESCE(d.nt_user_name, d.login_name) |
| 4043 | + HAVING COUNT(*) > 0 |
| 4044 | + |
| 4045 | + END |
| 4046 | + |
| 4047 | + |
| 4048 | +/*End: checking default trace for odd DBCC activity*/ |
| 4049 | + |
| 4050 | + /*Begin check for autoshrink events*/ |
| 4051 | + |
| 4052 | + IF NOT EXISTS ( SELECT 1 |
| 4053 | + FROM #SkipChecks |
| 4054 | + WHERE DatabaseName IS NULL AND CheckID = 205 ) |
| 4055 | + BEGIN |
| 4056 | + INSERT INTO [#BlitzResults] |
| 4057 | + ( [CheckID] , |
| 4058 | + [Priority] , |
| 4059 | + [FindingsGroup] , |
| 4060 | + [Finding] , |
| 4061 | + [URL] , |
| 4062 | + [Details] ) |
| 4063 | + |
| 4064 | + SELECT 205 AS CheckID , |
| 4065 | + 50 AS Priority , |
| 4066 | + 'Autoshrink events' AS FindingsGroup , |
| 4067 | + 'File shrinking' AS Finding , |
| 4068 | + '' AS URL , |
| 4069 | + N'The database ' + QUOTENAME(t.DatabaseName) + N' has had ' |
| 4070 | + + CONVERT(NVARCHAR(10), COUNT(*)) |
| 4071 | + + N' auto shrink events between ' |
| 4072 | + + CONVERT(NVARCHAR(30), MIN(t.StartTime)) + ' and ' + CONVERT(NVARCHAR(30), MAX(t.StartTime)) |
| 4073 | + + ' that lasted on average ' |
| 4074 | + + CONVERT(NVARCHAR(10), AVG(DATEDIFF(SECOND, t.StartTime, t.EndTime))) |
| 4075 | + + ' seconds.' AS Details |
| 4076 | + FROM sys.fn_trace_gettable( @base_tracefilename, DEFAULT) AS t |
| 4077 | + WHERE t.EventClass IN (94, 95) |
| 4078 | + GROUP BY t.DatabaseName |
| 4079 | + HAVING AVG(DATEDIFF(SECOND, t.StartTime, t.EndTime)) > 5 |
| 4080 | + |
| 4081 | + END |
| 4082 | + |
3838 | 4083 |
|
3839 | 4084 | IF @CheckUserDatabaseObjects = 1 |
3840 | 4085 | BEGIN |
|
0 commit comments