专用于卷的备份状态字段¶
本规范建议为卷引入一个新的 backup_status 字段,以消除活动备份任务对卷附加工作流程的阻塞或序列化问题。
问题描述¶
目前,所有 cinder 任务都使用状态字段来检查合适的卷 status,同时执行任何特定操作。 在任务的活动阶段,其状态也会通过相同的卷状态字段被持有和更新。 最后,任务抛出的某些错误也会通过此字段传回。 基本上,这个单个字段创建了一种锁定或同步机制,以确保任何时候只有一个任务作用于一个卷。
虽然这有助于协调影响卷本身的任务,但将相同的逻辑应用于备份实际上是不必要的或有帮助的
作用于卷本身的操作(例如 resize 或 attaching)和备份(备份)在技术上并不相关。 备份驱动程序和块设备驱动程序独立运行,备份是从卷快照读取的,或者,如果配置选项 backup_use_temp_snapshot 设置为 false,则是卷的克隆。
备份可能需要很长时间才能完成,并且在此期间会阻止卷上的任何其他任务。 如果假设正在备份一个 8TB 的卷,即使备份速度为 1 GB/s,卷备份仍然需要 ~2.5 小时才能完成。 从状态机角度来看,解耦这一点(因为它对于大多数通过快照工作的驱动程序或实现来说已经是这样)似乎非常有益。
用例¶
将备份任务与其他卷上的任务解耦,有两个方面的用例
1. 对于云运营商 - 目前,在实例实时迁移期间,将卷从源计算节点分离并将其附加到目标计算节点,会被并发运行的卷备份阻塞。 更糟糕的是,可能长时间运行的备份(任务)也可能由用户触发,从而阻塞管理操作,例如将所有实例迁移到其他主机以关闭超visor 进行维护。
如果卷足够大或备份传输速率慢,这可能会导致用户无限期地“锁定”管理任务。
2. 对于云用户 - 当前正在运行的备份任务会阻止紧急操作任务。 正在运行的备份会阻止用户快速调整正在耗尽可用空间的卷的大小,或将其附加到另一个实例。 如果备份任务甚至是由云提供商或某些自动调度触发的,则此问题会更加严重。
提议的变更¶
对于卷,应该有一个字段 backup_status 来保存当前存储在 status 中的备份相关值
‘backing-up’
‘error_backing-up’
‘restoring-backup’
‘error_restoring’
(backup_status 也可以是 null,以指示当前此卷没有备份相关状态。)
然后,这些应该从 status 的有效值列表中删除,并成为 backup_status 的值。
某些任务启动的条件检查会有一些变化,但通常依赖于将保留在状态字段中的那些卷状态值。
备选方案¶
之前有一个规范 [1] 将所有任务状态移动到一个新的字段。 但最终这过于复杂,并且不适合描述的解耦卷备份的用例。
数据模型影响¶
必须向卷表中添加一个额外的字段 backup_status,并更改其可能保存的有效值列表。
这将首先通过数据库模式更改来引入,以添加新字段。
然后,通过在线更新/升级来拆分“移出”的与备份相关的状态到它们的新专用字段。
卷状态的有效值也必须减少。 https://opendev.org/openstack/cinder/src/commit/5c23c9fbe41baef22a71eac4406fd9db269d1271/cinder/objects/fields.py#L168-L190 因为状态 backing-up、error_backing-up 仅存储在备份状态中。
该方法 conditional_update 需要支持数据库更新过程中不同版本的卷数据模型。 此外, cinder 项目中对该方法的调用都必须更新为使用新字段。
REST API 影响¶
由于引入了一个新字段以及随之而来的状态字段的拆分,因此需要一个新的 API 微版本。 为了服务旧的微版本,必须引入数据模型之间的映射。 基本上,API 必须在旧的微版本中使用时,将来自两个字段(状态、备份_状态)的状态呈现为单个状态字段。
必须将 backup_status 的附加字段发送给用户。 卷的有效状态仅允许减少的集合。 此外,端点 reset_status_backup 操作需要适应新的数据模型,以允许(仅限管理员)设置备份状态。
注意:要更改的端点列表基于当前提出的更改,可能会发生变化。
显示卷
{
"volume": {
"attachments": [],
"availability_zone": "nova",
"bootable": "false",
"consistencygroup_id": null,
"created_at": "2018-11-29T06:50:07.770785",
"description": null,
"encrypted": false,
"id": "f7223234-1afc-4d19-bfa3-d19deb6235ef",
"links": [
{
"href": "http://127.0.0.1:45839/v3/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef",
"rel": "self"
},
{
"href": "http://127.0.0.1:45839/89afd400-b646-4bbc-b12b-c0a4d63e5bd3/volumes/f7223234-1afc-4d19-bfa3-d19deb6235ef",
"rel": "bookmark"
}
],
"metadata": {},
"migration_status": null,
"multiattach": false,
"name": null,
"os-vol-host-attr:host": null,
"os-vol-mig-status-attr:migstat": null,
"os-vol-mig-status-attr:name_id": null,
"os-vol-tenant-attr:tenant_id": "89afd400-b646-4bbc-b12b-c0a4d63e5bd3",
"replication_status": null,
"size": 10,
"snapshot_id": null,
"source_volid": null,
"status": "creating",
"backup_status": null,
"updated_at": null,
"user_id": "c853ca26-e8ea-4797-8a52-ee124a013d0e",
"volume_type": "__DEFAULT__",
"provider_id": null,
"group_id": null,
"service_uuid": null,
"shared_targets": true,
"cluster_name": null,
"volume_type_id": "5fed9d7c-401d-46e2-8e80-f30c70cb7e1d",
"consumes_quota": true
}
}
更新卷
返回 backup_status 的附加字段
列出卷
显示 backup_status 的附加字段
backup_status 的附加过滤器
列出详细卷
显示 backup_status 的附加字段
backup_status 的附加过滤器
此外(仅在使用新的微版本时可用)
设置卷 backup_status
取消设置卷 backup_status
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
性能影响¶
虽然本身没有性能影响,但将备份状态机与状态解耦将减少卷上发生任务的序列化。
其他部署者影响¶
开发人员影响¶
卷的状态只能设置为减少的状态列表。 此外,备份状态现在只能通过引入的 backup_status 字段设置或取消设置。
上述更改的影响是,所有方法都必须检查哪些允许与卷并发交互的方法,并使用 backup_status 字段而不是状态字段来指示正在运行的进程。 此更改应传达给依赖 cinder api 来检查状态的其他开发团队,以使用旧的微版本或更新为使用状态和 backup_status。
由于当前将状态用作锁定机制,以防止在达到无效状态时启动操作,因此 API 中的方法调用必须更新为在必要时也包括对 backup_status 的检查。 目前,这部分工作由 conditional_update 方法完成,该方法需要接收对更新的卷模型的支持。 仅当接收到旧数据库模型时才需要此版本控制。 API 始终发送新的模型,即使使用旧的 API 版本也是如此,因为翻译层。 此翻译层保证与旧 API 版本的向后兼容性,并将 (status, backup_status) -> status 和 status -> (status, backup_status) 进行翻译。
为了能够对 openstack 的数据库进行在线迁移以进行更新,需要一种将状态 -> (status, backup_status) 重新映射并将其保存到数据库中的方法。 只有在完成模式更新后才应调用此方法。 此方法将允许旧版本的 openstack 能够像以前一样执行并根据需要设置或检查其状态。 这些方法应在后续版本中删除。
升级影响¶
无
实现¶
必须维护以下关于可以对卷执行哪些操作/任务的现有限制
在卷当前正在备份时,拒绝删除卷
如果一个已经正在进行中,则拒绝卷的并发备份
如果当前正在运行备份,则拒绝卷或“块存储”迁移
负责人¶
- 主要负责人
Christian Rohmann (IRC: crohmann)
其他贡献者
工作项¶
将状态字段拆分为上述状态和 backup_status 字段
通过向卷表中添加 backup_status 列来更新 SQL 数据模型
创建 DB 迁移 (Alembic)
允许在线迁移数据库的模型的附加方法
通过添加 backup_status 字段和增加版本号来更新卷类
引入验证方法,用于新的 backup_status 字段,以保证不会设置错误的状态
更新状态字段的验证方法,以保证不会设置错误的状态
为 old 数据库模型添加对 conditional_update 方法的版本控制
更新对 conditional_update 的方法调用,以使用状态和 backup_status
引入 API 层作为翻译器,以服务旧的微版本
引入一个新的微版本,以允许备份与使用卷的状态字段作为锁定机制的其他操作隔离。
文档
破坏性更改
API 文档
模型
端点
旧数据库模型的升级指南/脚本
在线迁移
模式更新
依赖项¶
必须将依赖关系传达给其他开发团队,以确保他们使用旧的微版本以避免破坏性更改,并切换到新的拆分字段。 此更改应特别传达给 nova 团队,nova 团队会定期检查附加卷的状态。
测试¶
由于只有减少的集合的状态通过 status 字段处理,并且 backup_status 作为新引入的字段,因此必须调整一些功能测试以使用新的数据模型。
必须添加进一步的测试,以确保旧 API 微版本的翻译层按预期工作。 例如,备份状态通过旧版本中的 status,然后通过新版本中的 backup_status 来呈现。
由于 conditional_update` 方法需要在此版本中支持版本控制,因此应编写测试以验证版本控制是否正确发生。
文档影响¶
添加一个发布说明,解释更改的动机和效果
记录卷本身以及备份和恢复任务的状态机。
记录旧微版本的翻译层以及翻译行为。
参考资料¶
[1] 之前提出的添加任务状态的规范:https://review.opendev.org/c/openstack/cinder-specs/+/818551
历史记录¶
发布名称 |
描述 |
|---|---|
2023.02 |
引入 |