Trove/snapshot-design
- Launchpad Entry: Reddwarf:server-templates
- Created: 2013年2月13日
- Contributors: Don Kehn (dkehn)
目录
备份设计
概述
此蓝图的目标是在 Reddwarf 中实现支持 DbaaS 备份的功能,这些功能可用于支持数据库功能(例如备份、克隆等)。这将支持 Reddwarf API(guest_agent),并提供支持以一致的 DB 视图中的快照,以便可以将其用于复制设置、Master DB 的克隆和/或备份,以便可以执行按时间点还原。
有很多方法可以实现备份设计,例如:带有 master-data 选项的 mysqldump,Percona 的 XtraBackup,Openstack 的卷快照等。每种方法都有其优点和缺点。因此,本文档中提出的设计将提供一个可插拔接口,以便在开发功能时可以无需更改代码即可将其合并。某些实体的 SLA 可能只允许由于可接受的停机时间等原因而使用某种类型的快照。因此,为了提供最强大的快照实现,这种可插拔的 API 提供了最佳的解决方案。
设计目标
以下是设计目标
- 可插拔接口到较低的快照实现层,以支持多种快照机制,例如 Xtrabackup、mysqldump、Openstack 的 Volume 支持等。这将允许各种快照实现,这些实现可以定义不同的服务级别。例如
- 高可用性将使用 Xtrabackup
- 对于较低的服务级别,使用 mysqldump。
- 数据库支持与备份相关的信息,例如名称、备份时间、快照当前状态的信息、租户信息等。
- 使用 ACL 支持备份安全性和访问权限,从谁到哪个备份。
存储
生成的备份作为工件将被上传到 Swift。提交给 Reddwarf 的 Auth 令牌将被转发到 Swift,快照将位于用户 Swift 帐户中的容器中。假设用户在尝试创建快照时具有必要的 Swift 角色。Reddwarf 将在接受用户的创建请求之前,对 Swift 执行 HEAD 操作。
ACL 设计
ACL 将使用 Openstack Storage ACL。ACL 允许我们对单个对象和容器拥有更大的控制权,而无需完全的读取/写入访问特定容器的权限。访问控制是在容器基础上完成的,并在角色级别实现。当用户使用其所处的角色创建容器时,可以通过将其他角色添加到容器来授予其他用户访问权限。在我们的例子中,应用以下分层模式。从下面的图中可以看出,每个租户将有一个 BackupManager 角色,并且与该角色关联的可以有许多用户。每个用户都有能力在 swift 中创建快照对象,并访问它以从快照中恢复 VM 的数据库。这些用户必须在使用之前被预先分配到 BackupManager 的角色,并且由具有该租户管理职责的用户分配。这样我们可以确保租户之间的安全性和隔离性。
http://www.scion-eng.com/Pictures/hp/ACLPic1.jpg
请注意,要被授权执行备份和恢复的用户必须首先被分配到 BackupManager 角色,然后才能尝试备份或恢复。
分配到 BackupManager 角色后,用户可以使用其凭据创建备份并从先前创建的备份中恢复。此外,可以使用这些凭据获得的可用备份列表可以仅针对用户所属的租户获得。
可插拔接口
为了支持各种可能的快照机制,似乎最合理的方法是提供一个可插拔接口到这些底层功能,以便以最有效的方式扩展快照实现的 capabilities。将在 ~/reddwarf/reddwarf/guestagent/plugins 下创建一个目录,其中包含使用其特定实现方法(例如 xtrabackup、mysqldump、卷快照等)的各种快照实现。
在 Reddwarf API 的调用中,将公开一种类型,该类型将用于加载支持的实现。
数据库设计
为了支持快照,将在 Reddwarf 数据库中创建一个数据库表,以确定以下信息
- TENANT_ID - 这将是确定谁可以访问 Swift 中哪个快照的最精细的谓词。TENANT_ID、ROLE_ID、USER 和 PASSWORD 将是确定您是否可以访问 Swift 容器的必要元素。
- Name - 将代表快照的名称,将是唯一的。
- 快照的大小 - 这应该反映快照的整个大小。例如,如果快照由数据目录组成,则此大小应反映所有相关文件。
- 快照的时间戳 - 这将反映快照与从中获取的数据库一致的时间点。
- 快照的状态 - 这应该指示快照的当前状态。在快照过程中,代理程序将通过此状态更新以反映状态。可能的状态是
- started - 表示 API 和代理程序具有请求并正在启动。
- running - 表示代理程序正在执行快照,鉴于数据库的大小,这可能是快照请求的一种状态一段时间。
- completed - 表示快照已完成,容器位于 Swift 中。
- failed - 表示发生错误,请参阅“备注”部分以获取有关故障的详细信息。
数据库表的示例和定义如下
DROP TABLE IF EXISTS snapshot;
CREATE TABLE backups (
id int(10)unsigned NOT NULL auto_increment,
name varchar(128) NOT NULL DEFAULT '',
location varchar(1024) NOT NULL DEFAULT '',
tenant_id varchar(36) NOT NULL DEFAULT '00000000-0000-0000-000000000000',
bkup_type varchar(32) NOT NULL DEFAULT '',
size float unsigned not null DEFAULT 0.0,
deleted tinyint(1) NOT NULL DEFAULT 0,
created_ts timestamp NOT NULL DEFAULT "0000-00-00 00:00:00",
deleted_ts timestamp NOT NULL DEFAULT "0000-00-00 00:00:00",
state varchar(32) NOT NULL DEFAULT 'started',
last_updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY (name, tenant_id),
KEY idx_location(location),
KEY idx_bkup_type(bkup_type)
) ENGINE=ENGINE_INNODB DEFAULT CHARSET=utf8;
- id - 主键。
- name - 唯一名称,用于在租户中标识快照。
- location - 这标识了 Swift 系统中快照的位置,以便于检索。
- tenant_id - 这是 36 个字符的 TENANT_ID。
- bkup_type - 定义快照的表示方式,例如 Xtrabackup、mysqldump、LVM 等。
- size - 快照的总大小(以字节为单位),对于 xtrabackup,这是所有子目录的总和等。
- deleted - 1 = 已删除,快照已从 Swift 系统中删除,0 = 此快照位于 Swift 系统中。
- create_ts - 创建快照的时间戳。
- deleted_ts - 删除快照的时间戳。
- state - 状态表示快照的实际状态,这应该指示快照的当前状态。在快照过程中,代理程序将通过此状态更新以反映状态。可能的状态是
- started - 表示 API 和代理程序具有请求并正在启动快照过程。
- running - 实际快照正在进行中。
- completed - 快照已完成,快照过程已完成。
- failed - 表示发生错误,请参阅“备注”列以获取有关故障的详细信息。
- notes - 这是一个自由文本区域,用于提供有关故障性质或“started”和“running”状态期间的进一步状态信息的更多信息,将在状态为“completed”时包含快照操作的总运行时间。
- last_updated - 将保存此记录的上次更新的时间戳。
Xtrabackup 的状态图
为了演示代码结构,以下图表中显示了各种过程的状态图
使用 Xtrabackup 请求备份
备份请求图
使用 Xtrabackup 请求恢复
恢复快照
备份列表列表
列出备份
API 规范
创建备份
作为 Reddwarf 用户,我需要能够将我的实例备份到我的 Swift 帐户中,以便我可以备份实例中的所有 MySQL 数据。
POST /backups 创建新的实例备份。
参数
name - 可选 - 如果未指定名称,将自动填充一个
instanceid - 要从中创建备份的实例的 ID
description - 可选 - 备份的描述
请求体:
{
"backup" : {
"name":"My Backup"
"instanceid":"4c6ad8e3-d857-46e2-aca4-dcbbfdab8526"
"description" : "Backups for my production database."
}
}
响应
{
"backup": {
"id" : "56b80958-cf34-4e9e-b5b0-b84fbe5e4ecc"
"name" : "My Snapshot",
"locationRef" : "https:/<service>/<api version>/<account>/<container>/<snapshot>",
"status" : "STARTED"
}
}
列出所有备份
作为 Reddwarf 用户,我需要能够查看所有实例的所有可用备份的列表,以便我可以轻松地找到跨所有实例之前保存的数据。
GET /backups 列出给定租户 ID 的所有备份。
响应
{
"backups": [
{
"id" : "56b80958-cf34-4e9e-b5b0-b84fbe5e4ecc"
"name" : "My Backup",
"description" : "Backups for my production database."
"locationRef" : "https:/<service>/<api version>/<account>/<container>/<backup>",
"instanceRef" : "https://service/v1.0/1234/instances/28d1b8f3-172a-4f6d-983d-36021508444a"
"created" : "2012-03-28T21:31:02Z"",
"updated" : "2012-03-28T21:34:25Z",
"status" : "COMPLETED",
},
{
"id" : "56b80958-cf34-4e9e-b5b0-b84fbe5e4eea"
"name" : "My other backup",
"description" : "Backups for my production database."
"locationRef" : "https:/<service>/<api version>/<account>/<container>/<backup>",
"instanceRef" : "https://service/v1.0/1234/instances/28d1b8f3-172a-4f6d-983d-36021508444a"
"created" : "2012-03-28T21:31:02Z"",
"updated" : "2012-03-28T21:34:25Z",
"deleted" : "2012-03-28T21:34:25Z",
"status" : "DELETED",
},
{
"id" : "45x453467-df99-4j5k-a4a5-v873455e4wwt"
"name" : "My other backup",
"description" : "Backups for my production database."
"locationRef" : "https:/<service>/<api version>/<account>/<container>/<backup>",
"instanceRef" : "https://service/v1.0/1234/instances/28d1b8f3-172a-4f6d-983d-36021508444a"
"created" : "2012-03-28T21:31:02Z"",
"updated" : "2012-03-28T21:34:25Z",
"status" : "FAILED",
}
]
}
列出指定实例的备份
作为 Reddwarf 用户,我需要能够查看单个实例的可用备份列表,以便我可以找到实例之前保存的数据。
GET /instance/instanceId/backups 返回实例的备份列表
与列出所有租户备份相同
删除备份
作为 Reddwarf 用户,我需要能够删除备份或多个备份,以便我可以删除不再需要的 Swift 帐户中的数据以节省空间/金钱。
DELETE /backups/{uid} 删除指定的备份
从备份创建实例
作为 Reddwarf 用户,我需要能够从快照创建新的 Reddwarf 实例,以便我可以快速创建现有数据库实例的副本。
POST /instances 创建新的数据库实例。
新属性
snapshotRef -
响应代码:与当前调用相同
错误代码:与当前调用相同
描述
请求体
{
"instance": {
"flavorRef": "https://service//v1.0/1234/flavors/1",
"name": "my_db_inst",
"volume": {
"size": 2
}
"restorePoint" : {
"backupRef": "https://service/v1.0/1234/snapshots/56b80958-cf34-4e9e-b5b0-b84fbe5e4ecc" | '56b80958-cf34-4e9e-b5b0-b84fbe5e4ecc'
}
}
响应
{
"instance": {
"created": "2012-01-25T21:53:09Z",
"flavor": {
"id": "1",
"links": [
...
]
},
"hostname": "192.168.1.1",
"id": "dea5a2f7-3ec7-4496-adab-0abb5a42d635",
"links": [
...
],
"name": "my_db_inst",
"status": "BUILD",
"updated": "2012-01-25T21:53:10Z",
"volume": {
"size": 2
}
}