Найти тему

SQL: использование SNAPSHOT в разработке и тестировании

нейроплод
нейроплод

Сегодня 12 февраля 2023 года, 11 часов 56 минут, -4
Всем доброго дня!

В этот раз решил поделиться опытом работы с SQL.

SNAPSHOT - это моментальный снимок информационной базы.

В чем его преимущество?

1. Сам моментальный снимок создается очень быстро.

2. Позволяет восстанавливать базу на момент снимка в считанные секунды.

Как работать с моментальным снимком?

Разберем на примере условной базы storage

Нам потребуются логические имена файлов базы и путь к файлам. Можно посмотреть в параметрах базы, а можно использовать скрипт:

exec sp_helpdb storage

Создание моментального снимка

Далее, используя полученную информацию, создаем моментальный снимок базы:

USE [master]
go

create database storage_11_snap
on
(Name = storage_Data,
FILENAME = 'D:\MSSQL\DATA\storage_11_snap_Data.snap')
AS SNAPSHOT OF storage

Восстановление базы из моментального снимка

После различных манипуляций над базой данных мы можем быстро вернуться к исходному состоянию:

USE [ServiceDB]
go

exec KillAllConnections storage
--чуть ниже приложу эту хранимую процедуру

USE [master]
go

restore database storage
from Database_Snapshot = 'storage_11_snap'
go

Удаление моментального снимка

После окончания работ, если снимок уже не нужен, желательно его удалить:

USE [master]
go

DROP database storage_11_snap
go

Все моментальные снимки баз

Посмотреть моментальные снимки баз можно запросом:

USE [master]
go

select
name
,database_id
,source_database_id
,create_date
,snapshot_isolation_state_desc
from sys.databases

go

у моментальных снимков указан source_database_id

Отключений всех подключений: KillAllConnections

ALTER PROCEDURE [dbo].[KillAllConnections]

@DBName nvarchar(128)

AS

SET NOCOUNT ON;

DECLARE @spidstr varchar(8000) = '';

IF db_id(@DBName) < 4

BEGIN

PRINT 'Connections to system databases cannot be killed'

RETURN

END;

SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '

FROM master..sysprocesses WHERE dbid=db_id(@DBName);

IF LEN(@spidstr) > 0

EXEC(@spidstr);

Удачи!