将 SQL Server 备份到 S3 兼容的对象存储的 URL

适用于:SQL Server 2022 (16.x) 及更高版本

本文介绍了使用 S3 兼容对象存储作为备份目的地的概念、要求和所需的组件。 备份和还原功能在概念上类似于使用 SQL Server 备份到 Azure Blob 存储的 URL 作为备份设备类型。

有关支持平台的信息,请参阅 S3 兼容对象存储的提供商

概述

SQL Server 2022 (16.x) 为数据平台引入了对象存储集成,使你能够将 SQL Server 与 S3 兼容对象存储以及 Azure 存储集成。 为了提供此集成,SQL Server 支持 S3 连接器,该连接器使用 S3 REST API 连接到任意 S3 兼容对象存储的提供商。 SQL Server 2022 (16.x) 通过添加对 REST API 的新 S3 连接器的支持来扩展现有BACKUP/RESTORETO/FROM URL 语法。

指向 S3 兼容资源的 URL 以 s3:// 为前缀,以表示正在使用 S3 连接器。 以 s3:// 开头的 URL 始终假定基础协议为 https

部件编号和文件大小限制

为了存储数据,S3 兼容对象存储提供商必须将文件拆分成多个称为部件的块,类似于 Azure Blob 存储中的块 blob

每个文件最多可拆分 10,000 个部分,每个部件大小范围为 5 MB 到 20 MB,此范围由 T-SQL BACKUP 命令通过参数 MAXTRANSFERSIZE 控制。 MAXTRANSFERSIZE 的默认值为 10 MB,因此每个部件的默认大小为 10 MB。 虽然此值指定 最大 传输大小,但不能保证每个发送的部件为 10 MB。 部件的大小受数据相邻的影响。 例如,如果有 4 MB 的数据与 2 MB 的数据相邻,则在达到 5 MB 的最低大小部分后发送 6 MB。 或者,如果相邻数据量为 12 MB,则发送最大大小 (10 MB) 以内的数据,剩余的 2 MB 将在下一部分中发送。 S3 连接器始终尝试发送可能的最大数据大小,但永远不会超过 MAXTRANSFERSIZE 该值。

单个文件的最大支持大小为 10,000 个部分 * MAXTRANSFERSIZE,如果需要备份更大的文件,必须将其拆分/分布为最多 64 个 URL。 文件的最终最大支持大小为 10,000 个部件 * MAXTRANSFERSIZE * URL 数

注意

需要使用 COMPRESSION 才能更改 MAXTRANSFERSIZE 值。

S3 终结点的先决条件

必须配置 S3 端点,如下所示:

  • 必须配置 TLS。 假设所有连接通过 HTTPS 而不是 HTTP 进行安全传输。 端点将由安装在 SQL Server OS 主机上的证书进行验证。
  • 在 S3 兼容的对象存储上创建的凭据具有执行操作所需的适当权限。 在存储层上创建的用户和密码命名为 Access Key IDSecret Key ID。 需要同时对 S3 终结点进行身份验证。
  • 至少配置一个桶。 无法从 SQL Server 2022 (16.x) 创建或配置存储桶。

安全性

备份权限

若要将 SQL Server 连接到与 S3 兼容的对象存储,需要建立两组权限,一组权限在 SQL Server 上,另一组在存储层上。

在SQL Server,用于颁发BACKUP或RESTORE命令的用户帐户应位于具有更改任何凭据权限的db_backupoperator数据库角色中。

在存储层上:

  • 在 AWS S3 中,创建一个自定义角色并具体声明 S3 API 需要访问权限。 备份和还原需要以下权限:ListBucket(浏览)、PutObject(写入 - 进行备份)。
  • 在其他 S3 兼容存储中,用户 (Access Key ID) 必须同时拥有 ListBucket 和 WriteOnly 权限。

还原权限

如果还原的数据库不存在,则用户必须具有 CREATE DATABASE 能够执行 RESTORE的权限。 如果数据库存在,RESTORE其权限默认授予给 sysadmindbcreator 固定服务器角色的成员以及数据库所有者(dbo)。

RESTORE 权限授予的角色,其成员信息始终可供服务器随时获取。 由于只有在数据库可访问且未损坏时才能检查固定数据库角色的成员身份,而执行 RESTORE 时并非总能满足这一条件,因此 db_owner 固定数据库角色的成员不具有 RESTORE 权限。

在存储层上:

  • 在 AWS S3 中,创建一个自定义角色并具体声明 S3 API 需要访问权限。 备份和还原需要以下权限:ListBucket(浏览)、GetObject(读取 - 用于还原)。
  • 在其他 S3 兼容存储中,用户 (Access Key ID) 必须同时拥有 ListBucket 和 ReadOnly 权限。

