SQL Server 备份到 URL

本主题介绍使用 Azure Blob 存储服务作为备份目标所需的概念、要求和组件。 备份和还原功能与使用磁盘或磁带时相同,或类似但区别不大。 区别均为显著的例外,并且本主题中包括少量代码示例。

要求、组件和概念

本节内容:

安全性

以下是备份到 Azure Blob 存储服务或从 Azure Blob 存储服务还原时的安全注意事项和要求。

  • 为 Azure Blob 存储服务创建容器时,建议将访问权限设置为 专用。 将访问权限设置为“私有”后,只允许可提供对 Azure 帐户进行身份验证所需的信息的用户或帐户进行访问。

    重要

    SQL Server要求将 Azure 帐户名称和访问密钥身份验证存储在SQL Server凭据中。 此信息用于在执行备份或还原操作时向 Azure 帐户进行身份验证。

  • 用于发出 BACKUP 或 RESTORE 命令的用户帐户应属于具有“更改任意凭据”权限的 db_backup 操作员数据库角色。

关键组件和概念简介

以下两部分介绍了 Azure Blob 存储服务,以及备份到 Azure Blob 存储服务或从中进行还原时使用的 SQL Server 组件。 了解这些组件以及它们之间的交互对备份到 Azure Blob 存储服务或从中进行还原来说至关重要。

创建 Azure 帐户是这个过程的第一步。 SQL Server使用 Azure 存储帐户名称及其访问密钥值进行身份验证,以及向存储服务写入和读取 Blob。 SQL Server 凭据存储此身份验证信息,并且将在备份或还原期间使用这些信息。 有关创建存储帐户和执行简单还原的完整演练,请参阅教程使用 Azure 存储服务进行SQL Server备份和还原

将存储帐户映射到 sql 凭据

Azure Blob 存储服务

存储帐户: 存储帐户是所有存储服务的起始点。 若要访问Azure Blob 存储服务,请先创建一个 Azure 存储帐户。 需要存储帐户名称及其访问密钥属性才能对Azure Blob 存储服务及其组件进行身份验证。

容器: 容器提供一组 Blob 的分组,并且可以存储无限数量的 Blob。 若要将SQL Server备份写入 Azure Blob 服务,必须至少创建根容器。

Blob: 任意类型和大小的文件。 可将两类 Blob 存储到 Azure 存储服务中:块 Blob 和页 Blob。 SQL Server 备份使用页 Blob 作为 Blob 类型。 Blob 可使用以下 URL 格式进行寻址:https://< storage account.blob.core.windows.net/>< container>/<blob>

Azure Blob 存储

有关 Azure Blob 存储服务的详细信息,请参阅如何使用Azure Blob 存储服务

有关页 Blob 的详细信息,请参阅了解块和页 Blob

SQL Server 组件

URL: URL 指定统一资源标识符 (URI) 来标识唯一备份文件。 URL 用于提供 SQL Server 备份文件的位置和名称。 在此实现中,唯一有效的 URL 是指向 Azure 存储帐户中的页 Blob 的 URL。 该 URL 必须指向实际 Blob,而不仅仅是容器。 如果 Blob 不存在,则创建它。 如果指定了现有 Blob,除非指定了“WITH FORMAT”选项,否则 BACKUP 将失败。

警告

如果选择将备份文件复制并上传到 Azure Blob 存储服务,请使用页 blob 作为存储选项。 不支持从块 Blob 进行还原。 从块 blob 类型 RESTORE 将出错并且失败。

下面是一个示例 URL 值:http[s]://ACCOUNTNAME.Blob.core.windows.net/< CONTAINER>/<FILENAME.bak>。 HTTPS 不是必需的,但建议这样做。

凭据: SQL Server 凭据是用于存储连接到 SQL Server 外部资源所需的身份验证信息的对象。 此处,SQL Server备份和还原过程使用凭据向 Azure Blob 存储服务进行身份验证。 凭据存储着存储帐户的名称和存储帐户的 access key 值。 创建凭据后,在发出 BACKUP/RESTORE 命令时必须在 WITH CREDENTIAL 选项中指定它。 有关如何查看、复制或重新生成存储帐户 访问密钥的详细信息,请参阅 存储帐户访问密钥

