Today's Script will drop all database snapshots and create a database snapshot for all online read writeable user databases. I create this script for use in a database mirroring partnership so that the snapshots could be used on the mirroring partner so to impact the mirroring principal less. As such I set the mirroring partnership servers at the beginning of the script because the mirroring partners databases are inaccessible so I have to retrieve the file information from the mirroring principal. This can be changed to run on servers not in a mirroring partnership.
Other than that the only other thing to update is the @SnapshotDirectory variable to the path where you want the snapshots to exist. Each snapshot has a prefix of 'snap_' and a suffix of the time in the format of '_hh00' this was because the snapshots where created on an hourly basis.
----------------------------------------------------------------- Drop And Create Database Snapshots ----------------------------------------------------------------- For more SQL resources, check out SQLServer365.blogspot.com ----------------------------------------------------------------- You may alter this code for your own purposes. You may republish altered code as long as you give due credit. You must obtain prior permission before blogging this code. THIS CODE AND INFORMATION ARE PROVIDED "AS IS" ----------------------------------------------------------------- * Name: spDropAndCreateDatabaseSnapshots * Description: This procedure drops all database snapshots and creates a databsae snapshot of * all online read / writable user databases * Execution: EXEC dbo.spDropAndCreateDatabaseSnapshots * Release Initials CostBefore CostAfter DROP PROCEDURE [dbo].[spDropAndCreateDatabaseSnapshots] ; CREATE PROCEDURE [dbo].[spDropAndCreateDatabaseSnapshots] DECLARE @DatabaseName VARCHAR(100) DECLARE @SQL VARCHAR(6000) DECLARE @SQL1 VARCHAR(2000) DECLARE @SQL2 VARCHAR(2000) DECLARE @SQL3 VARCHAR(2000) DECLARE @SQL4 VARCHAR(2000) DECLARE @SnapshotPrefix VARCHAR(5) DECLARE @SnapshotName VARCHAR(200) DECLARE @SnapshotSeperator VARCHAR(1) DECLARE @SnapshotHour VARCHAR(3) DECLARE @SnapshotMin VARCHAR(2) DECLARE @SnapshotExtension VARCHAR(5) DECLARE @SnapshotDirectory VARCHAR(100) DECLARE @DBSnapshotName VARCHAR(100) DECLARE @MinSnapshotID INT DECLARE @MaxSnapshotID INT DECLARE @ServerName VARCHAR(15) SET @SnapshotDirectory = 'D:\Snapshot\' SET @SnapshotPrefix = 'Snap_' SET @SnapshotSeperator = '_' SELECT @SnapshotHour = DATEPART(hh, GETDATE()) -- Set the servername for the mirroring partner to pick up file names for each database IF @@SERVERNAME = 'PARTNERSERVER' SET @ServerName = 'PRINCIPLESERVER' IF @@SERVERNAME = 'PRINCIPLESERVER' SET @ServerName = 'PARTNERSERVER' -- If time is before 10am then add a leading 0 for consistancy IF LEN(@SnapshotHour) < 2 SET @SnapshotHour = '0' + @SnapshotHour SET @SnapshotHour = @SnapshotSeperator + @SnapshotHour SET @SnapshotExtension = '.snap' -- Check for temporary tableS and drop it if it exists IF OBJECT_ID('tempDB.dbo.#Database') IS NOT NULL IF OBJECT_ID('tempDB.dbo.#SQL2') IS NOT NULL IF OBJECT_ID('tempDB.dbo.#Snapshot') IS NOT NULL -- Create temporary tables DatabaseName VARCHAR(100) SnapshotName VARCHAR(2000) -- Check for existing database snapshots and delete them WHERE --snapshot_isolation_state = 1 name NOT IN ( 'master', 'model', 'msdb', 'tempdb', AND LEFT(name, 5) = 'Snap_' ) -- Insert all database snapshot names into a temporary table INSERT INTO #Snapshot ( SnapshotName ) WHERE --snapshot_isolation_state = 1 name NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'distribution' ) AND LEFT(name, 5) = 'Snap_' -- Set Variables for the drop snapshot loop SELECT @MinSnapshotID = MIN(ID), -- Begin loop to drop snapshots WHILE @MinSnapshotID <= @MaxSnapshotID SELECT @DBSnapshotName = SnapshotName WHERE ID = @MinSnapshotID -- Build DROP DATABASE COMMAND SET @SQL = 'DROP DATABASE ' + @DBSnapshotName + ';' -- Try Catch block to execute SQL and handle errors -- Drop Database Snapshots WHERE message_id = @@ERROR AND language_id = 1033 -- British English -- Get the next SnapshotName ID SET @MinSnapshotID = @MinSnapshotID + 1 -- Create Database Snapshots for all Online Read/Writable databases WHERE name NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'distribution', 'reports', 'reportserver', 'reportservertempdb' ) AND DATABASEPROPERTYEX(name, 'Updateability') = 'READ_WRITE' AND DATABASEPROPERTYEX(name, 'Status') = 'ONLINE' -- Insert Online, Read/Writable database names into temporary table INSERT INTO #Database ( DatabaseName ) WHERE name NOT IN ( 'master', 'model', 'msdb', 'tempdb', 'distribution', 'reports', 'reportserver', 'reportservertempdb' ) AND DATABASEPROPERTYEX(name, 'Updateability') = 'READ_WRITE' AND DATABASEPROPERTYEX(name, 'Status') = 'ONLINE' SELECT @MinDBID = MIN(ID), WHILE @MinDBID <= @MaxDBID SELECT @DatabaseName = DatabaseName -- Build up snapshot string SET @SnapshotName = @SnapshotPrefix + @DatabaseName + @SnapshotHour + @SnapshotMin -- Create Start of SQL command to be run CREATE DATABASE ' + @SnapshotName + ' -- Remove records from table ready for next database -- Build command to Insert files into temp table SET @SQL2 = 'INSERT #SQL2 + '+ '''' + name + '', FILENAME = ''''' + @SnapshotDirectory + ''' + name + ''' + @SnapshotHour + @SnapshotMin + '.snap'''')'' FROM ' + @ServerName + '.' + @DatabaseName + '.sys.database_files -- Try Catch block to execute SQL and handle errors -- Insert files into tmp table WHERE message_id = @@ERROR AND language_id = 1033 -- British English -- Set Variables for the append , loop SELECT @MinFileID = MIN(ID), -- Begin Loop to append , to the end of all except the last record WHILE @MinFileID < @MaxFileID -- Append , to the end of the current record -- Get the next DatabaseName ID SET @MinFileID = @MinFileID + 1 SELECT @MinFileID = MIN(ID), -- Begin Loop to concatenante all files WHILE @MinFileID <= @MaxFileID -- Append , to the end of the current record SET @SQL3 = @SQL3 + @SQL2 -- Get the next DatabaseName ID SET @MinFileID = @MinFileID + 1 -- Create End of SQL command to be run SET @SQL4 = 'AS SNAPSHOT OF ' + @DatabaseName + ';' -- Concatenate SQL variables ready for execution SET @SQL = @SQL1 + @SQL3 + @SQL4 -- Try Catch block to execute SQL and handle errors -- Create Database Snapshots WHERE message_id = @@ERROR AND language_id = 1033 -- British English -- Get the next DatabaseName ID SET @MinDBID = @MinDBID + 1 Enjoy!
Chris