为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 .NET Core 中恢复 SQL Server 备份

如何在 .NET Core 中恢复 SQL Server 备份

C#
慕侠2389804 2021-06-04 13:04:38
我想.bak使用 .NET Core还原 SQL Server 数据库 ( )。这是我在GitHub 上的空网站,因此您可以查看当前配置。在完整的 .NET Framework 中恢复数据库相当简单 - 正如这里所见。有没有办法直接从 .NET Core 执行此操作,还是需要引用 .NET Framework 并使用 .NET Framework 类库?无论我如何尝试,我都无法让它发挥作用。编辑我尝试添加 SQLManagementObject,但不能。我在 .NET Core 2.0 上。编辑 2我们的旧项目主要是 ADO.NET。他们(广泛地)使用以下我无法带入我的 .NET Core 项目的 DLL:Microsoft.SqlServer.ConnectionInfo微软.SqlServer.SmoMicrosoft.SqlServer.SmoExtendedMicrosoft.SqlServer.Management.Sdk.Sfc
查看完整描述

2 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

您不应该使用 SMO,SMO 是为那些想要在“管理 SQL 服务器类型应用程序”中管理 SQL 服务器的人创建的,您一定会遇到使用简单 TSQL 命令时不会遇到的版本控制问题。TSQL 命令在 .net Core 上运行良好。

我想提到的一件事是,您正在向某些令人不安的权限开放您的应用程序。

  1. 您需要将您的数据库设置为单用户模式,然后才能恢复您的数据库,当您这样做时,您的网络用户将能够继续执行它正在执行的操作(更新、删除、插入)所有这些都会改变事务日志并将搞砸了一些事情(选择退出某些合法选项,付款,取消某些东西......)。

  2. 您对 Web 用户能够将其设置为单用户模式或恢复数据库感到满意,这可能是非常恶意的吗?

  3. 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;

如果源在磁带上或托管在AmazonMicrosoft云中,这两种方法都将失败。


查看完整回答
反对 回复 2021-06-05
  • 2 回答
  • 0 关注
  • 308 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信