有关如何创建SQL Server凭据的分步说明,请参阅本主题后面的创建凭据示例。

有关凭据的一般信息,请参阅 凭据

有关使用凭据的其他示例的信息,请参阅创建SQL Server 代理代理

限制

  • 不支持备份到高级存储。

  • 支持的最大备份大小为 1 TB。

  • 可使用 TSQL、SMO 或 PowerShell cmdlet 发出备份或还原语句。 当前未启用使用 Azure Blob 存储服务备份或还原SQL Server Management Studio备份或还原向导。

  • 不支持创建逻辑设备名称。 因此,不支持使用 sp_dumpdevice 或通过 SQL Server Management Studio 将 URL 添加为备份设备。

  • 不支持追加到现有备份 blob。 只能使用 WITH FORMAT 选项覆盖到现有 Blob 的备份。

  • 不支持在单个备份操作中备份到多个 blob。 例如,下面的代码将返回错误:

    BACKUP DATABASE AdventureWorks2012
    TO URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012_1.bak'
       URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012_2.bak'
          WITH CREDENTIAL = 'mycredential'
         ,STATS = 5;  
    GO
    
  • 不支持使用 BACKUP 指定块大小。

  • 不支持指定 MAXTRANSFERSIZE

  • 不支持指定备份集选项 - RETAINDAYSEXPIREDATE

  • SQL Server 要求备份设备名称最多包含 259 个字符。 对于用于指定 URL“https://.blob.core.windows.net//.bak”所需的元素,BACKUP TO URL 占用 36 个字符,其余 223 个字符将用于帐户、容器和 Blob 名称。

对备份/还原语句的支持

备份/还原语句 支持 例外 注释
BACKUP 不支持 BLOCKSIZE 和 MAXTRANSFERSIZE。 要求指定 WITH CREDENTIAL
RESTORE 要求指定 WITH CREDENTIAL
RESTORE FILELISTONLY 要求指定 WITH CREDENTIAL
RESTORE HEADERONLY 要求指定 WITH CREDENTIAL
RESTORE LABELONLY 要求指定 WITH CREDENTIAL
RESTORE VERIFYONLY 要求指定 WITH CREDENTIAL
RESTORE REWINDONLY

有关备份语句的语法和一般信息,请参阅 BACKUP (Transact-SQL)

有关还原语句的语法和一般信息,请参阅 RESTORE (Transact-SQL)

对备份参数的支持

参数 支持 异常 注释
DATABASE
LOG
TO (URL) 与 DISK 和 TAPE 不同,URL 不支持指定或创建逻辑名称。 此参数用于指定备份文件的 URL 路径。
MIRROR TO
WITH 选项:
CREDENTIAL 仅当使用 BACKUP TO URL 选项备份到 Azure Blob 存储服务时,才支持 WITH CREDENTIAL。
DIFFERENTIAL
COPY_ONLY
COMPRESSION|NO_COMPRESSION
DESCRIPTION
名称
EXPIREDATE | RETAINDAYS
NOINIT | INIT 如果使用,则忽略此选项。

不能追加到 blob。 要覆盖备份,请使用 FORMAT 参数。
NOSKIP | SKIP
NOFORMAT | FORMAT 如果使用,则忽略此选项。

除非指定 WITH FORMAT,否则对现有 blob 的备份失败。 指定 WITH FORMAT 时,覆盖现有 blob。
MEDIADESCRIPTION
MEDIANAME
BLOCKSIZE
BUFFERCOUNT
MAXTRANSFERSIZE
NO_CHECKSUM | CHECKSUM
STOP_ON_ERROR | CONTINUE_AFTER_ERROR
统计信息
REWIND | NOREWIND
UNLOAD | NOUNLOAD
NORECOVERY | STANDBY
NO_TRUNCATE

有关备份参数的详细信息,请参阅 BACKUP (Transact-SQL)

对还原参数的支持

