Trove 复制 V2

包含您的 Launchpad 蓝图的 URL

https://blueprints.launchpad.net/trove/bp/replication-v2

Trove Juno 版本奠定了 Trove 复制支持的基础。V1 版本的复制专注于在 MySQL 5.5 中提供只读从库复制。对于 Kilo 版本的 V2 复制发布,复制将被扩展以提供 MySQL 复制中的手动故障转移支持,利用 MySQL 5.6 的最新复制功能。

问题描述

对于 OpenStack 的 Kilo 版本,Trove 复制支持将被扩展到在复制主库发生故障时支持手动故障转移。具体来说,这意味着用户可以指示 Trove 降级复制主库并将从库提升为新的主库。对于 V2,手动提升意味着用户需要执行一个操作来导致故障转移 - 一个检测故障并导致故障转移发生的组件不在 V2 的范围内。

提议的变更

支持的功能

  • 手动故障转移

  • 位于不同可用区的从库/主库

  • 自动生成从库以替换被提升为主库的从库

  • 自动生成的从库将创建在与被提升为主库的从库相同的可用区

  • 分配给已删除/降级的旧主库的公网 IP 将转移到新的主库

  • 被提升的从库的公网 IP 将转移到新的从库

  • 将使用 GTID 来促进主库提升(注意:这会将功能集限制为 MySQL 5.6 及更高版本)

  • 如果主库站点可访问,可以选择一个从库提升为新的主库,旧主库将被降级为从库。此操作将以防止数据丢失的方式进行。此操作对于在不中断服务的情况下调整主库大小很有用。

  • 可以删除主库站点,在这种情况下,Trove 将选择一个从库提升为新的主库(参见下面的 MASTER_PROMOTION_STRATEGY),并生成一个新的从库来替换被提升的从库。如果主库站点不可访问,它将被强制从 Trove/Nova 中删除;这是“故障转移”不可访问的主库的方式。

  • 删除时的新的主库选择过程具有以下 MASTER_PROMOTION_STRATEGY (CONF) 开关:MOST_RECENT:选择更新最快的从库作为新的主库,PROXIMATE_AZ:选择与主库在同一可用区的更新最快的从库作为新的主库,PROXIMATE_REGION:选择与主库在同一区域的更新最快的从库作为新的主库。PROXIMATE_REGION 将是默认设置(尽管目前等同于 MOST_RECENT),并且可能是 V2 中唯一实现的选项。

  • 将实现基于现有备份和增量快照的复制

  • 将向 create-instance 添加 replica_count 选项,以允许从给定的快照启动 N 个从库。来自给定快照的所有副本将具有相同的“create-instance”选项。

不支持的功能

  • 自动故障转移

  • 区域支持

  • 可写从库

  • 与 MySQL 5.6 之前的版本相关的从库提升功能将不受支持

  • 每个数据存储的复制策略 - 这可以在 Kilo 中通过一个独立的蓝图来实现

  • 基于 GTID 的 MariaDB 复制(binlog 复制不会针对 MariaDB 进行测试,但应与 MySQL 兼容)

  • 主机亲和力/反亲和力

  • 处理在主库上直接执行更新时创建的“错误事务”,这些更新与主库上的更改冲突。直接在从库上执行更新不受 Trove 支持,从库站点将被置于“只读”模式。

复制 V2 组件

V2 复制功能将由几个组件组成

  • 实现新的复制策略以支持基于 GTID 的复制,以及 binlog 复制。

  • 从复制主库手动故障转移

  • 基于现有备份的增量快照的复制配置。

  • 单次调用创建多个从库

从 Binlog 复制升级到基于 GTID 的复制

MySQL 5.6 引入了一种基于全局事务 ID (GTID) 的新型复制。通过为每个事务分配 GTID,MySQL 能够简化主库和从库之间的事务协调,从而实现更简单、更可靠的故障转移到新的主库。

此功能要求 trove-integration 项目升级到使用 Ubuntu 14.04 和 MySQL 5.6。

将创建一个名为“MysqlGTIDReplicationStrategy”的新复制策略来支持 MySQL 5.6 及更高版本的基于 GTID 的新复制,现有的名为“MysqlBinlogReplication”的复制策略将继续支持 MySQL 5.5,但不支持本文档中列出的新功能。

从复制主库手动故障转移

用户可以通过执行 Trove 命令来导致从库成为复制的新主库。对于复制的 V2 版本,将不提供检测主库故障条件的功能。

为了帮助用户最大限度地减少数据丢失,将有两种不同的方式来导致从库被提升为新的主库。如果用户希望提升从库以替换健康且可访问的主库,他们将对从库执行一个新的“promote_to_replica_source”函数以取代现有的主库;此函数将与主库站点协调,以确保不会丢失任何数据。如果主库站点不可访问,用户将使用“eject_replica_source”函数从复制集中删除该实例,复制策略将选择更新最快的从库提升为新的主库;此操作可能会导致在主库站点上提交但未复制到任何从库的任何事务丢失。Trove 不允许删除可访问的主库站点,因为这会不必要地导致数据丢失。

不会采取任何措施来允许用户或操作员“修复”与主库站点不同步的从库。相反,将尽一切努力配置复制,以防止从库与主库不同步。将设置以下 MySQL 选项以确保安全复制

主库选项

  • 将为 MIXED 模式日志配置二进制日志。这将允许在安全的情况下使用基于语句的复制,并在必要时使用基于行的复制。

  • 将使用 enforce_gtid_consistency 选项来防止与 GTID 复制使用冲突的语句。

  • 当使用 Percona 数据库时,将使用 Percona enforce_storage_engine 选项来限制复制到 InnoDB 存储引擎。这是为了防止使用 MyISAM 表,这些表在崩溃恢复期间可能会损坏。

从库选项

  • 从库将在 READ_ONLY 模式下执行,以避免主库和从库之间的事务冲突。默认情况下,用户没有数据库的 root 访问权限;如果他们选择启用 root 访问权限,则假定他们足够高级,不会执行会扰乱复制的从库上的操作。

  • 从库的中继日志将存储在数据库中的表中,以在数据库中执行的语句和记录从库执行中继日志的位置之间提供事务一致性。

  • 将启用中继日志恢复,以便在 mysql 启动期间进行中继日志恢复。为了支持 relay_log_recovery,将启用 relay_log_purge。

提升从库为新的主库

用户可以选择一个从库提升为复制集的新主库。此操作将包括以下步骤

  1. 联系每个从库,如果任何一个不可访问则中止操作

  2. 使旧主库变为只读

  3. 分离旧主库的公网 IP

  4. 分离主库候选者的公网 IP

  5. 记录主库的最新 GTID

  6. 对于每个从库(包括主库候选者)

    • 等待从库接收/应用主库的最新 GTID

  7. 将主库候选者设置为复制主库站点

  8. 对于每个剩余的从库

    • 使实例成为新主库的从库

  9. 使旧主库成为新主库的从库

  10. 将主库候选者的 IP 分配给旧主库(现在是从库)

  11. 使新主库可写

  12. 将旧主库的公网 IP 分配给新主库

提升为新的主库 API

为了替换健康的主库站点,将在客户端和任务管理器 API 中添加 promote_to_replica_source API 调用。

弹出主库站点

如果复制主库站点无法使用,用户可以选择将该实例“弹出”复制集。弹出不可访问的主库实例将导致其从库之一被选择提升为新的主库站点,并生成一个新的从库来填充复制集。弹出的主库将可供检查,但将不再参与复制。此操作将包括以下步骤

  1. 如果可以联系到主库站点,则中止操作

  2. 联系每个从库,如果任何一个不可访问则中止操作

  3. 分离主库的公网 IP

  4. 记录主库的区域/可用区

  5. 选择主库候选者(参见主库候选者选择)

  6. 将主库候选者从从库切换为新的主库

  7. 对于每个剩余的从库

    • 将从库连接到新的主库实例

  8. 将新主库标记为可写

  9. 将主库的公网 IP 附加到新的主库

  10. 在与旧主库相同的区域/可用区中创建新的从库

  11. 将主库候选者的公网 IP 分配给新的从库

主库候选者选择

