SQL Server: Set SSIS alert if group of database is getting over size
Scenario
This article is suitable for several scenarios, but let’s imagine a particular situation: you are a DBA with hundreds of databases to manage and several different servers (University, Big Company, Hospital, etc).
You need to keep the size of all your databases under control and in order to do this you run “on remote” different queries. This is error prone. Sometimes you forget to do run the process. Maybe you are on vacation or involved in early morning meetings. Whatever the reason, it is better to automate a process warning you about the status of your databases. SSIS and T-SQL are perfect for the task.
Steps
Create Table
Create a table Forum with the column Over90 in the DB Control (you can choose your favorite name/db)
Create a procedure in Master DB
USE [master] GO /****** Object: StoredProcedure [dbo].[ForumArticle] Script Date: 12/31/2014 09:38:19 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE procedure [dbo]. [ForumArticle] as SET NOCOUNT ON DECLARE @Kb float DECLARE @PageSize float DECLARE @SQL varchar( 2000) SELECT @Kb = 1024.0 SELECT @PageSize= v. low/ @Kb FROM master.. spt_values v WHERE v. number= 1 AND v.type='E' IF OBJECT_ID('tempdb.dbo.#FileSize') IS NOT NULL DROP TABLE #FileSize CREATE TABLE #FileSize DatabaseName sysname, FileName sysname, FileSize int, FileGroupName sysname, LogicalName sysname )
IF OBJECT_ID('tempdb.dbo.#FileStats') IS NOT NULL DROP TABLE #FileStats CREATE TABLE #FileStats FileID int, FileGroup int, TotalExtents int, UsedExtents int, LogicalName sysname, FileName nchar( 520) ) IF OBJECT_ID('tempdb.dbo.#LogSpace') IS NOT NULL DROP TABLE #LogSpace CREATE TABLE #LogSpace DatabaseName sysname, LogSize float, SpaceUsedPercent float, Status bit ) INSERT #LogSpace EXEC ('DBCC sqlperf(logspace)') DECLARE @DatabaseName sysname DECLARE cur_Databases CURSOR FAST_FORWARD FOR SELECT DatabaseName = [name] FROM dbo.sysdatabases ORDER BY DatabaseName OPEN cur_Databases FETCH NEXT FROM cur_Databases INTO @DatabaseName WHILE @@FETCH_STATUS = 0 BEGIN SET @SQL = ' USE [' + @DatabaseName + ']; DBCC showfilestats; INSERT #FileSize (DatabaseName, FileName, FileSize, FileGroupName, LogicalName) SELECT ''' + @DatabaseName + ''', filename, size, ISNULL(FILEGROUP_NAME(groupid),''LOG''), [name] FROM dbo.sysfiles sf; ' INSERT #FileStats EXECUTE ( @SQL) FETCH NEXT FROM cur_Databases INTO @DatabaseName END CLOSE cur_Databases DEALLOCATE cur_Databases declare @var as int SELECT @var=COUNT(*) FROM #FileSize fsi LEFT JOIN #FileStats fs ON fs.FileName = fsi.FileName LEFT JOIN #LogSpace ls ON ls. DatabaseName = fsi. DatabaseName WHERE CAST(ISNULL((( fsi. FileSize - UsedExtents* 8.0) / fsi. FileSize * 100.0), 100- ls. SpaceUsedPercent) as decimal( 15, 2)) < 10
update [Control] . dbo. Forum set over90= @var
GO |
You can even run this code in SSMS (without the where condition) in order to have the picture of your Instance situation but you can do a lot more using SSIS.
Package to build
Below the final package (but we are going to build it step by step):
SQL Task
We have got one Execute SQL task “Run the Procedure ForumArticle”, another Execute SQL task “Select the number of db over 90% of availability” and three different Send Mail Task.
For this purpose I chose as limit for my alert the 90% of availability.
[ CODE FROM THE PROCEDURE ]
WHERE CAST(ISNULL((( fsi. FileSize - UsedExtents* 8.0) / fsi. FileSize * 100.0), 100- ls. SpaceUsedPercent) as decimal( 15, 2)) < 10
It’s up to you to choose the range you want consider as alert. In our case the range is 90%.
Let’s start with SSIS.
SSIS
Step 1: New package
Let’s create a new package with Execute SQL task:
We need to set up the Connection and after this to write the TSQL statement
A simple exec forumarticle. (the scope is to update the table Forum in the DB control)
[ CODE FROM THE PROCEDURE ]
update [Control]. dbo. Forum set over90= @var
Task to query table
Now we can interrogate the table forum but we need to set up the variable to pass to the mail. Let’s start with another Execute SQL Task.
Set up the Execute SQL Task.
We need a ResultSet as “Single row”, the Connection pointing to Control db and the SQLstatement that read the column over90. Do you remember? Running the procedure in the previous task we updated the over90 with the number of database that have already achieved the 90% of availability. Now we are just checking how many db are over the range. But we need to use this information later so we write this result in a variable. How?
Using SSIS variables
Be careful, the Scope must be the package name and as Data Type INT 32. Now we have the variable. Let’s go back to the Execute SQL Task.
In Result Set click on Add and write cnt (it comes from select over90 as cnt from forum as Result Name and VariableForum as Variable Name
Tasks to send mail
Now I want three different mail (Send Mail Task): one in case I have more than ten db over 90% (Critical Alert), one in case I have less than 10 but more than 0 db over 90% (Low Alert), one in case I have no db over 90% (No alert).
In order to split the condition we can use the VariableForum that we have already set up on the previous step.
Let’s join the task. Right click edit (or double click) and you can fix the join with the variable.
As operation we must choose Expression, as Expression we say that the variableforum is greater than 10 and we must use the logical AND.
For the second mail ( Low alert) we change the Precedence Constraint Editor as:
The correct syntax to insert in the expression window is:
@[User::VariableForum]>1 && @[User::VariableForum]<11
** **
For the last Precedence Constraint Editor (No alert) is simple to set up:
@[User::VariableForum]<1
Now we have the condition. We need to set up the mail. In order to set up the mail I strongly recommend you to create an email that can be run from SQL agent as owner (ask your network administrator). Let’s say that we already have this mail SSIS@company.com
1. Setup Connection
First thing to do is set up the connection:
2. Setup Mail
Second thing to do is to set up the mail:
3. Setup Expression
Third thing to do is to set up the Expression in this way:
The Expression string is :
"You have got "+(DT_WSTR, 10)@[User::Variable1]+" database that have already achieved 90% of availability"
Do the same changing only the subject (Low alert and No alert) with the other mail.
Complete package
The package is now complete:
Create new job
Now we need to create a new job in SQL Agent and to add up the new step:
Schedule task
And to schedule the task:
Final result
The final result is that every morning you’ll be warned with the situation of your database system. You can schedule as many package as you want. You can travel, you can go on vacation, you can take a week off; don’t worry, SSIS will tell you if something is going wrong.