参数 支持 例外 注释
DATABASE
LOG
FROM (URL) FROM URL 参数用于指定备份文件的 URL 路径。
WITH Options:
CREDENTIAL 仅当使用 RESTORE FROM URL 选项从Azure Blob 存储服务还原时,才支持 WITH CREDENTIAL。
PARTIAL
RECOVERY | NORECOVERY | STANDBY
LOADHISTORY
MOVE
REPLACE
RESTART
RESTRICTED_USER
文件
PASSWORD
MEDIANAME
MEDIAPASSWORD
BLOCKSIZE
BUFFERCOUNT
MAXTRANSFERSIZE
CHECKSUM | NO_CHECKSUM
STOP_ON_ERROR | CONTINUE_AFTER_ERROR
FILESTREAM
统计信息
REWIND | NOREWIND
UNLOAD | NOUNLOAD
KEEP_REPLICATION
KEEP_CDC
ENABLE_BROKER | ERROR_BROKER_CONVERSATIONS | NEW_BROKER
STOPAT | STOPATMARK | STOPBEFOREMARK

有关还原参数的详细信息,请参阅 RESTORE 参数 (Transact-SQL)

使用 SQL Server Management Studio 中的备份任务

SQL Server Management Studio 中的备份任务已得到增强,以包括 URL 作为目标选项之一,以及备份到 Azure 存储所需的其他支持对象,例如 SQL 凭据。

以下步骤介绍对备份数据库任务所做的更改,以允许备份到 Azure 存储:

  1. 启动 SQL Server Management Studio 并连接到 SQL Server 实例。 选择要备份的数据库,右键单击“ 任务”,然后选择“ 备份”。。这将打开“备份数据库”对话框。

  2. 在常规页上, URL 选项用于创建 Azure 存储的备份。 选择此选项后,将看到此页上启用其他选项:

    1. 文件名: 备份文件的名称。

    2. SQL 凭据: 可指定现有的 SQL Server 凭据,也可通过单击“SQL 凭据”框旁的 “创建” ,新建一个。

      重要

      单击 “创建” 打开的对话框需要管理证书或订阅的发布配置文件。 SQL Server 当前支持发布配置文件版本 2.0。 要下载支持的发布配置文件版本,请参阅 下载发布配置文件 2.0

      如果您无权访问管理证书或发布配置文件,可以创建一个 SQL 凭据,方法是使用 Transact-SQL 或 SQL Server Management Studio 指定存储帐户名称和访问密钥信息。 请参阅 创建凭据 部分中的示例代码,以使用 Transact-SQL 创建凭据。 或者,使用 SQL Server Management Studio,从数据库引擎实例中右键单击 “安全性”,依次选择 “新建”“凭据”。 在 “标识” 字段中指定存储帐户名称,在 “密码” 字段中指定访问密钥。

    3. Azure 存储容器: 用于存储备份文件的 Azure 存储容器的名称。

    4. URL 前缀: 使用在上一步中所述的字段中指定的信息自动生成此信息。 如果手动编辑此值,则确保它与以前提供的其他信息相匹配。 例如,如果修改存储 URL,则确保设置 SQL 凭据以向同一存储帐户进行身份验证。

选择 URL 作为目标后,将禁用“媒体选项”页中的某些选项。 以下主题详细介绍“备份数据库”对话框:

备份数据库(“常规”页)

备份数据库(“介质选项”页)

备份数据库(“备份选项”页)

创建凭据 - 向 Azure 存储进行身份验证

使用维护计划向导将 SQL Server 备份到 URL

与前面所述的备份任务类似,SQL Server Management Studio 中的维护计划向导已得到增强,以包含 URL 作为目标选项之一,以及备份到 Azure 存储所需的其他支持对象(如 SQL 凭据)。 有关详细信息,请参阅使用维护计划向导中的定义备份任务部分。

使用 SQL Server Management Studio 从 Azure 存储还原

