Skip to content

Instantly share code, notes, and snippets.

@nanoDBA
Created May 22, 2025 14:57
Show Gist options
  • Save nanoDBA/d9e6b940131816b557d8d11f7c520d73 to your computer and use it in GitHub Desktop.
Save nanoDBA/d9e6b940131816b557d8d11f7c520d73 to your computer and use it in GitHub Desktop.
πŸš€ Rapidly fills a SQL Server test database log file to simulate disk full and alerting scenarios. Useful for testing error handling, monitoring, and DBA/ops automation. 😎
/*
| File: Improved-Fill-TestLogVolume.sql
| Description: πŸš€ Rapidly fills a SQL Server test database log file to simulate
| disk full and alerting scenarios. Useful for testing error
| handling, monitoring, and DBA/ops automation. 😎
| Purpose: Quickly consume log file space to test SQL Server's response to
| log growth, disk full, and alerting. Designed for use in
| dev/test environments only! Not for prod! ⚠️
| The script can optionally reserve a buffer of free space on the
| log drive, or attempt to fill the drive completely. See below.
| Created: 2025-05-14
| Modified: 2025-05-20
| Refactored: 2025-05-20 for idempotency and SQL Server compatibility
| (AI/DBA collaboration)
| WARNING: TEST/DEV USE ONLY! This script will fill disk space and may
| trigger alerts or impact system stability. Use with caution! πŸ’₯
*/
-- AI-Updated: 2024-05-20 12:00:00 | Marker: AIUPD-20240520120000-496d70726f7665642d46696c6c2d546573744c6f67566f6c756d652e73716c #|
-- ============================================================================
-- Summary:
-- This script rapidly fills a SQL Server test database log file to simulate
-- disk full and alerting scenarios. It is designed for use in dev/test
-- environments to test error handling, monitoring, and automation. πŸ˜…
--
-- Features:
-- - User-configurable parameters for directories, file sizes, and behavior
-- - Dynamic detection of default data/log directories
-- - Optional sparse file pre-fill using PowerShell
-- - High-speed log-filling loop with progress and free space checks
-- - Robust cleanup section (can be run standalone)
-- - All output is immediate and unbuffered (RAISERROR ... WITH NOWAIT)
-- - Control over reserved disk space buffer for safe or aggressive fill
-- - Snarky comments and emoji for fun and clarity
--
-- Recommendations:
-- - Only use in non-production environments! ⚠️
-- - Monitor system alerts and disk space closely
-- - Use the cleanup section to remove all test artifacts and sparse files
-- - Adjust reserved disk space buffer as needed for your environment
-- - To fill the drive as much as possible, set ReservedLogDriveSpaceMB = 0
-- - If you break the loop or script, run the cleanup section manually
--
-- Reserved Disk Space Buffer (ReservedLogDriveSpaceMB):
-- - This parameter controls how much free space (in MB) to leave on the log
-- drive after filling. It is used to avoid completely filling the drive,
-- which can cause system instability.
-- - Set to NULL (default): Auto-calculate as 2% of free space or 512 MB min.
-- - Set to a specific value (e.g., 1000): Reserve that many MB free.
-- - Set to 0: Attempt to fill the drive completely (dangerous, for test only).
--
-- Examples:
-- ('ReservedLogDriveSpaceMB', NULL) -- Auto-calc (safe-ish default)
-- ('ReservedLogDriveSpaceMB', 1000) -- Leave 1 GB free
-- ('ReservedLogDriveSpaceMB', 0) -- Fill drive as much as possible! πŸ’₯
--
-- ============================================================================
-- =============================================
-- USER CONFIGURABLE PARAMETERS (EDIT BELOW)
-- =============================================
-- All user parameters are now stored in a temp table for robust scope.
-- Edit these values to control script behavior. 😎
IF OBJECT_ID('tempdb..#params') IS NOT NULL DROP TABLE #params;
CREATE TABLE #params (
param_name NVARCHAR(100) PRIMARY KEY,
param_value SQL_VARIANT
);
-- Insert user parameters with comments for each
INSERT INTO #params (param_name, param_value) VALUES
('OverrideDataDir', NULL), -- Optional: override data directory (e.g. 'D:\SQLData\')
('OverrideLogDir', NULL), -- Optional: override log directory (e.g. 'E:\SQLLogs\')
('LogInitialSizeMB', 512), -- Initial log file size in MB
('LogGrowthMB', 512), -- Log file growth increment in MB
('EnableSparseFile', 1), -- 1 = enable sparse file pre-fill, 0 = disable
('ReservedLogDriveSpaceMB', NULL), -- MB to leave free on log drive (see docs above)
--('ReservedLogDriveSpaceMB', 0), -- 🐲 🐲 🐲 DANGER - ARE YOU SURE?! 0 MB to leave free on log drive (see docs above) 🐲
('UseMeaningfulSparseFileName', 1), -- 1 = timestamp in sparse file name, 0 = generic name
('BatchSize', 50000), -- Rows per batch insert (log fill speed)
('BatchCount', 10000), -- Max number of batches to run
('MonitorInterval', 10), -- Report progress every N batches
('PerformCleanup', 1); -- 1 = run cleanup at end, 0 = skip cleanup
-- =============================================
-- Parameter Extraction (assign to variables from #params)
-- =============================================
-- Extract user parameters into variables for use throughout the script.
DECLARE @OverrideDataDir NVARCHAR(512);
DECLARE @OverrideLogDir NVARCHAR(512);
DECLARE @LogInitialSizeMB INT;
DECLARE @LogGrowthMB INT;
DECLARE @EnableSparseFile BIT;
DECLARE @ReservedLogDriveSpaceMB BIGINT;
DECLARE @UseMeaningfulSparseFileName BIT;
DECLARE @BatchSize INT;
DECLARE @BatchCount INT;
DECLARE @MonitorInterval INT;
DECLARE @PerformCleanup BIT;
SELECT @OverrideDataDir = CAST(param_value AS NVARCHAR(512)) FROM #params WHERE param_name = 'OverrideDataDir';
SELECT @OverrideLogDir = CAST(param_value AS NVARCHAR(512)) FROM #params WHERE param_name = 'OverrideLogDir';
SELECT @LogInitialSizeMB = CAST(param_value AS INT) FROM #params WHERE param_name = 'LogInitialSizeMB';
SELECT @LogGrowthMB = CAST(param_value AS INT) FROM #params WHERE param_name = 'LogGrowthMB';
SELECT @EnableSparseFile = CAST(param_value AS BIT) FROM #params WHERE param_name = 'EnableSparseFile';
SELECT @ReservedLogDriveSpaceMB = CAST(param_value AS BIGINT) FROM #params WHERE param_name = 'ReservedLogDriveSpaceMB';
SELECT @UseMeaningfulSparseFileName = CAST(param_value AS BIT) FROM #params WHERE param_name = 'UseMeaningfulSparseFileName';
SELECT @BatchSize = CAST(param_value AS INT) FROM #params WHERE param_name = 'BatchSize';
SELECT @BatchCount = CAST(param_value AS INT) FROM #params WHERE param_name = 'BatchCount';
SELECT @MonitorInterval = CAST(param_value AS INT) FROM #params WHERE param_name = 'MonitorInterval';
SELECT @PerformCleanup = CAST(param_value AS BIT) FROM #params WHERE param_name = 'PerformCleanup';
-- Use these variables throughout the script and pass them as parameters to procedures
-- No function-based parameter access, no database prefixes
USE master;
-- =============================================
-- Variable Declarations and Initialization (internal/derived)
-- =============================================
-- These variables are used for dynamic paths, file sizes, and cleanup. πŸ’Ύ
DECLARE @DefaultDataPath NVARCHAR(512); -- Path to a user DB data file (for default dir detection).
DECLARE @DefaultLogPath NVARCHAR(512); -- Path to a user DB log file (for default dir detection).
DECLARE @DataDir NVARCHAR(512); -- Final data directory used for test DB.
DECLARE @LogDir NVARCHAR(512) = NULL; -- Final log directory used for test DB and cleanup (always in scope).
DECLARE @DataFile NVARCHAR(512); -- Full path for test DB data file.
DECLARE @LogFile NVARCHAR(512); -- Full path for test DB log file.
DECLARE @SQL NVARCHAR(MAX); -- For dynamic SQL (DB creation, etc.).
DECLARE @SparseFileSizeMB BIGINT = NULL; -- Size of sparse file to pre-fill log drive.
DECLARE @LogDriveLetter CHAR(1) = NULL; -- Drive letter for log file.
DECLARE @LogDriveFreeMB BIGINT = NULL; -- Free space on log drive (MB).
DECLARE @TimeStamp VARCHAR(20) = ''; -- Timestamp for unique sparse file names.
DECLARE @SparseFilePath NVARCHAR(512) = NULL; -- Full path for sparse file.
DECLARE @CalculatedBufferMB BIGINT = NULL; -- Calculated buffer space to leave free.
DECLARE @FinalFreeMB BIGINT = NULL; -- Final free space after log fill (MB).
DECLARE @cmd NVARCHAR(1000) = NULL; -- For cleanup PowerShell command (always in scope).
-- =============================================
-- Dynamic Data/Log Directory Detection
-- =============================================
-- Find default data/log directories from an existing user DB. πŸ“
SELECT TOP 1 @DefaultDataPath = physical_name FROM sys.master_files WHERE database_id > 4 AND file_id = 1; -- user DB data file
SELECT TOP 1 @DefaultLogPath = physical_name FROM sys.master_files WHERE database_id > 4 AND file_id = 2; -- user DB log file
-- Extract directory (everything up to the last backslash).
SET @DataDir = LEFT(@DefaultDataPath, LEN(@DefaultDataPath) - CHARINDEX('\', REVERSE(@DefaultDataPath)) + 1);
SET @LogDir = LEFT(@DefaultLogPath, LEN(@DefaultLogPath) - CHARINDEX('\', REVERSE(@DefaultLogPath)) + 1);
-- Allow override from user-tunable parameters.
SET @DataDir = ISNULL(@OverrideDataDir, @DataDir);
SET @LogDir = ISNULL(@OverrideLogDir, @LogDir);
PRINT 'Using directories:';
PRINT ' Data: ' + @DataDir;
PRINT ' Log: ' + @LogDir;
-- =============================================
-- Ensure xp_cmdshell is enabled before any usage
-- =============================================
-- xp_cmdshell is required for PowerShell-based sparse file creation and cleanup.
EXEC dbo.SetXpCmdShellEnabled @Enable = 1;
-- =============================================
-- Clean up any existing test database
-- =============================================
PRINT 'Cleaning up any existing test database...';
IF DB_ID(N'TestLogFill') IS NOT NULL
BEGIN
PRINT ' Dropping existing TestLogFill database...';
ALTER DATABASE TestLogFill SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE TestLogFill;
END
-- =============================================
-- Create Test Database
-- =============================================
-- Build file paths for new test DB.
SET @DataFile = @DataDir + 'TestLogFill_Data.mdf';
SET @LogFile = @LogDir + 'TestLogFill_Log.ldf';
IF DB_ID(N'TestLogFill') IS NULL
BEGIN
PRINT 'Creating TestLogFill database...';
SET @SQL = N'CREATE DATABASE TestLogFill
ON PRIMARY
(
NAME = N''TestLogFill_Data'',
FILENAME = N''' + @DataFile + ''',
SIZE = 100MB
)
LOG ON
(
NAME = N''TestLogFill_Log'',
FILENAME = N''' + @LogFile + ''',
SIZE = ' + CAST(@LogInitialSizeMB AS VARCHAR) + 'MB,
FILEGROWTH = ' + CAST(@LogGrowthMB AS VARCHAR) + 'MB
);';
EXEC sp_executesql @SQL;
PRINT ' Database created successfully.';
END
ELSE
BEGIN
PRINT 'TestLogFill database already exists.';
END
-- =============================================
-- Create Test Table and Execute Log Fill (only if DB exists)
-- =============================================
IF DB_ID(N'TestLogFill') IS NOT NULL
BEGIN
-- Create Test Table using dynamic SQL to ensure context
SET @SQL = N'
USE [TestLogFill];
IF OBJECT_ID(''dbo.LogFill'', ''U'') IS NOT NULL DROP TABLE dbo.LogFill;
CREATE TABLE dbo.LogFill
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Dummy CHAR(8000) NOT NULL DEFAULT REPLICATE(''A'', 8000)
);
';
EXEC sp_executesql @SQL;
END
ELSE
BEGIN
PRINT 'ERROR: TestLogFill database does not exist. Aborting table creation and log fill.';
RETURN;
END
-- =============================================
-- PRE-FILL DRIVE WITH SPARSE FILE (OPTIONAL)
-- =============================================
-- Optionally pre-fill the log drive with a sparse file to simulate low disk.
USE master;
IF @EnableSparseFile = 1
BEGIN
-- Get log directory and drive letter for sparse file creation.
SELECT @LogDir = LEFT(physical_name, LEN(physical_name) - CHARINDEX('\', REVERSE(physical_name)) + 1)
FROM sys.master_files
WHERE database_id = DB_ID('TestLogFill') AND file_id = 2;
SET @LogDriveLetter = LEFT(@LogDir, 1);
-- Get free space on log drive.
CREATE TABLE #DriveSpace (Drive CHAR(1), FreeMB BIGINT);
INSERT INTO #DriveSpace EXEC master.dbo.xp_fixeddrives;
SELECT @LogDriveFreeMB = FreeMB FROM #DriveSpace WHERE Drive = @LogDriveLetter;
DROP TABLE #DriveSpace;
-- Calculate buffer and sparse file size.
SET @CalculatedBufferMB = CASE
WHEN @LogDriveFreeMB * 0.02 < 512 THEN 512
ELSE CAST(@LogDriveFreeMB * 0.02 AS BIGINT)
END;
SET @ReservedLogDriveSpaceMB = ISNULL(@ReservedLogDriveSpaceMB, @CalculatedBufferMB);
SET @SparseFileSizeMB = @LogDriveFreeMB - @ReservedLogDriveSpaceMB;
-- Build timestamped sparse file name if requested.
IF @UseMeaningfulSparseFileName = 1
BEGIN
SET @TimeStamp = '_' +
REPLACE(CONVERT(VARCHAR(10), GETDATE(), 120), '-', '') + '_' +
REPLACE(CONVERT(VARCHAR(8), GETDATE(), 108), ':', '');
END
IF @SparseFileSizeMB > 0
BEGIN
SET @SparseFilePath = @LogDir + 'TestLogFill_LogDriveFiller' + @TimeStamp + '.sparse';
PRINT ' Log drive ' + @LogDriveLetter + ': has ' + CAST(@LogDriveFreeMB AS VARCHAR) + ' MB free';
PRINT ' Creating sparse file: ' + @SparseFilePath;
PRINT ' Sparse file size: ' + CAST(@SparseFileSizeMB AS VARCHAR) + ' MB (98% of free space)';
PRINT ' Buffer space left: ' + CAST(@ReservedLogDriveSpaceMB AS VARCHAR) + ' MB (' +
CASE WHEN @ReservedLogDriveSpaceMB = @CalculatedBufferMB
THEN 'calculated as 2% of free space or 512 MB minimum'
ELSE 'user override' END + ')';
-- Build and execute PowerShell command to create sparse file.
DECLARE @PowerShellCmd NVARCHAR(4000) =
'powershell -command "fsutil file createnew ''' + @SparseFilePath + ''' ' + CAST(CAST(@SparseFileSizeMB AS BIGINT) * 1024 * 1024 AS VARCHAR) + '; fsutil sparse setflag ''' + @SparseFilePath + '''"';
PRINT ' Executing sparse file creation...';
EXEC xp_cmdshell @PowerShellCmd;
PRINT ' Updated drive space after sparse file creation:';
EXEC master.dbo.xp_fixeddrives;
END
ELSE
BEGIN
PRINT 'WARNING: Not enough free space to create sparse file! Buffer (' +
CAST(@ReservedLogDriveSpaceMB AS VARCHAR) + ' MB) is larger than available space (' +
CAST(@LogDriveFreeMB AS VARCHAR) + ' MB)';
END
END
-- =============================================
-- Main Log Fill Loop (after sparse file creation)
-- =============================================
-- This is the main high-speed log fill. Progress and free space are checked
-- every @MonitorInterval batches. If free space drops below 10 MB, the loop
-- exits with a warning. πŸ’₯
IF DB_ID(N'TestLogFill') IS NOT NULL
BEGIN
-- Inline log fill logic (replaces FillLogFast procedure)
SET @SQL = N'
USE TestLogFill;
DECLARE @i INT = 0;
DECLARE @StartTime DATETIME = GETDATE();
DECLARE @StartTimeStr VARCHAR(20) = CONVERT(VARCHAR(20), @StartTime);
RAISERROR(''Starting high-speed log fill at %s...'', 0, 1, @StartTimeStr) WITH NOWAIT;
BEGIN TRANSACTION;
WHILE @i < ' + CAST(@BatchCount AS VARCHAR) + '
BEGIN
INSERT INTO dbo.LogFill (Dummy)
SELECT TOP (' + CAST(@BatchSize AS VARCHAR) + ') REPLICATE(CHAR(65 + (@i % 26)), 8000)
FROM sys.all_objects a CROSS JOIN sys.all_objects b;
SET @i = @i + 1;
IF @i % ' + CAST(@MonitorInterval AS VARCHAR) + ' = 0
BEGIN
DECLARE @ElapsedSec INT = DATEDIFF(SECOND, @StartTime, GETDATE());
DECLARE @RowsInserted BIGINT = @i * ' + CAST(@BatchSize AS VARCHAR) + ';
DECLARE @RowsPerSec BIGINT = CASE WHEN @ElapsedSec > 0 THEN @RowsInserted / @ElapsedSec ELSE 0 END;
-- Check free space
CREATE TABLE #DriveSpace (Drive CHAR(1), FreeMB BIGINT);
INSERT INTO #DriveSpace EXEC master.dbo.xp_fixeddrives;
DECLARE @CurrentFreeMB BIGINT;
SELECT @CurrentFreeMB = FreeMB FROM #DriveSpace WHERE Drive = ''' + @LogDriveLetter + ''';
DROP TABLE #DriveSpace;
RAISERROR(''Batch %I64d complete. Inserted %I64d rows (%I64d rows/sec). Free space: %I64d MB'', 0, 1, @i, @RowsInserted, @RowsPerSec, @CurrentFreeMB) WITH NOWAIT;
IF @CurrentFreeMB < 10
BEGIN
RAISERROR(''WARNING: Free space below 10 MB (actual: %I64d MB), stopping log fill.'', 0, 1, @CurrentFreeMB) WITH NOWAIT;
BREAK;
END
CHECKPOINT;
END
END;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
';
EXEC sp_executesql @SQL;
END
ELSE
BEGIN
PRINT 'ERROR: TestLogFill database does not exist. Aborting log fill.';
RETURN;
END
-- =============================================
-- FILL REMAINING DRIVE SPACE
-- =============================================
-- If sparse file was used, fill the remaining buffer space with log data.
IF @EnableSparseFile = 1 AND @SparseFileSizeMB > 0
BEGIN
PRINT 'Filling remaining drive space (' + CAST(@ReservedLogDriveSpaceMB AS VARCHAR) + ' MB) with log data...';
DECLARE @EstimatedRowsPerMB INT = 125; -- Approx. 8000 bytes per row / 1024^2 = ~125 rows/MB
DECLARE @MaxRows INT = @ReservedLogDriveSpaceMB * @EstimatedRowsPerMB;
DECLARE @AdjustedBatchCount INT = CEILING(CAST(@MaxRows AS FLOAT) / @BatchSize);
PRINT ' Estimated rows to fill ' + CAST(@ReservedLogDriveSpaceMB AS VARCHAR) + ' MB: ' + CAST(@MaxRows AS VARCHAR);
PRINT ' Adjusted batch count: ' + CAST(@AdjustedBatchCount AS VARCHAR);
-- Inline log fill logic for remaining drive space
SET @SQL = N'
USE TestLogFill;
DECLARE @i2 INT = 0;
DECLARE @StartTime2 DATETIME = GETDATE();
DECLARE @StartTimeStr2 VARCHAR(20) = CONVERT(VARCHAR(20), @StartTime2);
RAISERROR(''Starting high-speed log fill for remaining space at %s...'', 0, 1, @StartTimeStr2) WITH NOWAIT;
BEGIN TRANSACTION;
WHILE @i2 < ' + CAST(@AdjustedBatchCount AS VARCHAR) + '
BEGIN
INSERT INTO dbo.LogFill (Dummy)
SELECT TOP (' + CAST(@BatchSize AS VARCHAR) + ') REPLICATE(CHAR(65 + (@i2 % 26)), 8000)
FROM sys.all_objects a CROSS JOIN sys.all_objects b;
SET @i2 = @i2 + 1;
IF @i2 % ' + CAST(@MonitorInterval AS VARCHAR) + ' = 0
BEGIN
DECLARE @ElapsedSec2 INT = DATEDIFF(SECOND, @StartTime2, GETDATE());
DECLARE @RowsInserted2 BIGINT = @i2 * ' + CAST(@BatchSize AS VARCHAR) + ';
DECLARE @RowsPerSec2 BIGINT = CASE WHEN @ElapsedSec2 > 0 THEN @RowsInserted2 / @ElapsedSec2 ELSE 0 END;
-- Check free space
CREATE TABLE #DriveSpace2 (Drive CHAR(1), FreeMB BIGINT);
INSERT INTO #DriveSpace2 EXEC master.dbo.xp_fixeddrives;
DECLARE @CurrentFreeMB2 BIGINT;
SELECT @CurrentFreeMB2 = FreeMB FROM #DriveSpace2 WHERE Drive = ''' + @LogDriveLetter + ''';
DROP TABLE #DriveSpace2;
RAISERROR(''Batch %I64d complete. Inserted %I64d rows (%I64d rows/sec). Free space: %I64d MB'', 0, 1, @i2, @RowsInserted2, @RowsPerSec2, @CurrentFreeMB2) WITH NOWAIT;
IF @CurrentFreeMB2 < 10
BEGIN
RAISERROR(''WARNING: Free space below 10 MB (actual: %I64d MB), stopping log fill.'', 0, 1, @CurrentFreeMB2) WITH NOWAIT;
BREAK;
END
CHECKPOINT;
END
END;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
';
EXEC sp_executesql @SQL;
PRINT ' Final drive space after filling:';
EXEC master.dbo.xp_fixeddrives;
CREATE TABLE #FinalDriveSpace (Drive CHAR(1), FreeMB BIGINT);
INSERT INTO #FinalDriveSpace EXEC master.dbo.xp_fixeddrives;
SELECT @FinalFreeMB = FreeMB FROM #FinalDriveSpace WHERE Drive = @LogDriveLetter;
DROP TABLE #FinalDriveSpace;
IF @FinalFreeMB < 100
BEGIN
PRINT 'WARNING: Drive ' + @LogDriveLetter + ': has only ' + CAST(@FinalFreeMB AS VARCHAR) + ' MB free. Disk is nearly full!';
END
ELSE
BEGIN
PRINT 'Remaining space filled. Drive ' + @LogDriveLetter + ': has ' + CAST(@FinalFreeMB AS VARCHAR) + ' MB free.';
END
END
ELSE
BEGIN
PRINT 'Skipping remaining drive space fill (sparse file disabled or insufficient space).';
END
-- =============================================
-- Cleanup Section (runs if @PerformCleanup = 1)
-- =============================================
-- This section will clean up all test artifacts and sparse files if enabled.
IF @PerformCleanup = 1
BEGIN
USE master;
PRINT 'Cleaning up test resources...';
-- End any open transaction before cleanup
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
-- Remove the sparse file first
SELECT @LogDir = LEFT(physical_name, LEN(physical_name) - CHARINDEX('\', REVERSE(physical_name)) + 1)
FROM sys.master_files
WHERE database_id = DB_ID('TestLogFill') AND file_id = 2;
-- Find and delete sparse files with our naming pattern
EXEC dbo.SetXpCmdShellEnabled @Enable = 1;
SET @cmd = 'powershell -command "& { Remove-Item -Path ''' + @LogDir + 'TestLogFill_LogDriveFiller*.sparse'' -Force }"';
EXEC xp_cmdshell @cmd;
-- Drop the test database
IF DB_ID(N'TestLogFill') IS NOT NULL
BEGIN
ALTER DATABASE TestLogFill SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE TestLogFill;
END
-- Disable xp_cmdshell if it was enabled
EXEC dbo.SetXpCmdShellEnabled @Enable = 0;
PRINT 'Cleanup complete.';
END
ELSE
BEGIN
PRINT 'Cleanup skipped. Set @PerformCleanup = 1 to enable.';
END
PRINT 'Log fill process has been initiated.';
PRINT 'Monitor system alerts for disk full conditions.';
PRINT 'When testing is complete, uncomment and run the cleanup section at the end of this script.';
/*
-- =============================================
-- Standalone Cleanup Section (can be run anytime)
-- =============================================
--Uncomment this section and run manually when you want to clean up all test artifacts and sparse files.
--This will work even if the main script was interrupted or the log-filling loop was broken.
USE master;
PRINT 'Cleaning up test resources...';
-- End any open transaction before cleanup
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
-- Enable xp_cmdshell if needed
IF NOT EXISTS (SELECT 1 FROM sys.configurations WHERE name = 'xp_cmdshell' AND value_in_use = 1)
BEGIN
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
END
-- Recalculate log directory from TestLogFill if it exists, else use default from any user DB
DECLARE @LogDir NVARCHAR(512);
SELECT TOP 1 @LogDir = LEFT(physical_name, LEN(physical_name) - CHARINDEX('\', REVERSE(physical_name)) + 1)
FROM sys.master_files
WHERE (database_id = DB_ID('TestLogFill') AND file_id = 2)
OR (database_id > 4 AND file_id = 2);
-- Remove sparse files matching the pattern
DECLARE @cmd NVARCHAR(1000);
SET @cmd = 'powershell -command "& { Remove-Item -Path ''' + @LogDir + 'TestLogFill_LogDriveFiller*.sparse'' -Force -ErrorAction SilentlyContinue }"';
EXEC xp_cmdshell @cmd;
-- Drop the test database if it exists
IF DB_ID(N'TestLogFill') IS NOT NULL
BEGIN
ALTER DATABASE TestLogFill SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE TestLogFill;
END
-- Disable xp_cmdshell and advanced options after cleanup
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;
EXEC sp_configure 'show advanced options', 0; RECONFIGURE;
PRINT 'Cleanup complete.';
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment