-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathВосстановление_БД1_из_созданной_копии_БД2.sql
197 lines (176 loc) · 8.69 KB
/
Восстановление_БД1_из_созданной_копии_БД2.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
-------------------------------------------
-- Скрипт восстанавливет одну базу данных из резервной копии другой базы на текущий момент времени ("перезаливает" базу).
-- Алгоритм пработы:
-- 1. Создается резервная копия базы-источнка с флагом "Только резервное копирование"
-- 2. Восстановливается база-назначения из полученой резервной копии
-- 3. База-назначения переводится в простую модель восстановления
-- 4. База-назначения сжимается
-- 5. Файл резервной копии удаляется
-- 6. Отправляется электронное сообщение о результате работы с использованием настроенного почтового профиля
-- Автор: Онянов Виталий (Tavalik.ru)
-- Версия от 20.05.2017
-- Свежие версии скриптов: https://github.com/Tavalik/SQL_TScripts
-------------------------------------------
-- НАСТРАИВАЕМЫЕ ПЕРЕМЕННЫЕ
-- База данных назначения
DECLARE @DBName_To as nvarchar(40) = 'TestBase'
-- База данных источник
DECLARE @DBName_From as nvarchar(40) = 'WorkBase'
-- Каталог для резервной копии
DECLARE @Path as nvarchar(400) = 'E:\Backup_SQL'
-- Имя почтового профиля, для отправки электонной почты
DECLARE @profile_name as nvarchar(100) = 'ОсновнойПрофиль'
-- Получатели сообщений электронной почты, разделенные знаком ";"
DECLARE @recipients as nvarchar(500) = '[email protected]'
-------------------------------------------
-- СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ
DECLARE @SQLString NVARCHAR(4000)
DECLARE @backupfile NVARCHAR(500)
DECLARE @physicalName NVARCHAR(500), @logicalName NVARCHAR(500)
DECLARE @out as int = 0
DECLARE @subject as NVARCHAR(100) = ''
DECLARE @finalmassage as NVARCHAR(1000) = ''
-------------------------------------------
-- ТЕЛО СКРИПТА
use master
-- 1. Создаем резервную копию с флагом "Только резервное копирование"
-- Формируем строку для исполнения
SET @backupfile = @Path + '\\' + @DBName_From + '_' + Replace(CONVERT(nvarchar, GETDATE(), 126),':','-') + '.bak'
SET @SQLString =
N'BACKUP DATABASE [' + @DBName_From + ']
TO DISK = N''' + @backupfile + '''
WITH NOFORMAT, NOINIT,
SKIP, NOREWIND, NOUNLOAD, STATS = 10, COPY_ONLY'
-- Выводим и выполняем полученную инструкцию
PRINT @SQLString
BEGIN TRY
EXEC sp_executesql @SQLString
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'ОШИБКА Создания резервной копии базы ' + @DBName_From
SET @finalmassage = 'Ошибка создания резервной копии базы ' + @DBName_From + ' в каталог ' + @Path + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL:' + CHAR(13) + @SQLString
END CATCH;
-- 2. Загружаем полученный файл резервной копии
IF @subject = ''
BEGIN
-- Формируем строку для исполнения
SET @SQLString =
N'RESTORE DATABASE [' + @DBName_To + ']
FROM DISK = N''' + @backupfile + '''
WITH
FILE = 1,'
-- Переименуем файлы базы данных на исходные
-- Новый цикл по всем файлам базы данных
DECLARE fnc CURSOR LOCAL FAST_FORWARD FOR
(
SELECT
t_From.name,
t_To.physical_name
FROM sys.master_files as t_To
join sys.master_files as t_From
on t_To.file_id = t_From.file_id
WHERE t_To.database_id = DB_ID(@DBName_To)
and t_From.database_id = DB_ID(@DBName_From)
)
OPEN fnc;
FETCH fnc INTO @logicalName, @physicalName;
WHILE @@FETCH_STATUS=0
BEGIN
SET @SQLString = @SQLString + '
MOVE N''' + @logicalName + ''' TO N''' + @physicalName + ''','
FETCH fnc INTO @logicalName, @physicalName;
END;
CLOSE fnc;
DEALLOCATE fnc;
SET @SQLString = @SQLString + '
RECOVERY,
REPLACE,
STATS = 5'
-- Выводим и выполняем полученную инструкцию
PRINT @SQLString
BEGIN TRY
EXEC sp_executesql @SQLString
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'ОШИБКА ВОССТАНОВЛЕНИЯ базы данных ' + @DBName_To
SET @finalmassage = 'Ошибка восстановления полной резервной копии для базы данных ' + @DBName_To + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL:' + CHAR(13) + @SQLString
END CATCH;
END
-- 3. Переводим базу в простую модель восстановления
IF @subject = '2'
BEGIN
-- Формируем строку для исполнения
SET @SQLString = 'ALTER DATABASE ' + @DBName_To + ' SET RECOVERY SIMPLE;'
-- Выводим и выполняем полученную инструкцию
PRINT @SQLString
BEGIN TRY
EXEC sp_executesql @SQLString
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'ОШИБКА ВОССТАНОВЛЕНИЯ базы данных ' + @DBName_To
SET @finalmassage = 'Ошибка перевода в простую модель восстановления базы данных ' + @DBName_To + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL:' + CHAR(13) + @SQLString
END CATCH;
END
-- 4. Запускаем сжатие базы данных
IF @subject = '2'
BEGIN
-- Формируем строку для исполнения
SET @SQLString = 'DBCC SHRINKDATABASE(N''' + @DBName_To + ''');'
-- Выводим и выполняем полученную инструкцию
PRINT @SQLString
BEGIN TRY
EXEC sp_executesql @SQLString
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'ОШИБКА ВОССТАНОВЛЕНИЯ базы данных ' + @DBName_To
SET @finalmassage = 'Ошибка сжатия базы данных ' + @DBName_To + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL:' + CHAR(13) + @SQLString
END CATCH;
END
-- 5. Если файл был создан, удалим файл резервной копии
BEGIN TRY
EXEC master.dbo.xp_fileexist @backupfile, @out out
IF @out = 1 EXEC master.dbo.xp_delete_file 0, @backupfile
END TRY
BEGIN CATCH
-- Ошбика выполнения операции
SET @subject = 'ОШИБКА ВОССТАНОВЛЕНИЯ базы данных ' + @DBName_To
SET @finalmassage = 'Ошибка удаления файла резервной копии ' + @backupfile + CHAR(13) + CHAR(13)
+ 'Код ошибки: ' + CAST(ERROR_NUMBER() as nvarchar(10)) + CHAR(13) + CHAR(13)
+ 'Текст ошибки: ' + ERROR_MESSAGE() + CHAR(13) + CHAR(13)
+ 'Текст T-SQL:' + CHAR(13) + 'master.dbo.xp_delete_file 0, ' + @backupfile
END CATCH;
-- Если ошибок не было, сформируем текст сообщения
IF @subject = ''
BEGIN
-- Успешное выполнение всех операций
SET @subject = 'Успешное восстановление базы данных ' + @DBName_To
SET @finalmassage = 'Успешное восстановление базы данных ' + @DBName_To + ' из резервной копии базы данных ' + @DBName_From
END
-- 6. Если задан профиль электронной почты, отправим сообщение
IF @profile_name <> ''
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @profile_name,
@recipients = @recipients,
@body = @finalmassage,
@subject = @subject;
-- Выводим сообщение о результате
SELECT
@subject as subject,
@finalmassage as finalmassage
GO