如果要还原数据库,则加入 URL 作为要从其进行还原的设备。 以下步骤介绍还原任务中允许从 Azure 存储还原的更改:

  1. 在 SQL Server Management Studio 中还原任务的 “常规” 页中选择 “设备” 后,将进入 “选择备份设备” 对话框,其中包括 “URL” 作为备份介质类型。

  2. 选择 “URL” 并单击 “添加”时,将打开 “连接到 Azure 存储” 对话框。 指定要向 Azure 存储进行身份验证的 SQL 凭据信息。

  3. 然后,SQL Server使用提供的 SQL 凭据信息连接到 Azure 存储,并打开“在 Azure 中查找备份文件”对话框。 此页上显示位于存储中的备份文件。 选择要用于还原的文件,然后单击 “确定” 。 这会返回到“选择备份设备”对话框,单击此对话框上的“确定”将返回到“main还原”对话框,你将能够在其中完成还原。 有关详细信息,请参阅以下主题:

    还原数据库(“常规”页)

    还原数据库(“文件”页)

    还原数据库(“选项”页)

代码示例

本节包含以下示例。

创建凭据

以下示例创建一个凭据,用于存储 Azure 存储身份验证信息。

IF NOT EXISTS  
(SELECT * FROM sys.credentials   
WHERE credential_identity = 'mycredential')  
CREATE CREDENTIAL mycredential WITH IDENTITY = 'mystorageaccount'  
,SECRET = '<storage access key>' ;  
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  
string secret = "<storage access key>";  

// Create a Credential  
string credentialName = "mycredential";  
Credential credential = new Credential(server, credentialName);  
credential.Create(identity, secret);  
# create variables  
$storageAccount = "mystorageaccount"  
$storageKey = "<storage access key>"  
$secureString = ConvertTo-SecureString $storageKey  -asplaintext -force  
$credentialName = "mycredential"  

$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTANCENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# Create a credential  
New-SqlCredential -Name $credentialName -Path $srvpath -Identity $storageAccount -Secret $secureString

备份整个数据库

以下示例将 AdventureWorks2012 数据库备份到 Azure Blob 存储服务。

BACKUP DATABASE AdventureWorks2012   
TO URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012.bak'   
      WITH CREDENTIAL = 'mycredential'   
      ,COMPRESSION  
      ,STATS = 5;  
GO
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url  
string url = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup to Url  
Backup backup = new Backup();  
backup.CredentialName = credentialName;  
backup.Database = dbName;  
backup.CompressionOption = BackupCompressionOptions.On;  
backup.Devices.AddDevice(url, DeviceType.Url);  
backup.SqlBackup(server);  
# create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTANCENAME"   
# for default instance, the $srvpath varilable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# navigate to SQL Server Instance  
CD $srvPath   
$backupFile = $backupUrlContainer + "AdventureWorks2012" +  ".bak"  
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName -CompressionOption On

备份数据库和日志

下面的示例备份 AdventureWorks2012 示例数据库,默认情况下,该数据库使用简单恢复模式。 若要支持日志备份,请将 AdventureWorks2012 数据库改为使用完整恢复模式。 然后,该示例创建 Azure Blob 的完整数据库备份,并在更新活动一段时间后备份日志。 此示例将创建具有日期时间戳的备份文件名。

-- To permit log backups, before the full database backup, modify the database   
-- to use the full recovery model.  
USE master;  
GO  
ALTER DATABASE AdventureWorks2012  
   SET RECOVERY FULL;  
GO  

-- Back up the full AdventureWorks2012 database.  
       -- First create a file name for the backup file with DateTime stamp  

DECLARE @Full_Filename AS VARCHAR (300);  
SET @Full_Filename = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012_Full_'+   
REPLACE (REPLACE (REPLACE (CONVERT (VARCHAR (40), GETDATE (), 120), '-','_'),':', '_'),' ', '_') + '.bak';   
--Back up Adventureworks2012 database  

BACKUP DATABASE AdventureWorks2012  
TO URL =  @Full_Filename  
WITH CREDENTIAL = 'mycredential';  
,COMPRESSION  
GO  
-- Back up the AdventureWorks2012 log.  
DECLARE @Log_Filename AS VARCHAR (300);  
SET @Log_Filename = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012_Log_'+   
REPLACE (REPLACE (REPLACE (CONVERT (VARCHAR (40), GETDATE (), 120), '-','_'),':', '_'),' ', '_') + '.trn';  
BACKUP LOG AdventureWorks2012  
 TO URL = @Log_Filename  
 WITH CREDENTIAL = 'mycredential'  
 ,COMPRESSION;  