在选择要提升为替换不可访问的主库站点的从库时,选择主库候选者的算法将由任务管理器配置的 MASTER_PROMOTION_STRATEGY 配置选项的值确定(不是特定于数据存储的)。此选项的可能值如下

策略

描述

MOST_RECENT

选择 GTID 最高的从库作为主库候选者

PROXIMATE_AZ

选择与旧主库在同一可用区的 GTID 最高的从库

PROXIMATE_REGION

选择与旧主库在同一区域的 GTID 最高的从库

PROXIMATE_REGION 设置将是默认设置,因为这将确保新的主库站点与旧主库位于同一区域;对于 Kilo 版本,这将等同于 MOST_RECENT 选项(并且可能以这种方式实现),因为 Trove 中未实现区域支持。

增量快照

为了提高从库创建的性能,默认操作将是获取最新的备份(完整或增量)并创建增量备份以用于复制快照。如果没有找到以前的备份,将创建完整的备份以包含在复制快照中。如果指定了“备份”选项以及“replica_of”选项,将从指示的备份执行增量备份。

多从库创建

将添加 replica_count 选项以支持从单个复制快照创建多个从库。

  • 将向 trove create 命令添加 replica_count 选项

  • 将向 taskmanager ReST API 的 create_instance 任务中添加 replica_count 参数

  • taskmanager FreshInstanceTasks.create_instance 方法将迭代地从单个复制快照创建指定的数量的从库(实施者可以并行实现从库创建,如果时间允许,并且应该调查这样做,但这对于 V2 来说不是必需的)

配置

将 MysqlGTIDReplicationStrategy 值添加到 MySQL 配置的 ReplicationStategy 选项中。

添加了新的配置选项 master_promotion_strategy 到 MySQL 配置,其值为上述值。

数据库

预计不会对数据库产生影响。

公共 API

提升为复制源

将向 Trove REST API 添加一个新的操作,以允许将副本提升为其复制集的主库

POST http://127.0.0.1:8779/v1.0/<tenant id>/instance/<instance id>/action
{
    *"promote_to_replica_source": null*
}

RESP: [200]
  {
      'date': '<date>',
      'content-length': '<RESP BODY len>',
      'content-type': 'application/json'
  }
RESP BODY:
  {
      "instance": {
          *"status": "PROMOTE",*
          "updated": "2014-11-25T21:25:11",
          "name": "m",
          "links": [
              {
                  "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/instances\/...",
                  "rel": "self"
              },
              {
                  "href": "https:\/\/10.40.10.178:8779\/instances\/...",
                  "rel": "bookmark"
              }
          ],
          "created": "2014-11-25T21:25:06",
          "ip": [
              "10.0.0.2"
          ],
          "replicas": [
              {
                  "id": "8e5710df-ef39-4201-a059-764d9091f079",
                  "links": [
                      {
                          "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/instances\/...",
                          "rel": "self"
                      },
                      {
                          "href": "https:\/\/10.40.10.178:8779\/instances\/...",
                          "rel": "bookmark"
                      }
                  ]
              }
          ],
          "id": "fff6d8c5-9d05-4a00-ab58-d8954ec945a3",
          "volume": {
              "used": 0.13,
              "size": 1
          },
          "flavor": {
              "id": "7",
              "links": [
                  {
                      "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/flavors\/7",
                      "rel": "self"
                  },
                  {
                      "href": "https:\/\/10.40.10.178:8779\/flavors\/7",
                      "rel": "bookmark"
                  }
              ]
          },
          "datastore": {
              "version": "5.5",
              "type": "mysql"
          }
      }
  }

将添加一个新的 CLI 命令来调用 promote_to_replica_source API

trove promote-to-replica-source <replica id>

弹出复制源

将向 Trove REST API 添加一个新的操作,以允许将复制源从复制集中弹出

POST http://127.0.0.1:8779/v1.0/<tenant id>/instance/<instance id>/action
{
    *"eject_replica_source": null*
}

RESP: [200]
  {
      'date': '<date>',
      'content-length': '<RESP BODY len>',
      'content-type': 'application/json'
  }
