跳转到: 导航, 搜索

Trove/snapshot-design

< Trove(重定向自 Snapshot-design)
  • Launchpad Entry: Reddwarf:server-templates
  • 创建时间: 2013年2月13日
  • 贡献者: Don Kehn (dkehn)

备份设计

概述

此蓝图的目标是在 Reddwarf 中实现支持 DbaaS 备份的功能,这些功能可用于支持数据库功能(即备份、克隆等)。这将支持 Reddwarf API(guest_agent),并提供支持以一致的 DB 视图中的快照,以便可以将其用于复制设置、Master DB 的克隆和/或备份,以便可以执行按时间点还原。

有很多方法可以实现备份设计,例如:带有 master-data 选项的 mysqldump,Perconas 的 XtraBackup,Openstack 的卷快照等。每种方法都有其优点和缺点。因此,本文档中提出的设计将提供一个可插拔接口,以便在开发功能时可以无需更改代码即可将其合并。某个实体的 SLA 可能只允许由于可接受的停机时间等原因使用某种类型的快照。因此,为了提供最强大的快照实现,这种可插拔的 API 提供了最佳实践。

设计目标

以下是设计目标

  • 可插拔接口到较低的快照实现层,以支持多种快照机制,例如 Xtrabackup、mysqldump、Openstack 的 Volume 支持等。这将允许各种快照实现,这些实现可以定义不同的服务级别。例如
    • 高可用性将使用 Xtrabackup
    • 对于较低的服务级别,使用 mysqldump。
  • 数据库支持有关备份的信息,例如名称、备份时间、有关快照当前状态的状态信息、租户信息等。
  • 使用 ACL 支持备份安全性和访问权限,从谁到哪个备份。

存储

生成的备份作为工件将被上传到 Swift。呈现给 Reddwarf 的 Auth 令牌将被转发到 Swift,并且快照将位于用户 Swift 帐户中的容器中。假设用户在尝试创建快照时具有必要的 Swift 角色。Reddwarf 将在接受用户的创建请求之前,对 Swift 执行 HEAD 请求。

ACL 设计

ACL 将使用 Openstack 存储 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 容器的必要元素。
  • 名称 - 将代表快照的名称,将是唯一的。
  • 快照大小 - 这将反映快照的整个大小。例如,如果快照由数据目录组成,则此大小应反映所有相关文件。
  • 快照时间戳 - 这将反映快照与从中获取的数据库一致的时间点。
  • 快照状态 - 这应该指示快照的当前状态。在快照过程中,代理程序将通过此状态更新以反映状态。可能的状态是
    • 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 发起备份请求

StateDiaSnapshotXtraRequest.jpg

备份请求图

使用 Xtrabackup 发起恢复请求

RestoreFromSnapshot.jpg

恢复快照

备份列表列表

SnapshotList.jpg

列出备份

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
    }
}