受支持的功能

BACKUPRESTORE 所支持功能的简要概述:

  1. 每个 URL 的单个备份文件最多可以达到 200,000 MiB(其中 MAXTRANSFERSIZE 设置为 20 MB)。
  2. 备份最多可以条带化为 64 个 URL。
  3. 支持镜像,但仅支持跨 URL 镜像。 不支持同时使用 URL 和 DISK 进行镜像。
  4. 支持并推荐压缩。
  5. 支持加密。
  6. 从具有 S3 兼容对象存储的 URL 还原没有大小限制。
  7. 在还原数据库时,MAXTRANSFERSIZE 的值由备份阶段分配的值决定。
  8. 可以指定虚拟主机或路径样式格式的 URL。
  9. 支持 WITH CREDENTIAL
  10. 支持 REGION 且默认值为 us-east-1
  11. MAXTRANSFERSIZE 的大小从 5 MB 到 20 MB 不等。10 MB 是 S3 连接器的默认值。

支持的备份和还原语句

声明 S3 终结点 备注
BACKUP 是的
RESTORE 是的
RESTORE FILELISTONLY 是的
RESTORE HEADERONLY 是的
RESTORE LABELONLY 是的
RESTORE VERIFYONLY 是的
RESTORE REWINDONLY

备份的支持参数

WITH 选项 S3 终结点 备注
BLOCKSIZE 是的 MAXTRANSFERSIZE 确定部件大小。
BUFFERCOUNT 是的
COMPRESSION 是的
COPY_ONLY 是的
CREDENTIAL 是的
DESCRIPTION 是的
DIFFERENTIAL 是的
ENCRYPTION 是的
FILE_SNAPSHOT
MAXTRANSFERSIZE 是的 从 5 MB(5,242,880 字节)到 20 MB(20,971,520 字节),默认值为 10 MB(10,485,760 字节)。
MEDIADESCRIPTION 是的
MEDIANAME 是的
MIRROR TO 是的 仅与另一个 URL 配合使用,不支持带有 MIRRORURLDISK
NAME 是的
NOFORMAT / FORMAT 是的
NOINIT / INIT 不支持追加操作。 若要覆盖备份,请使用 WITH FORMAT
NO_CHECKSUM / CHECKSUM 是的
NO_TRUNCATE 是的
REGION 是的 默认值是 us-east-1。 必须与 BACKUP_OPTIONS 一起使用。
STATS 是的

还原的支持参数

WITH 选项 S3 终结点 备注
BLOCKSIZE 是的 MAXTRANSFERSIZE 确定部件大小。
BUFFERCOUNT
CHECKSUM / NO_CHECKSUM 是的
CREDENTIAL 是的
ENABLE_BROKER / ERROR_BROKER_CONVERSATIONS / NEW_BROKER 是的
FILE RESTORE FROM URL 不支持的逻辑名称。
FILESTREAM 是的
KEEP_CDC 是的
KEEP_REPLICATION 是的
LOADHISTORY 是的
MAXTRANSFERSIZE
MEDIANAME 是的
MEDIAPASSWORD 在 SQL Server 2012 之前的版本中进行的某些备份是必需的。
MOVE 是的
PARTIAL 是的
PASSWORD 在 SQL Server 2012 之前的版本中进行的某些备份是必需的。
RECOVERY / NORECOVERY / STANDBY 是的
REGION 是的 默认值是 us-east-1。 必须与 RESTORE_OPTIONS 一起使用。
REPLACE 是的
RESTART 是的
RESTRICTED_USER 是的
REWIND / NOREWIND
STATS 是的
STOP_ON_ERROR / CONTINUE_AFTER_ERROR 是的
STOPAT / STOPATMARK / STOPBEFOREMARK 是的
UNLOAD / NOUNLOAD

区域

您的 S3 兼容对象存储提供程序可以提供确定存储桶位置的特定区域的功能。 使用此可选参数可以通过指定特定存储桶属于哪个区域来提供更大的灵活性。 此参数需要将 WITHBACKUP_OPTIONSRESTORE_OPTIONS 一起使用。 这些选项要求以 JSON 格式声明值。 这样,S3 兼容的存储提供程序就可以具有相同的通用 URL,但分布在多个区域。 在这种情况下,备份或还原命令会指向指定区域,而无需更改 URL。

如果未声明任何值,us-east-1 将指定为默认值。

备份示例:

WITH BACKUP_OPTIONS = '{"s3": {"region":"us-west-1"}}'

还原示例:

WITH RESTORE_OPTIONS = '{"s3": {"region":"us-west-1"}}'

