Quantcast
Channel: CodeSection,代码区,SQL Server(mssql)数据库 技术分享 - CodeSec
Viewing all articles
Browse latest Browse all 3160

Simple DBCC CHECKDB process to report on database corruption for all SQL Server ...

$
0
0

By: Alejandro Cobar || Related Tips:More > Database Consistency Checks DBCCs

Problem

As DBAs, we all know how important it is to check all of the SQL Server databases under our care for potential corruption issues. However, to accomplish that, we might not have the time to do any of the following:

Setup a maintenance plan across all X SQL Server instances under our support. Setup a custom job to run a consistency check across all databases in all X SQL Server instances (which this tip particularly aims to address). Build a PowerShell solution (if you want to get a bit fancy here).

Regardless of the way you choose to go, you have to consider other important factors as well:

Environment type (production / non-production) When is the maintenance window? How much time do you have during the maintenance window? Solution

I have come up with a custom *simple solution that lets you check the consistency of all the databases under your care, save only the end result (without that much overhead) with a few additional important values, while having to modify only a couple of things that are very specific to your use case.

*By simple I’m not implying that the amount of code used is small, but instead simple in terms of what it accomplishes in the end.

SQL Server DBCC CHECKDB Script as a whole

The entire script consists of 3 sections:

Creation of the table to store the final results. Creation of the custom stored procedure. Creation of the job to automate it.

You can find complete "plug-and-play" script , in case you want to test it right away, attached within this tip.

I will be detailing each section in the next sub-sections.

Creation of the SQL Server DBCC CheckDB table

This will be used to store the result of the execution of the DBCC CHECKDB statement against each database.

You can use a different database, I used the master just as an example. Here’s the description for the fields that might not be so obvious at a first glance: [checkdb_type] -> ‘FULL’ or ‘PHYSICAL ONLY’ (will explain later the reason for these 2 values in the Stored Procedure). [completion_time] in seconds because it is very useful to know how long a CHECKDB against each database took. You can even use this information to plan your checks in a more efficient way because you can get an average of the time it takes to complete for each database. [last_good_dbcc] tells you when was the last time a successful CHECKDB took place, something very important to know so that later on you can prioritize those that haven’t had a check in a while (for whatever reason). USE [master]
GO
CREATE TABLE [dbo].[CheckDB](
[instance] [varchar](255) NOT NULL,
[database] [varchar](255) NOT NULL,
[size] [int] NOT NULL,
[result] [varchar](max) NULL,
[checkdb_type] [varchar](255) NULL,
[data_collection_timestamp] [smalldatetime] NULL,
[completion_time] [int] NULL,
[last_good_dbcc] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO Creation of the SQL Server DBCC CheckDB Stored Procedure

At a first glance the stored procedure might seem quite big, but it is only because it contains some validations and considerations that you probably won’t find in similar versions.

Here are the most important points to note:

From the very start, you can see that the stored procedure can accept 2 parameters: @dbSizeThreshold : by default, it is set at 512,000 MB (500GB) and it is used to determine if the CHECKDB will use the "PHYSICAL_ONLY" option for databases larger than 500GB (you can set it to whatever you think fits your case). Let’s keep in mind that your maintenance window might not be enough to accommodate a full CHECKDB for a big database (or databases), and a run with "PHYSICAL_ONLY" option might represent at least a small victory for you. @force : this parameter is designed to override the @dbSizeThreshold behavior. For instance, you might have an instance with only 1 big database (bigger than the threshold value) but you feel confident enough that a full CHECKDB can be successful within your maintenance window, so you go for it and set it to 1 to proceed with a full run of the CHECKDB. This stored procedure takes into account the SQL Server version where it’s being executed, so you don’t have to worry to deploy a different version depending on how old yours is. Since we are executing the CHECKDB command WITH TABLERESULTS, there is a slight variation in the output obtained starting from SQL Server 2012 (since it adds more fields to the mix), but the stored procedure creates the right table for you. You might notice that I use a cursor to traverse the database list and run the CHECKDB against each one of them. I know that cursors are somewhat of a "taboo" thing within our profession, for their low performance, but its purpose is purely for control. First I populate the table "master.dbo.CheckDB" with the databases to be checked by the stored procedure. As each one is checked successfully, then the respective record is updated in the table. By doing this, you know if a particular database was not a part of the process. Server might have been patched and rebooted while the execution was taking place. Server was unexpectedly shutdown while the execution was taking place. The SQL Server instance was restarted while the execution was taking place. When CHECKDB is executed against the master database, the output for the ResourceDB is also obtained, so I also make sure to capture that one as well. USE [master]
GO
/****** Object: StoredProcedure [dbo].[Simple_CHECKDB] Script Date: 8/30/2018 3:45:26 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Alejandro Cobar
-- Create date: 8/22/2018
-- Description: Runs DBCC CHECKDB ON each database and stores the output message
-- =============================================
CREATE PROCEDURE [dbo].[Simple_CHECKDB]
@dbSizeThreshold INT = 512000,
@force INT = 0
AS
BEGIN
SET NOCOUNT ON;
-- Temporal table to obtain the "Last Known Good DBCC CHECKDB" execution for each database
IF NOT OBJECT_ID('tempdb..#DBInfo') IS NULL
DROP TABLE #DBInfo;
CREATE TABLE #DBInfo
([ParentObject] VARCHAR(255)
,[Object] VARCHAR(255)
,[Field] VARCHAR(255)
,[Value] VARCHAR(255)
)
-- Depending on the SQL Server version, the respective temporal table will be created to store the CHECKDB results
DECLARE @version INT;
SELECT @version = RIGHT(LEFT(@@VERSION,25),4);
--Starting from SQL Server 2012, new fields were introduced to the output of DBCC CHECKDB WITH TABLERESULTS
IF NOT OBJECT_ID('tempdb..#CheckDB_old') IS NULL
DROP TABLE #CheckDB_old;
IF NOT OBJECT_ID('tempdb..#CheckDB_new') IS NULL
DROP TABLE #CheckDB_new;
IF @version >= 2012
CREATE TABLE #CheckDB_new
([Error] INT

Viewing all articles
Browse latest Browse all 3160

Trending Articles