重用已删除的镜像成员,而不是创建新的

https://blueprints.launchpad.net/glance/+spec/reuse-the-deleted-image-member

在创建新的镜像成员之前,检查已删除的镜像成员,如果存在则更新它,否则创建新的镜像成员。

问题描述

如果 Glance 后端数据库不是 MySQL 或 PostgreSQL,镜像成员的唯一约束仅包括 image-id 和 member。在这种情况下,如果一个镜像成员被删除,然后使用相同的参数再次创建,Glance 会发起查询以查看是否已经存在一个镜像成员,但结果不包含被标记为已删除的记录。Glance 会尝试使用相同的参数创建一个新的镜像成员,然后会因为重复错误而失败。

提议的变更

使用单个记录来维护镜像和租户之间的关系。在创建新的镜像成员时,首先检查所有现有的镜像成员记录,包括已删除的镜像成员,如果存在则更新它,否则创建新的镜像成员。

备选方案

像我们在 022_image_member_index.py 中为 MySQL 和 PostgreSQL 所做的那样,统一镜像成员的唯一约束。它已经迁移了 MySQL 和 PostgreSQL 的镜像成员的唯一约束,现在其唯一约束包括 image-id、member 和 deleted_at。目前 “deleted_at” 列允许为空。对于 DB2 等其他数据库,其唯一约束比 MySQL 更严格。唯一约束下的列应该是 “NOT NULL”,否则会发生错误。因此,我们无法为这些类型的数据库创建相同的唯一约束。

我们将在迁移中将 “deleted_at” 列更改为 “not nullable”。这意味着我们必须为新创建的镜像成员插入一个默认的时间戳值,一个带有非空时间戳的活动成员会混淆用户。

另一个解决方案是将唯一约束从 (image-id, member, deleted_at) 迁移到 (image-id, member, created_at) 对于 MySQL 和 PostgreSQL,从 (image-id, member) 迁移到 (image-id, member, created_at) 对于其他数据库。created_at 不允许为空,因此新的约束将适用于所有数据库。这个解决方案需要针对不同数据库进行数据迁移。

数据模型影响

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

在创建新的镜像成员时,它将搜索所有镜像成员记录,包括已删除的项目。但是,如果我们启用此补丁,将很少看到许多已删除的镜像成员,因为关系将仅由单个记录维护。唯一的情况是,在应用此补丁之前创建了多个已删除的镜像成员,我们可以使用另一个补丁中的迁移脚本来删除它们。

其他部署者影响

配置选项将会改变

开发人员影响

实现

负责人

主要负责人

龙泉沙

评审人员

核心评审人

nikhil-komawar Ian Cordasco

其他审核员

Kamil Rykowski Abhishek Kekane

工作项

  • 创建新的镜像成员时,重用已删除的镜像成员

依赖项

测试

  • 验证在创建新的镜像成员时,已删除的镜像成员已被更新

文档影响

参考资料

提议的补丁

https://review.openstack.org/190895

PostgreSQL 的唯一约束,与 MySQL 相同

https://postgresql.ac.cn/docs/8.1/static/ddl-constraints.html

DB2 的唯一约束

https://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.admin.dbobj.doc/doc/c0020151.html