2 回答
TA贡献1757条经验 获得超8个赞
您不应该使用 SMO,SMO 是为那些想要在“管理 SQL 服务器类型应用程序”中管理 SQL 服务器的人创建的,您一定会遇到使用简单 TSQL 命令时不会遇到的版本控制问题。TSQL 命令在 .net Core 上运行良好。
我想提到的一件事是,您正在向某些令人不安的权限开放您的应用程序。
您需要将您的数据库设置为单用户模式,然后才能恢复您的数据库,当您这样做时,您的网络用户将能够继续执行它正在执行的操作(更新、删除、插入)所有这些都会改变事务日志并将搞砸了一些事情(选择退出某些合法选项,付款,取消某些东西......)。
您对 Web 用户能够将其设置为单用户模式或恢复数据库感到满意,这可能是非常恶意的吗?
Web 用户将需要提升权限才能完成此操作,我可以想象有人会使用它来将数据库备份到公共文件夹,然后只获取您的 Web 服务器。我们的防火墙日志每天都会显示这种类型的攻击媒介(“他们”不知道我们不使用它)。
如果您需要恢复数据库,您可能会将其传递给为此设置的另一个任务。然后你可以让这个“池任务”处理这个。
假设您接受我上面提到的我的担忧(不是一个完整的列表),并且您会接受想要卸载它的想法,我建议您为此使用 SQL 服务器中的任务。您可以安排这些任务永远运行......秒/分钟/天甚至循环它们。
您可以在任务中有“N”个步骤,1 个步骤用于“测试还原条件”,然后按照您用于以托管方式进行还原的步骤,完成后更新日志/发送邮件等等。
使用任务时,您可以使用具有适当权限的用户运行它,并且在单用户模式下设置数据库时,您的网站将失去连接,并将被迫等待还原作业以还原数据库状态。
为了能够使用 SQL 作业,您需要确保它在服务器上被激活。
根据您的任务内容,如果您希望 TSQL 语句看起来像这样,请注意您需要验证 SQL 服务器报告的备份文件是否确实存在,这使用了 master.sys.xp_cmdshell:
USE Master;
GO
SET NOCOUNT ON
-- 1 - Variable declaration
DECLARE @dbName sysname
DECLARE @backupPath NVARCHAR(500)
DECLARE @cmd NVARCHAR(500)
DECLARE @fileList TABLE (backupFile NVARCHAR(255))
DECLARE @lastFullBackup NVARCHAR(500)
DECLARE @lastDiffBackup NVARCHAR(500)
DECLARE @backupFile NVARCHAR(500)
-- 2 - Initialize variables
SET @dbName = 'Customer'
SET @backupPath = 'D:\SQLBackups\'
-- 3 - get list of files
SET @cmd = 'DIR /b "' + @backupPath + '"'
INSERT INTO @fileList(backupFile)
EXEC master.sys.xp_cmdshell @cmd
-- 4 - Find latest full backup
SELECT @lastFullBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.BAK'
AND backupFile LIKE @dbName + '%'
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + @lastFullBackup + ''' WITH NORECOVERY, REPLACE'
PRINT @cmd
-- 4 - Find latest diff backup
SELECT @lastDiffBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.DIF'
AND backupFile LIKE @dbName + '%'
AND backupFile > @lastFullBackup
-- check to make sure there is a diff backup
IF @lastDiffBackup IS NOT NULL
BEGIN
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + @lastDiffBackup + ''' WITH NORECOVERY'
PRINT @cmd
SET @lastFullBackup = @lastDiffBackup
END
-- 5 - check for log backups
DECLARE backupFiles CURSOR FOR
SELECT backupFile
FROM @fileList
WHERE backupFile LIKE '%.TRN'
AND backupFile LIKE @dbName + '%'
AND backupFile > @lastFullBackup
OPEN backupFiles
-- Loop through all the files for the database
FETCH NEXT FROM backupFiles INTO @backupFile
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'RESTORE LOG [' + @dbName + '] FROM DISK = '''
+ @backupPath + @backupFile + ''' WITH NORECOVERY'
PRINT @cmd
FETCH NEXT FROM backupFiles INTO @backupFile
END
CLOSE backupFiles
DEALLOCATE backupFiles
-- 6 - put database in a useable state
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] WITH RECOVERY'
PRINT @cmd
一种更安全的方法是查询服务器并希望该位置有效:
SELECT
bs.database_name,
bs.backup_start_date,
bmf.physical_device_name
FROM
msdb.dbo.backupmediafamily bmf
JOIN
msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE
bs.database_name = 'MyDB'
ORDER BY
bmf.media_set_id DESC;
如果源在磁带上或托管在Amazon或Microsoft云中,这两种方法都将失败。
- 2 回答
- 0 关注
- 308 浏览
添加回答
举报