Linux 支持

SQL Server 使用 WinHttp 来实现其使用的 HTTP REST API 的客户端。 它依赖 OS 证书存储来验证由 http(s) 端点提供的 TLS 证书。 但是,Linux 上的 SQL Server CA 必须放在 /var/opt/mssql/security/ca-certificates 处创建的预定义位置,此文件夹只存储和支持前 50 个证书。 在启动 SQL Server 进程之前,CA 必须就位。

SQL Server 在启动期间从文件夹中读取证书,并将其添加到信任存储中。

只有超级用户才能在文件夹中写入,而 mssql 用户必须能够读取。

不支持的功能

  • 不支持使用非安全 http URL 备份到与 S3 兼容的对象存储。 客户负责用 https URL 设置其 S3 主机,此端点由安装在 SQL Server OS 主机上的证书进行验证。
  • SQL Server Express 和 SQL Server Express 使用高级服务的版本不支持备份到与 S3 兼容的对象存储。

限制

以下是目前使用 S3 兼容对象存储进行备份和还原的限制:

  • 由于 S3 Standard REST API 的当前限制,在 BACKUP T-SQL 命令运行期间,因正在进行的分段上传操作而在客户的 S3 兼容对象存储中创建的临时未提交数据文件,在发生备份失败时不会被删除。 如果 T-SQL 命令失败或取消, BACKUP 这些未提交的数据块将继续保留在与 S3 兼容的对象存储中。 如果备份成功,对象存储会自动移除这些临时文件,从而形成最终的备份文件。 某些 S3 兼容存储提供程序将通过其垃圾回收器系统处理临时文件。
  • URL 总长度限制为 259 个字符。 完整的字符串包含在此限制中,包括 s3:// 连接器名称。 因此,可用限制为 254 个字符。 但是,我们建议坚持采用 200 个字符的限制,以允许可能引入查询参数。
  • SQL 凭据名称的限制为 128 个 UTF-16 格式的字符。
  • 密钥 ID 不得包含 : 字符。

路径样式和虚拟主机样式

备份到 S3 支持以路径样式或虚拟主机样式写入 URL。

路径样式示例:s3://<endpoint>:<port>/<bucket>/<backup_file_name>

虚拟主机示例:s3://<bucket>.<domain>/<backup_file_name>

示例

创建凭据

  • 凭证的名称应提供存储路径,有多个标准,具体取决于存储平台。
  • 使用 S3 连接器时,IDENTITY 应始终为 'S3 Access Key'
  • 访问密钥 ID 和密钥 ID 不得包含冒号。 访问密钥 ID 和密钥 ID 是在 S3 兼容的对象存储中创建的用户和密码。
  • 仅允许字母数字值。
  • 访问密钥 ID 必须对 S3 兼容的对象存储具有适当的权限。

用于 CREATE CREDENTIAL 创建服务器级凭据,以便通过与 S3 兼容的对象存储终结点进行身份验证。

