Câu trả lời:
Tôi, cá nhân, sử dụng sp_restorecriptgenie của Paul Brewer. Đây là liên kết đến bài viết SCC có nó. Trong phần 'Thủ tục'
http://www.sqlservercentral.com/articles/Restore+database/95839/
Về cơ bản, một khi bạn xây dựng thủ tục được lưu trữ, chỉ cần chạy exec sp_restorescriptgenie
và tập lệnh sẽ ra ngoài và nhận tất cả các bản sao lưu cho mỗi DB (ngay cả nhật ký giao dịch) và cung cấp cho bạn một tập lệnh để tạo chúng. Đồng thời tạo các lệnh DBCC CHECKDB để kiểm tra các DB sau khi khôi phục.
Tôi thực sự chỉ sử dụng tập lệnh này khoảng một giờ trước để tôi có thể thực hiện khôi phục thử nghiệm và xác minh bản sao lưu của mình.
Có một kịch bản rất tốt trên liên kết dưới đây:
Cách tạo tập lệnh khôi phục cơ sở dữ liệu trong SQL Server
Dựa trên tập lệnh đó, tôi đã tạo thủ tục lưu trữ của mình bên dưới, hoạt động rất tốt, mặc dù nó không tạo ra DBCC CHECKDB:
nó cần 3 tham số:
@Database sysname - the database name you want to generate the restore
@MovePathLog NVARCHAR(1008) - where to move the transaction log file to
@MovePathData NVARCHAR(1008) - where to move the data file(s) to
Đây là mã:
use master
go
IF OBJECT_ID('sp_genRestoreScripts') IS NOT NULL
DROP PROCEDURE sp_genRestoreScripts
GO
create procedure sp_genRestoreScripts
@Database sysname,
@MovePathLog NVARCHAR(1008),
@MovePathData NVARCHAR(1008)
as begin
DECLARE @FullMediaSetID NVARCHAR(20)
DECLARE @BackupSetID NVARCHAR(20)
DECLARE @FullPath NVARCHAR(400)
DECLARE @FullPosition NVARCHAR(20)
DECLARE @LogMediaSetID NVARCHAR(20)
DECLARE @LogPath NVARCHAR(400)
DECLARE @LogPosition NVARCHAR(20)
DECLARE @DiffMediaSetID NVARCHAR(20)
DECLARE @DiffPath NVARCHAR(400)
DECLARE @DiffPosition NVARCHAR(20)
DECLARE @SQLMove NVARCHAR(MAX)
SET @SQLMove =''
IF ( @MovePathData <> '' OR @MovePathLog <> '')
BEGIN
DECLARE @LogicalName NVARCHAR(200)
DECLARE @FileID NVARCHAR(10)
DECLARE @FileType NVARCHAR(10)
DECLARE @ExtName NVARCHAR(20)
DECLARE MoveCur CURSOR FOR
SELECT m.name
,m.file_id
,m.type
FROM sys.master_files m
INNER JOIN sys.databases d
ON m.database_id = d.database_id
WHERE d.name = @Database
OPEN MoveCur
FETCH NEXT FROM MoveCur INTO @LogicalName,@FileID,@FileType
WHILE @@FETCH_STATUS = 0
BEGIN
SET @ExtName = CASE
WHEN @FileID = 1 THEN '.mdf'
WHEN @FileID > 1 THEN CASE @FileType
WHEN 0 THEN '.ndf'
ELSE '.ldf'
END
END
SET @SQLMove = @SQLMove + CHAR(10) + ' , MOVE ' + '''' + @LogicalName + ''''
+ ' TO ' + '''' +
CASE @FileType
WHEN 0 THEN @MovePathData
ELSE @MovePathLog
END
+ @LogicalName + @ExtName + ''''
FETCH NEXT FROM MoveCur INTO @LogicalName,@FileID,@FileType
END
CLOSE MoveCur
DEALLOCATE MoveCur
END
SELECT
@BackupSetID = backup_set_id,
@FullMediaSetID = media_set_id,
@FullPosition = position
FROM msdb.dbo.backupset
WHERE backup_set_id =
(
SELECT MAX(backup_set_id)
FROM msdb.dbo.backupset
WHERE database_name = @Database
AND type='D'
GROUP BY database_name
)
SELECT @FullPath = physical_device_name
FROM msdb.dbo.backupmediafamily
WHERE media_set_id = @FullMediaSetID
IF NOT EXISTS(SELECT 1 FROM msdb.dbo.backupset
WHERE database_name = @Database AND type IN('L','I') AND backup_set_id > @BackupSetID)
BEGIN
PRINT REPLICATE('-',200)
PRINT '-----------//Full backup restore only'
PRINT REPLICATE('-',200)
PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
+ ' FROM DISK = ''' + @FullPath + '''' + CHAR(10)
+ ' WITH FILE = ' + @FullPosition + ', REPLACE' + @SQLMove
END
IF EXISTS(SELECT 1 FROM msdb.dbo.backupset
WHERE database_name = @Database AND type='L' AND backup_set_id > @BackupSetID)
BEGIN
PRINT REPLICATE('-',200)
PRINT '-----------//Full backup and log backup restore '
PRINT REPLICATE('-',200)
PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
+ ' FROM DISK = ''' + @FullPath + '''' + CHAR(10)
+ ' WITH FILE = ' + @FullPosition + ', NORECOVERY, REPLACE ' + @SQLMove
DECLARE log_cursor CURSOR FOR
SELECT media_set_id
,position
FROM msdb.dbo.backupset
WHERE database_name = @Database
AND type='L'
AND backup_set_id > @BackupSetID
ORDER BY backup_set_id
OPEN log_cursor
FETCH NEXT FROM log_cursor INTO @LogMediaSetID,@LogPosition
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @LogPath = physical_device_name
FROM msdb.dbo.backupmediafamily
WHERE media_set_id = @LogMediaSetID
PRINT 'RESTORE Log ' + @Database + CHAR(10)
+ ' FROM DISK = ''' + @LogPath
+ ''' WITH FILE = ' + @LogPosition + ', NORECOVERY'
FETCH NEXT FROM log_cursor INTO @LogMediaSetID,@LogPosition
END
CLOSE log_cursor
DEALLOCATE log_cursor
PRINT 'RESTORE DATABASE ' + @Database + ' WITH RECOVERY '
END
IF EXISTS(SELECT 1 FROM msdb.dbo.backupset
WHERE database_name = @Database AND type='I' AND backup_set_id > @BackupSetID)
BEGIN
PRINT REPLICATE('-',200)
PRINT '-----------//Full backup and differential backup restore '
PRINT REPLICATE('-',200)
PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
+ ' FROM DISK = ''' + @FullPath + '''' + CHAR(10)
+ ' WITH FILE = ' + @FullPosition + ', NORECOVERY, REPLACE ' + @SQLMove
DECLARE diff_cursor CURSOR FOR
SELECT media_set_id
,position
FROM msdb.dbo.backupset
WHERE database_name = @Database
AND type='I'
AND backup_set_id > @BackupSetID
ORDER BY backup_set_id
OPEN diff_cursor
FETCH NEXT FROM diff_cursor INTO @DiffMediaSetID,@DiffPosition
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @DiffPath = physical_device_name
FROM msdb.dbo.backupmediafamily
WHERE media_set_id = @DiffMediaSetID
PRINT 'RESTORE DATABASE ' + @Database + CHAR(10)
+ ' FROM DISK = ''' + @DiffPath
+ ''' WITH FILE = ' + @DiffPosition + ', NORECOVERY'
FETCH NEXT FROM diff_cursor INTO @DiffMediaSetID,@DiffPosition
END
CLOSE diff_cursor
DEALLOCATE diff_cursor
PRINT 'RESTORE DATABASE ' + @Database + ' WITH RECOVERY '
END
end
GO
Đây là cách bạn chạy thủ tục cho một cơ sở dữ liệu:
use master
go
exec sp_genRestoreScripts
@Database ='CAAltosextracts',
@MovePathLog ='F:\logs\',
@MovePathData ='e:\DATA\'
và đối với nhiều cơ sở dữ liệu, tôi sử dụng thủ tục được lưu trữ sp_foreachdb
declare @db_list NVARCHAR(MAX)
SELECT @db_list = STUFF((
SELECT ', ' + name FROM sys.databases
WHERE name NOT IN ('DBA','TABLEBACKUPS','MASTER','MSDB','MODEL','TEMPDB')
FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '')
--exec sp_foreachdb @database_list = @db_list
-- ,@command='use ?; print db_name() + char(13)'
exec sp_foreachdb @database_list = @db_list
,@command='
exec sp_genRestoreScripts
@Database =[?],
@MovePathLog =''F:\logs\'',
@MovePathData =''E:\DATA\''
'
@Database sysname
đó là 128 ký tự. Bạn có muốn tên cơ sở dữ liệu lớn hơn 128? Không cám ơn.
Tôi đang di chuyển SQL Server DB sang một phiên bản mới.
Bạn có thể sử dụng dbatools - Copy-DbaDatabase để sao lưu / khôi phục từ một nguồn tới nhiều đích .
Ngoài ra, để khôi phục dbatools - Khôi phục-DbaDatabase - cho phép bạn chỉ đến một vị trí sao lưu hoặc Tin tưởng vào lịch sử sao lưu msdb của bạn để xây dựng các lệnh và cũng cho phép bạn thực hiện khôi phục thời gian. Nó tự động tìm ra đầy đủ, khác biệt và tlogs.
Bạn thậm chí có thể tạo tập lệnh khôi phục của mình bằng cách sử dụng Xuất-DbaScript sang tệp.
Lưu ý: Tôi đã sử dụng cả dbatools và sp_restoreGene - cả hai đều thực sự tốt. Điểm cộng của dbatools là bạn có thể sử dụng các lệnh ghép ngắn khác cho toàn bộ quản lý máy chủ của mình.