GO  
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url for data backup  
string urlDataBackup = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}_Data-{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup Database to Url  
Backup backupData = new Backup();  
backupData.CredentialName = credentialName;  
backupData.Database = dbName;  
backup.CompressionOption = BackupCompressionOptions.On;  
backupData.Devices.AddDevice(urlDataBackup, DeviceType.Url);  
backupData.SqlBackup(server);  

// Generate Unique Url for data backup  
string urlLogBackup = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}_Log-{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup Database Log to Url  
Backup backupLog = new Backup();  
backupLog.CredentialName = credentialName;  
backupLog.Database = dbName;  
backup.CompressionOption = BackupCompressionOptions.On;  
backupLog.Devices.AddDevice(urlLogBackup, DeviceType.Url);  
backupLog.Action = BackupActionType.Log;  
backupLog.SqlBackup(server);  
#create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTANCENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# navigate to theSQL Server Instance
CD $srvPath   
#Create a unique file name for the full database backup  
$backupFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".bak"  

#Backup Database to URL
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName -CompressionOption On -BackupAction Database    

#Create a unique file name for log backup  

$backupFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".trn"  

#Backup Log to URL
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName -CompressionOption On -BackupAction Log

创建主文件组的完整文件备份

下面的示例创建主文件组的完整文件备份。

--Back up the files in Primary:  
BACKUP DATABASE AdventureWorks2012  
    FILEGROUP = 'Primary'  
    TO URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012files.bck'  
    WITH CREDENTIAL = 'mycredential'  
    ,COMPRESSION;  
GO  
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url  
string url = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-{3}.bck",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup to Url  
Backup backup = new Backup();  
backup.CredentialName = credentialName;  
backup.Database = dbName;  
backup.Action = BackupActionType.Files;  
backup.DatabaseFileGroups.Add("PRIMARY");  
backup.CompressionOption = BackupCompressionOptions.On;  
backup.Devices.AddDevice(url, DeviceType.Url);  
backup.SqlBackup(server);
#create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTANCENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# navigate to the SQL Server Instance  

CD $srvPath   
#Create a unique file name for the file backup  
$backupFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".bck"  

#Backup Primary File Group to URL  

Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName -CompressionOption On -BackupAction Files -DatabaseFileGroup Primary

创建主文件组的差异文件备份

下面的示例创建主文件组的差异文件备份。

--Back up the files in Primary:  
BACKUP DATABASE AdventureWorks2012  
    FILEGROUP = 'Primary'  
    TO URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012filesdiff.bck'  
    WITH   
       CREDENTIAL = 'mycredential'  
       ,COMPRESSION  
   ,DIFFERENTIAL;  
GO
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url  
string url = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup to Url  
Backup backup = new Backup();  
backup.CredentialName = credentialName;  
backup.Database = dbName;  
backup.Action = BackupActionType.Files;  
backup.DatabaseFileGroups.Add("PRIMARY");  
backup.Incremental = true;  
backup.CompressionOption = BackupCompressionOptions.On;  
backup.Devices.AddDevice(url, DeviceType.Url);  
backup.SqlBackup(server); 
#create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMUTERNAME\INSTANCENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# navigate to SQL Server Instance
CD $srvPath   

#create a unique file name for the full backup  
$backupdbFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".bak"  

#Create a differential backup of the primary filegroup
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName -CompressionOption On -BackupAction Files -DatabaseFileGroup Primary -Incremental

还原数据库并移动文件

要还原完整数据库备份并将还原的数据库移到 C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Data 目录,请使用以下步骤。

-- Backup the tail of the log first
DECLARE @Log_Filename AS VARCHAR (300);  
SET @Log_Filename = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012_Log_'+   
REPLACE (REPLACE (REPLACE (CONVERT (VARCHAR (40), GETDATE (), 120), '-','_'),':', '_'),' ', '_') + '.trn';  
BACKUP LOG AdventureWorks2012  
 TO URL = @Log_Filename  
 WITH CREDENTIAL = 'mycredential'  
 ,NORECOVERY;  
GO  

RESTORE DATABASE AdventureWorks2012 FROM URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012.bak'  
WITH CREDENTIAL = 'mycredential'  
 ,MOVE 'AdventureWorks2012_data' to 'C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.mdf'  
 ,MOVE 'AdventureWorks2012_log' to 'C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.ldf'  
 ,STATS = 5
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url  
string urlBackupData = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-Data{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup to Url  
Backup backup = new Backup();  
backup.CredentialName = credentialName;  
backup.Database = dbName;  
backup.Devices.AddDevice(urlBackupData, DeviceType.Url);  
backup.SqlBackup(server);  

// Generate Unique Url for tail log backup  
string urlTailLogBackup = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-TailLog{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup Tail Log to Url  
Backup backupTailLog = new Backup();  
backupTailLog.CredentialName = credentialName;  
backupTailLog.Database = dbName;  
backupTailLog.Action = BackupActionType.Log;  
backupTailLog.NoRecovery = true;  
backupTailLog.Devices.AddDevice(urlTailLogBackup, DeviceType.Url);  
backupTailLog.SqlBackup(server);  

// Restore a database and move files  
string newDataFilePath = server.MasterDBLogPath  + @"\" + dbName + DateTime.Now.ToString("s").Replace(":", "-") + ".mdf";  
string newLogFilePath = server.MasterDBLogPath  + @"\" + dbName + DateTime.Now.ToString("s").Replace(":", "-") + ".ldf";  

Restore restore = new Restore();  
restore.CredentialName = credentialName;  
restore.Database = dbName;  
restore.ReplaceDatabase = true;  
restore.Devices.AddDevice(urlBackupData, DeviceType.Url);  
restore.RelocateFiles.Add(new RelocateFile(dbName, newDataFilePath));  
restore.RelocateFiles.Add(new RelocateFile(dbName+ "_Log", newLogFilePath));  
restore.SqlRestore(server);
#create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTNACENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# navigate to SQL Server Instance
CD $srvPath   

#create a unique file name for the full backup  
$backupdbFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".bak"  

# Full database backup to URL  
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupdbFile  -SqlCredential $credentialName -CompressionOption On      

#Create a unique file name for the tail log backup  
$backuplogFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".trn"  

#Backup tail log to URL
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName  -BackupAction Log -NoRecovery    

# Restore Database and move files
$newDataFilePath = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile ("AdventureWorks_Data","C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.mdf")  
$newLogFilePath = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("AdventureWorks_Log","C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.ldf")  

Restore-SqlDatabase -Database AdventureWorks2012 -SqlCredential $credentialName -BackupFile $backupdbFile -RelocateFile @($newDataFilePath,$newLogFilePath)

使用 STOPAT 还原到时间点

下面的示例将数据库状态还原到某个时间点并显示一个还原操作。

RESTORE DATABASE AdventureWorks FROM URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012.bak'   
WITH   
  CREDENTIAL = 'mycredential'  
 ,MOVE 'AdventureWorks2012_data' to 'C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.mdf'  
 ,Move 'AdventureWorks2012_log' to 'C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.ldf'  
 ,NORECOVERY  
 --,REPLACE  
 ,STATS = 5;  
GO   

RESTORE LOG AdventureWorks FROM URL = 'https://mystorageaccount.blob.core.windows.net/mycontainer/AdventureWorks2012.trn'   
WITH CREDENTIAL = 'mycredential'  
 ,RECOVERY   
 ,STOPAT = 'Oct 23, 2012 5:00 PM'   
GO  
// Connect to default sql server instance on local machine  
Server server = new Server(".");  
string identity = "mystorageaccount";  

string credentialName = "mycredential";  
string dbName = "AdventureWorks2012";  
string blobContainerName = "mycontainer";  

// Generate Unique Url  
string urlBackupData = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-Data{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup to Url  
Backup backup = new Backup();  
backup.CredentialName = credentialName;  
backup.Database = dbName;  
backup.Devices.AddDevice(urlBackupData, DeviceType.Url);  
backup.SqlBackup(server);  

// Generate Unique Url for Tail Log backup  
string urlTailLogBackup = String.Format(@"https://{0}.blob.core.windows.net/{1}/{2}-TailLog{3}.bak",  
         identity,  
         blobContainerName,  
         dbName,  
         DateTime.Now.ToString("s").Replace(":", "-"));  

// Backup Tail Log to Url  
Backup backupTailLog = new Backup();  
backupTailLog.CredentialName = credentialName;  
backupTailLog.Database = dbName;  
backupTailLog.Action = BackupActionType.Log;  
backupTailLog.NoRecovery = true;  
backupTailLog.Devices.AddDevice(urlTailLogBackup, DeviceType.Url);  
backupTailLog.SqlBackup(server);  

// Restore a database and move files  
string newDataFilePath = server.MasterDBLogPath + @"\" + dbName + DateTime.Now.ToString("s").Replace(":", "-") + ".mdf";  
string newLogFilePath = server.MasterDBLogPath + @"\" + dbName + DateTime.Now.ToString("s").Replace(":", "-") + ".ldf";  

Restore restore = new Restore();  
restore.CredentialName = credentialName;  
restore.Database = dbName;  
restore.ReplaceDatabase = true;  
restore.NoRecovery = true;  
restore.Devices.AddDevice(urlBackupData, DeviceType.Url);  
restore.RelocateFiles.Add(new RelocateFile(dbName, newDataFilePath));  
restore.RelocateFiles.Add(new RelocateFile(dbName + "_Log", newLogFilePath));  
restore.SqlRestore(server);  
   
// Restore transaction Log with stop at   
Restore restoreLog = new Restore();  
restoreLog.CredentialName = credentialName;  
restoreLog.Database = dbName;  
restoreLog.Action = RestoreActionType.Log;  
restoreLog.Devices.AddDevice(urlBackupData, DeviceType.Url);  
restoreLog.ToPointInTime = DateTime.Now.ToString();   
restoreLog.SqlRestore(server);
#create variables  
$backupUrlContainer = "https://mystorageaccount.blob.core.windows.net/mycontainer/"  
$credentialName = "mycredential"  
$srvPath = "SQLSERVER:\SQL\COMPUTERNAME\INSTANCENAME"  
# for default instance, the $srvpath variable would be "SQLSERVER:\SQL\COMPUTERNAME\DEFAULT"  

# Navigate to SQL Server Instance Directory
CD $srvPath   

#create a unique file name for the full backup  
$backupdbFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".bak"  

# Full database backup to URL  
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupdbFile  -SqlCredential $credentialName -CompressionOption On     

#Create a unique file name for the tail log backup  
$backuplogFile = $backupUrlContainer + "AdventureWorks2012_" + (Get-Date).ToString("s").Replace("-","_").Replace(":", "_").Replace(" ","_").Replace("/", "_") +  ".trn"  

#Backup tail log to URL
Backup-SqlDatabase -Database AdventureWorks2012 -backupFile $backupFile  -SqlCredential $credentialName  -BackupAction Log -NoRecovery     

# Restore Database and move files
$newDataFilePath = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile ("AdventureWorks_Data","C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.mdf")  
$newLogFilePath = New-Object Microsoft.SqlServer.Management.Smo.RelocateFile("AdventureWorks_Log","C:\Program Files\Microsoft SQL Server\myinstance\MSSQL\DATA\AdventureWorks2012.ldf")  

Restore-SqlDatabase -Database AdventureWorks2012 -SqlCredential $credentialName -BackupFile $backupdbFile -RelocateFile @($newDataFilePath,$newLogFilePath) -NoRecovery    

# Restore Transaction log with Stop At:  
Restore-SqlDatabase -Database AdventureWorks2012 -SqlCredential $credentialName -BackupFile $backuplogFile  -ToPointInTime (Get-Date).ToString()

另请参阅

从 SQL Server 备份到 URL 的最佳做法和故障排除
系统数据库的备份和还原 (SQL Server)