USE [master];
CREATE CREDENTIAL [s3://<endpoint>:<port>/<bucket>]
WITH
        IDENTITY    = 'S3 Access Key',
        SECRET      = '<AccessKeyID>:<SecretKeyID>';
GO

BACKUP DATABASE [SQLTestDB]
TO      URL = 's3://<endpoint>:<port>/<bucket>/SQLTestDB.bak'
WITH    FORMAT /* overwrite any existing backup sets */
,       STATS = 10
,       COMPRESSION;

但是,AWS S3 支持两种不同的 URL 标准。

  • S3://<BUCKET_NAME>.S3.<REGION>.AMAZONAWS.COM/<FOLDER>(默认值)
  • S3://S3.<REGION>.AMAZONAWS.COM/<BUCKET_NAME>/<FOLDER>

有多种方法可以成功为 AWS S3 创建凭证。

-- S3 bucket name: datavirtualizationsample
-- S3 bucket region: us-west-2
-- S3 bucket folder: backup

CREATE CREDENTIAL [s3://datavirtualizationsample.s3.us-west-2.amazonaws.com/backup]
WITH    
        IDENTITY    = 'S3 Access Key'
,       SECRET      = 'accesskey:secretkey';
GO

BACKUP DATABASE [AdventureWorks2022]
TO URL  = 's3://datavirtualizationsample.s3.us-west-2.amazonaws.com/backup/AdventureWorks2022.bak'
WITH COMPRESSION, FORMAT, MAXTRANSFERSIZE = 20971520;
GO

或者,

CREATE CREDENTIAL [s3://s3.us-west-2.amazonaws.com/datavirtualizationsample/backup]
WITH    
        IDENTITY    = 'S3 Access Key'
,       SECRET      = 'accesskey:secretkey';
GO

BACKUP DATABASE [AdventureWorks2022]
TO URL  = 's3://s3.us-west-2.amazonaws.com/datavirtualizationsample/backup/AdventureWorks2022.bak'
WITH COMPRESSION, FORMAT, MAXTRANSFERSIZE = 20971520;
GO

备份到 URL

以下示例将在对象存储终结点执行完整数据库备份,此备份将跨多个文件进行条带化:

BACKUP DATABASE <db_name>
TO      URL = 's3://<endpoint>:<port>/<bucket>/<database>_01.bak'
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_02.bak'
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_03.bak'
--
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_64.bak'
WITH    FORMAT -- overwrite
,       STATS               = 10
,       COMPRESSION;

从URL恢复

以下示例从对象存储终结点位置执行数据库还原:

RESTORE DATABASE <db_name>
FROM    URL = 's3://<endpoint>:<port>/<bucket>/<database>_01.bak'
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_02.bak'
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_03.bak'
--
,       URL = 's3://<endpoint>:<port>/<bucket>/<database>_64.bak'
WITH    REPLACE -- overwrite
,       STATS  = 10;

加密和压缩选项

以下示例演示如何使用加密备份和还原 AdventureWorks2025 数据库,MAXTRANSFERSIZE 为 20 MB 和压缩:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = <password>;
GO

CREATE CERTIFICATE AdventureWorks2022Cert
    WITH SUBJECT = 'AdventureWorks2022 Backup Certificate';
GO
-- Backup database
BACKUP DATABASE AdventureWorks2022
TO URL = 's3://<endpoint>:<port>/<bucket>/AdventureWorks2022_Encrypt.bak'
WITH FORMAT, MAXTRANSFERSIZE = 20971520, COMPRESSION,
ENCRYPTION (ALGORITHM = AES_256, SERVER CERTIFICATE = AdventureWorks2022Cert)
GO

-- Restore database
RESTORE DATABASE AdventureWorks2022
FROM URL = 's3://<endpoint>:<port>/<bucket>/AdventureWorks2022_Encrypt.bak'
WITH REPLACE

使用地区配置进行备份和恢复

以下示例演示如何使用 AdventureWorks2025 备份和还原 REGION_OPTIONS 数据库:

可以在每个 BACKUP / RESTORE 命令中将区域参数化。 注意 BACKUP_OPTIONSRESTORE_OPTIONS 中的 S3 特定区域字符串,例如 '{"s3": {"region":"us-west-2"}}'。 默认区域为 us-east-1。 一个简单的示例:

-- Backup Database
BACKUP DATABASE AdventureWorks2022
TO URL = 's3://<endpoint>:<port>/<bucket>/AdventureWorks2022.bak'
WITH BACKUP_OPTIONS = '{"s3": {"region":"us-west-2"}}'

-- Restore Database
RESTORE DATABASE AdventureWorks2022
FROM URL = 's3://<endpoint>:<port>/<bucket>/AdventureWorks2022.bak'
WITH 
  MOVE 'AdventureWorks2022' 
  TO 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\AdventureWorks2022.mdf'
, MOVE 'AdventureWorks2022_log' 
  TO 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\AdventureWorks2022.ldf'
, RESTORE_OPTIONS = '{"s3": {"region":"us-west-2"}}'

例如:

-- S3 bucket name: datavirtualizationsample
-- S3 bucket region: us-west-2
-- S3 bucket folder: backup

CREATE CREDENTIAL   [s3://datavirtualizationsample.s3.amazonaws.com/backup]
WITH    
        IDENTITY    = 'S3 Access Key'
,       SECRET      = 'accesskey:secretkey';
GO

BACKUP DATABASE [AdventureWorks2022]
TO URL  = 's3://datavirtualizationsample.s3.amazonaws.com/backup/AdventureWorks2022.bak'
WITH
    BACKUP_OPTIONS = '{"s3": {"region":"us-west-2"}}' -- REGION AS PARAMETER)
, COMPRESSION, FORMAT, MAXTRANSFERSIZE = 20971520;
GO

RESTORE DATABASE AdventureWorks2022_1 
FROM URL = 's3://datavirtualizationsample.s3.amazonaws.com/backup/AdventureWorks2022.bak'
WITH 
  MOVE 'AdventureWorks2022' 
  TO 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\AdventureWorks2022_1.mdf'
, MOVE 'AdventureWorks2022_log' 
  TO 'C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\AdventureWorks2022_1.ldf'
, STATS = 10, RECOVERY
, REPLACE, RESTORE_OPTIONS = '{"s3": {"region":"us-west-2"}}'; -- REGION AS PARAMETER)
GO