在Azure平台上备份SQL Server 2012虚拟机中的数据

出于安全和隐私的考虑,最近不得不将一些多租户应用程序托管在不同的MS SQL数据库中。这些数据库本身托管在多个SQL 2012数据服务器上,运行在多个不同的虚拟机上。尽管市场上有许多优秀的数据库备份提供商,但没有一个定价模型适合特定配置,所以不得不自己构建一些东西。本文就是结果,希望它对其他人也有所帮助!

这里详细说明的方法基于“BACKUP TO URL”,这是在概述的。

设置

有一个核心数据库,其中包含一个表,列出了每个单独的客户数据库;这是起点。获取这些数据库的列表,并依次备份每一个。当然不需要这样做,如果愿意,可以直接枚举数据服务器中的所有数据库,这只是方法。要进行实际备份,使用增强的“BACKUP” SQL命令,允许使用URL作为目标设备。

远程备份“设备”所需的目标信息如下:

http[s]://ACCOUNTNAME.Blob.core.windows.net/<CONTAINER>/<FILENAME.bak>

相关部分是:

  • 需要输入Azure上的ACCOUNTNAME
  • 给出了一个容器名称(称之为"SQLBackup")
  • 给出了一个文件名(动态创建了一个)

完整的SQL很简单:

BACKUP DATABASE AdventureWorks2012 TO URL = 'https://ACCOUNTNAME.blob.core.windows.net/mycontainer/AdventureWorks2012_1.bak' WITH CREDENTIAL = 'mycredential', STATS = 5;

除了上述(1..3)项之外,还在命令中提供了一个“CREDENTIAL”。凭据是Azure上的ACCOUNTNAME加上blob容器共享密钥的细节。

要获取这两个,可以去Azure仪表板并获取密钥,方法是选择容器存储,然后点击屏幕底部的“管理密钥”

一旦有了密钥,就需要获取blob容器名称——这应该与存储帐户名称相同,如果不是,可以在blob仪表板的底部找到:

要创建一个名为“凭据”的凭据,需要运行以下SQL:

IF NOT EXISTS (SELECT * FROM sys.credentials WHERE credential_identity = 'MyCred') CREATE CREDENTIAL MyCred WITH IDENTITY = 'MyCred', SECRET = '[YOUR SECRET KEY]';

凭据“凭据”现在可以使用了。

为了能够运行测试,需要在blob容器中设置一个文件夹——称之为“SQLBackup”——愿意的话可以命名文件夹。

现在应该有足够的信息来运行测试了。让假设以下情况:

  • 数据库名称 = “数据库”
  • 凭据 = “凭据”
  • 存储容器 = “Azure存储”
  • 容器内的存储文件夹 = “SQLBackup”
  • 密钥 = “ABC123”

因此,测试命令如下:

BACKUP DATABASE MyDatabase TO URL = 'http://MyAzureStorage.blob.core.windows.net/sqlbackup/MyDatabase.bak' WITH CREDENTIAL = 'MyCred', COMPRESSION, STATS = 5;

如果运行它,应该看到类似这样的结果:

Processed 384 pages for database 'MyDatabase', file 'MyDatabase' on file 1. 100 percent processed. Processed 2 pages for database 'MyDatabase', file 'MyDatabase_log' on file 1. BACKUP DATABASE successfully processed 386 pages in 0.173 seconds (17.397 MB/sec).

可以通过查看Azure blob容器来确认数据是否正确传输。

全部放在一起

好的,这是痛苦的消除部分……让放在一起一个存储过程,它遍历每个数据库并备份它。逻辑如下:

  1. 创建一个临时表来存储数据库列表(如果存在,先删除它)
  2. 选择表数据并插入到临时表中。在案例中,存储了数据库名称和数据服务器名称,用冒号分隔,所以使用“CharIndex”函数首先分割出想要的东西
  3. 然后使用表游标遍历临时表,构建一个执行字符串,由URL、文件名等组成

SQL如下:

CREATE PROCEDURE BackupToAzure AS BEGIN -- delete temp table if exists IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID('tempdb.dbo.#TablesToBackup')) BEGIN DROP TABLE #TablesToBackup END -- create temp table Create table #TablesToBackup(DBName nvarchar(100)) -- populate insert into #TablesToBackup select SUBSTRING(LinkName, CHARINDEX(':', LinkName)+1, 100) as DBaseName from ClientDatabases -- declare cursor set @C = cursor for select * from #TablesToBackup declare @F nvarchar(100) open @C while 0=0 begin fetch next from @C into @F if not (@@FETCH_STATUS = 0) break DECLARE @pathName NVARCHAR(512) DECLARE @CMD NVARCHAR(300) DECLARE @URL NVARCHAR(300) DECLARE @Break NVARCHAR(5) DECLARE @FileDate NVARCHAR(20) SET QUOTED_IDENTIFIER OFF Set @URL = 'https://MyAzureStorage.blob.core.windows.net/sqlbackup/' Set @Break = '_' Set @FileDate = Convert(varchar(8), GETDATE(), 112) + '.bak' Set @Cmd = @URL + @F + @Break + @FileDate BACKUP DATABASE @F TO URL = @Cmd WITH FORMAT, CREDENTIAL = 'MyCred', COMPRESSION, STATS = 5 SET QUOTED_IDENTIFIER ON end close @C deallocate @C DROP TABLE #TablesToBackup END

好的,几乎完成了。如果运行脚本,它将创建存储过程。当执行存储过程时,它将成功地遍历每个数据库并依次备份它们。

这很好,唯一的问题是不想手动运行存储过程,所以创建了一个计划任务来为执行它。在MS Management Studio中,选择SQL Server Agent,右键单击并创建新作业。

给作业一个名称。并添加一个新的“步骤”。选择存储过程所在的数据库非常重要,否则可能会得到一个错误。在“命令”框中,输入“EXEC”命令和存储过程的名称。

最后,创建一个新的SCHEDULE项目并填写想要的时间细节。

最后一件事是能够查看发生了什么——为此,需要访问作业历史。这可以通过右键单击作业任务来访问。历史记录提供了有关过程健康状况的信息。

唯一剩下的就是备份备份了!……目前正在测试RedGates的解决方案来备份包含所有客户数据的*blob容器*——随着看到长期结果,可能会报告。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485