RESP BODY:
  {
      "instance": {
          *"status": "EJECT",*
          "updated": "2014-11-25T21:25:11",
          "name": "m",
          "links": [
              {
                  "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/instances\/...",
                  "rel": "self"
              },
              {
                  "href": "https:\/\/10.40.10.178:8779\/instances\/...",
                  "rel": "bookmark"
              }
          ],
          "created": "2014-11-25T21:25:06",
          "ip": [
              "10.0.0.2"
          ],
          "replicas": [
              {
                  "id": "8e5710df-ef39-4201-a059-764d9091f079",
                  "links": [
                      {
                          "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/instances\/...",
                          "rel": "self"
                      },
                      {
                          "href": "https:\/\/10.40.10.178:8779\/instances\/...",
                          "rel": "bookmark"
                      }
                  ]
              }
          ],
          "id": "fff6d8c5-9d05-4a00-ab58-d8954ec945a3",
          "volume": {
              "used": 0.13,
              "size": 1
          },
          "flavor": {
              "id": "7",
              "links": [
                  {
                      "href": "https:\/\/10.40.10.178:8779\/v1.0\/...\/flavors\/7",
                      "rel": "self"
                  },
                  {
                      "href": "https:\/\/10.40.10.178:8779\/flavors\/7",
                      "rel": "bookmark"
                  }
              ]
          },
          "datastore": {
              "version": "5.5",
              "type": "mysql"
          }
      }
  }

将添加一个新的 CLI 命令来调用 eject_replica_source API

trove eject-replica-source <replica source id>

Trove 创建副本计数

将使用新的字段 *replica_count* 增强 Trove REST API 的 create instance 操作,以指定要从指示的实例创建的副本数

POST http://127.0.0.1:8779/v1.0/<tenant id>/instances
{
    "instance": {
        "volume": {"size": 1},
        "flavorRef": "7",
        "name": "s",
        "replica_of": "<master id>",
        *"replica_count": "<n>"*
    }
}

RESP *unchanged*

将向“trove create”CLI 命令添加一个选项来指定新的副本计数选项

trove create <name> <flavor id> --replica_count=<count> ...

内部 API

将 promote_to_replica_source 方法添加到 taskmanager API。将 eject_replica_source 方法添加到 taskmanager API。

Guest Agent

此功能集的实现将导致对 MySQL guest agent 的许多添加。预计对现有代码的影响很小,并且预计不会对 API 的向后兼容性产生影响。

备选方案

无。

实现

负责人

主要负责人

vgnbkr

二级分配人

peterstac

里程碑

完成目标里程碑

Kilo-2

工作项

工作项

受让人

计划发布

GTID 支持

摩根

Kilo-3

故障切换

摩根

Kilo-3

从库数量

彼得

Kilo-3

增量快照

彼得

Kilo-3

依赖项

n/a

测试

现有集成测试被认为足以测试 GTID 复制的更改,因为没有功能更改,只有实现更改。

新的集成测试

晋升为主库(正向测试)

创建一个包含两个站点的新复制集。为每个实例附加浮动 IP 地址。执行 promote_to_replica_source API 调用,并验证主/从关系是否已正确更改,以及浮动 IP 地址是否保持与主库和从库的关联。

晋升为主库(负向测试)

创建一个包含两个站点的新复制集。在主站点上执行“service mysql stop”。验证是否无法对从站点执行 promote_to_replica_source。

删除主库(正向测试)

创建一个包含两个站点的新复制集。为每个实例附加浮动 IP 地址。在主库上执行“service mysql stop”以模拟主站点崩溃。对主站点执行删除 API 调用。确保从库已晋升为主库,已添加新的从库,并且浮动 IP 地址已正确移动。

从库数量

由于资源需求,将不会为此功能进行集成测试

增量快照

由于无法验证恢复是否实际上是从增量备份完成的,而不是从完整备份完成的,因此将不会为此功能进行集成测试

文档影响

用户指南

  • 添加说明手动故障切换的部分,包括通过 promote-to-replica-source 和通过删除故障主库两种方式

  • 复制部分应更新,以记录 “trove create” 命令的 replica_count 选项

CLI 参考

  • 添加 promote-to-replica-source 命令

  • 添加 eject-replica-source 命令

  • 使用 replica_count 更新 create 命令