Maintenance of SSISDB within SQL Server
The SSIS Server Maintenance Job is used for maintenance of SSISDB. It manages the retention of operations records in SSISDB. I noticed it had been turned off by someone last year and it hadn’t run since. Therefore, SSISDB had become bloated and there was only 10MB left on the data drive meaning the database could no longer auto grow.
Nobody was aware, why would they be? After all, nothing was failing. We didn’t have disk space monitoring enabled so the only time we found out there was a problem was when the disk had filled up.
I made 2 unsuccessful attempts at running the SSIS Server Maintenance Job. However, after several hours of processing and still no available free space in the database, I knew the job wasn’t coping with the sheer number of rows it had to delete. The deletes all happen from the parent table (internal.operations) and then all child tables using using cascading deletes. This approach maintains referential integrity but is not great for performance.
Due to this, I needed a new approach to the maintenance of SSISDB. As we hadn’t maintained these tables for 13/14 months, I was asking too much of SQL Server to let me delete everything at once. (Truncates wouldn’t do because I had to keep the last 2 weeks data).
A bit of investigation showed me that these were the related tables.
- Amend the retention period (days) in catalog.properties to 400 (because 14 was unmanageable with > 400 days of history)
- Write a delete script or find a reliable one that does this work due to SSISDB’s native stored procedures failing to cope
- Ensure SSISDB is in SIMPLE recovery model because it will reduce t-log growth
- Run the delete script and see how it performs and how much space is freed up in order that the days for deletions can be optimised
- Repeat steps 1-4 (each time lowering retention period (days)) until I achieve my target retention period of 14
- Ensure this never happens again 😎 (because it’s no fun getting 300 failure emails an hour)
1. Reduce retention period (days) in catalog.properties to 400 (This allowed me delete rows based on only 22,000 IDs)
To do this in T-SQL:
EXEC [SSISDB].[catalog].[configure_catalog] @property_name=N'RETENTION_WINDOW', @property_value=400
To do this is SSMS:
Right click SSISDB from Integration Services Catalog in SQL Server Management Studio. Then, amend Retention Period (days) to a suitable initial value – in my case 400 days.
2. Script out or find a reliable script that does this work manually.
I struck gold with a superb script from Tim Mitchell which honours the Retention Period (days) value. I decided this was better than writing my own. Please follow the link to review this script along with other useful information (or likewise, get the latest version from Tim’s Github).
3. Ensure SSISDB is in SIMPLE recovery model (as it helps with transaction log)
SELECT DB_NAME(database_id) AS DBName,recovery_model_desc FROM sys.databases WHERE DB_NAME(database_id) = 'SSISDB'
If it’s not, I recommend you ALTER database to SIMPLE recovery in order to minimise logging. It’s not an essential step but will save bloating your transaction log.
ALTER DATABASE [SSISDB] SET RECOVERY SIMPLE WITH NO_WAIT
4. Run script (from step 2) and see how it performs and how much space is freed up
SELECT NAME, size/128/1024.0 AS FileSizeGB, size/128/1024.0 - CAST(FILEPROPERTY(NAME, 'SpaceUsed') AS INT)/128/1024.0 AS FreeSpaceGB, (size/128/1024.0 - CAST(FILEPROPERTY(NAME, 'SpaceUsed') AS INT)/128/1024.0) / (size/128/1024.0) * 100 AS PercentFree FROM SSISDB.sys.database_files WHERE NAME = 'SSISdata';
5. Repeat steps 1-4 (each time lowering retention period (days)) until you achieve your target retention period
I started small by reducing the retention period (days) to 390. This allowed me to measure the time and impact of removing 10 days of data. I then went down to a retention period of 360 days. I found 14 days to be the best performing decrements so I kept doing this until I had only 14 days of data remaining. Following this, I kept the new script in place (scheduled nightly) via SQL Agent. There was no need to continue using the SSISDB cleanup stored procedure internal.cleanup_server_retention_window.
6. Ensure this never happens again
They say prevention is better than cure. Here are some ideas on how to implement this and ensure that your maintenance of SSISDB is ongoing:
- SQL Agent Job to check if date of oldest id is greater than expected (And alert of not)
- Write a check in PowerShell or even better, consider writing a command for DBATools.
- Professional monitoring tools may alert on this but I haven’t checked.