出于安全和隐私的考虑,最近不得不将一些多租户应用程序托管在不同的MS SQL数据库中。这些数据库本身托管在多个SQL 2012数据服务器上,运行在多个不同的虚拟机上。尽管市场上有许多优秀的数据库备份提供商,但没有一个定价模型适合特定配置,所以不得不自己构建一些东西。本文就是结果,希望它对其他人也有所帮助!
这里详细说明的方法基于“BACKUP TO URL”,这是在概述的。
有一个核心数据库,其中包含一个表,列出了每个单独的客户数据库;这是起点。获取这些数据库的列表,并依次备份每一个。当然不需要这样做,如果愿意,可以直接枚举数据服务器中的所有数据库,这只是方法。要进行实际备份,使用增强的“BACKUP” SQL命令,允许使用URL作为目标设备。
远程备份“设备”所需的目标信息如下:
http[s]://ACCOUNTNAME.Blob.core.windows.net/<CONTAINER>/<FILENAME.bak>
相关部分是:
完整的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”——愿意的话可以命名文件夹。
现在应该有足够的信息来运行测试了。让假设以下情况:
因此,测试命令如下:
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容器来确认数据是否正确传输。
好的,这是痛苦的消除部分……让放在一起一个存储过程,它遍历每个数据库并备份它。逻辑如下:
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容器*——随着看到长期结果,可能会报告。