<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Backup &amp; Restore &#8211; SQLpowered.com</title>
	<atom:link href="https://sqlpowered.com/script-category/backup-restore/feed/" rel="self" type="application/rss+xml" />
	<link>https://sqlpowered.com</link>
	<description>SQL Server + BI</description>
	<lastBuildDate>Sat, 31 Jan 2026 08:47:56 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://sqlpowered.com/wp-content/uploads/2020/07/FavIcon-e1594067873682-99x100.png</url>
	<title>Backup &amp; Restore &#8211; SQLpowered.com</title>
	<link>https://sqlpowered.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Delete large backup history</title>
		<link>https://sqlpowered.com/script/delete-large-backup-history/</link>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Sat, 31 Jan 2026 08:45:27 +0000</pubDate>
				<guid isPermaLink="false">https://sqlpowered.com/?post_type=script&#038;p=5794</guid>

					<description><![CDATA[msdb can get massive when the backup history isn’t purged regularly. In that state, sp_delete_backuphistory can run for a very long time (and sometimes becomes a maintenance nightmare). I built an alternative cleanup script that: purges old rows in batches (TOP + loop) is designed to be restartable and predictable...]]></description>
										<content:encoded><![CDATA[<p data-start="936" data-end="1127"><code data-start="936" data-end="942">msdb</code> can get <em data-start="951" data-end="960">massive</em> when the backup history isn’t purged regularly. In that state, <strong data-start="1020" data-end="1049"><code data-start="1022" data-end="1047">sp_delete_backuphistory</code></strong> can run for a very long time (and sometimes becomes a maintenance nightmare).</p>
<p data-start="1129" data-end="1172">I built an alternative cleanup script that:</p>
<ul>
<li>purges old rows in <strong data-start="1194" data-end="1205">batches</strong> (TOP + loop)</li>
<li>is designed to be <strong data-start="1288" data-end="1303">restartable</strong> and predictable</li>
<li>optionally adds <strong data-start="1237" data-end="1248">WAITFOR</strong> to reduce pressure</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">USE [msdb]
GO

SET NOCOUNT ON

DECLARE @BackupDate DATE
DECLARE @Msg NVARCHAR(MAX)

DROP TABLE IF EXISTS [#backup_set_id]
DROP TABLE IF EXISTS [#media_set_id]
DROP TABLE IF EXISTS [#restore_history_id]

CREATE TABLE [#backup_set_id] ([backup_set_id] INT NOT NULL PRIMARY KEY)
CREATE TABLE [#media_set_id] ([media_set_id] INT NOT NULL PRIMARY KEY)
CREATE TABLE [#restore_history_id] ([restore_history_id] INT NOT NULL PRIMARY KEY)

DROP TABLE IF EXISTS [#Dates]

CREATE TABLE [#Dates] ( [BackupDate] DATE NOT NULL PRIMARY KEY)


INSERT INTO [#Dates] 
	(	[BackupDate] )
	SELECT 
		DISTINCT CAST([backup_finish_date] AS DATE)
	FROM [dbo].[backupset]
	WHERE [backup_finish_date] &lt; DATEADD(dd,-5,GETDATE())

WHILE EXISTS (SELECT * FROM [#Dates])
BEGIN

	SELECT TOP(1) 
		@BackupDate = [BackupDate]		
	FROM [#Dates]
	ORDER BY [BackupDate]

	SET @Msg = CAST(@BackupDate AS NVARCHAR(20))
	RAISERROR('%s', 10, 1, @Msg) WITH NOWAIT

	--EXECUTE [dbo].[sp_delete_backuphistory] @BackupDate
    
    BEGIN TRY

        TRUNCATE TABLE [#backup_set_id]
        TRUNCATE TABLE [#media_set_id]
        TRUNCATE TABLE [#restore_history_id]

	    INSERT INTO [#backup_set_id] ([backup_set_id])
            SELECT DISTINCT [backup_set_id]
            FROM [msdb].[dbo].[backupset]
            WHERE [backup_finish_date] &lt; @BackupDate

        INSERT INTO [#media_set_id] ([media_set_id])
            SELECT DISTINCT [media_set_id]
            FROM [msdb].[dbo].[backupset]
            WHERE [backup_finish_date] &lt; @BackupDate

        INSERT INTO [#restore_history_id] ([restore_history_id])
            SELECT DISTINCT [restore_history_id]
            FROM [msdb].[dbo].[restorehistory]
            WHERE [backup_set_id] IN (SELECT [backup_set_id] FROM [#backup_set_id])

        BEGIN TRANSACTION

            DELETE FROM [msdb].[dbo].[backupfile]
            WHERE [backup_set_id] IN (SELECT [backup_set_id] FROM [#backup_set_id])

            DELETE FROM [msdb].[dbo].[backupfilegroup]
            WHERE [backup_set_id] IN (SELECT [backup_set_id] FROM [#backup_set_id])
            
            DELETE FROM [msdb].[dbo].[restorefile]
            WHERE [restore_history_id] IN (SELECT [restore_history_id] FROM [#restore_history_id])
            
            DELETE FROM [msdb].[dbo].[restorefilegroup]
            WHERE [restore_history_id] IN (SELECT [restore_history_id] FROM [#restore_history_id])
            
            DELETE FROM [msdb].[dbo].[restorehistory]
            WHERE [restore_history_id] IN (SELECT [restore_history_id] FROM [#restore_history_id])

            DELETE FROM [msdb].[dbo].[backupset]
            WHERE [backup_set_id] IN (SELECT [backup_set_id] FROM [#backup_set_id])
            
            DELETE [msdb].[dbo].[backupmediafamily]
            FROM [msdb].[dbo].[backupmediafamily] [bmf]
            WHERE [bmf].[media_set_id] IN (SELECT [media_set_id] FROM [#media_set_id])
                  AND ((SELECT COUNT(*) FROM [msdb].[dbo].[backupset] WHERE [media_set_id] = [bmf].[media_set_id]) = 0)

            DELETE [msdb].[dbo].[backupmediaset]
            FROM [msdb].[dbo].[backupmediaset] [bms]
            WHERE [bms].[media_set_id] IN (SELECT [media_set_id] FROM [#media_set_id])
                  AND ((SELECT COUNT(*) FROM [msdb].[dbo].[backupset] WHERE [media_set_id] = [bms].[media_set_id]) = 0)

        COMMIT TRANSACTION

    END TRY
    BEGIN CATCH

        IF @@TRANCOUNT &gt; 0
            ROLLBACK

        ;THROW

    END CATCH
    
	DELETE FROM [#Dates] WHERE [BackupDate] = @BackupDate

END
GO
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Create and restore database from database snapshot</title>
		<link>https://sqlpowered.com/script/create-and-restore-database-from-database-snapshot/</link>
		
		<dc:creator><![CDATA[Jan Dvořák]]></dc:creator>
		<pubDate>Thu, 08 Mar 2018 23:11:46 +0000</pubDate>
				<guid isPermaLink="false">https://sqlpowered.com/?post_type=script&#038;p=2355</guid>

					<description><![CDATA[USE [master] GO CREATE DATABASE [MY_DB_01] ON ( NAME = N'MY_DB', FILENAME = N'E:\DATA\MY_DB.ss' ) AS SNAPSHOT OF [MY_DB]; GO -- REVERT TO SNAPSHOT USE [master] GO -- Close existing connections DECLARE @Sql VARCHAR(1000) SET @Sql = '' SELECT @Sql = @Sql + 'kill ' + CONVERT(NVARCHAR(3), [spid]) + ';...]]></description>
										<content:encoded><![CDATA[<pre class="EnlighterJSRAW" data-enlighter-language="null">USE [master]
GO

CREATE DATABASE [MY_DB_01] ON
( NAME = N'MY_DB', FILENAME = N'E:\DATA\MY_DB.ss' )
AS SNAPSHOT OF [MY_DB];
GO

-- REVERT TO SNAPSHOT

USE [master]
GO

-- Close existing connections
DECLARE @Sql VARCHAR(1000)
SET @Sql = ''    
SELECT  @Sql = @Sql + 'kill ' + CONVERT(NVARCHAR(3), [spid]) + '; '
FROM    [master].[dbo].[sysprocesses]
WHERE   DB_NAME([dbid]) = 'MY_DB' 
EXECUTE(@Sql)
GO

-- Restore from snapshot
RESTORE DATABASE MY_DB
    FROM DATABASE_SNAPSHOT = 'MY_DB_01';
GO</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
