注意:这里还有一个很关键的问题没解决,配额信息如何处理?查看僵尸实例占用了多少配额倒是比较简单,但如何把这些配额释放回去?

我目前只能人工计算删除之后的instance、cores、ram值,然后去reservations和quota_usages表中修改。

这个方法很二缺,而且容易出错,但暂时没有更好的办法,还望路过的前辈支个招。


操作之前,我也尝试在网上找了一些,很多都是同出一源,屏蔽外键(SET FOREIGN_KEY_CHECKS=0;),然后删除instances表中的记录。显而易见,这种方式很暴力,会留下相当多的数据库垃圾条目。

当然,也是有一些通过脚本,或者逐条清除的办法来解决的,但版本相对比较早,比如像这位前辈的blog中的记录(传送门),关联的数据库条目相对非常少。


所以,只好自己照着前辈的方法摸索着去处理了…


以下以demo1实例为例,测试删除僵尸实例

获取当前状态,尝试删除,状态仍然是ERROR

[root@controller ~(demo)]$ nova list |grep demo1

| 38887ca5-b697-451f-8d95-36b8b64aae3e | demo1 | ERROR | - | NOSTATE | |


  1. 回收floating ip,这个例子里面实例并没有分配到floating ip,但还是需要先提出来,避免出现更多的数据库外键错误
    # nova remove-floating-ip demo1 192.168.8.101
    # nova floating-ip-delete 192.168.8.101

  2. 确认需要删除的实例的id,在数据库的表中,它可能以uuid,instance_uuid,id等名称出现
    # nova list | grep demo1
    从上面图中可以看到id是 38887ca5-b697-451f-8d95-36b8b64aae3e

  3. 确认数据库中此实例的信息
    mysql -uroot -pPASSWORD -e "USE nova; SELECT uuid, vm_state, display_name FROM instances WHERE uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"

  4. 逐条删除数据库表记录
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM security_group_instance_association WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_info_caches WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM block_device_mapping WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_extra WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"

    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_actions_events WHERE action_id IN (SELECT id FROM instance_actions WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e') ;"

    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_actions WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_faults WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_system_metadata WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instances WHERE uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"

  5. 如果删除过程中提示还有其他外键,比如以下提示,
    ERROR 1451 (23000) at line 1: Cannot delete or update a parent row: a foreign key constraint fails (`nova`.`instance_system_metadata`, CONSTRAINT `instance_system_metadata_ibfk_1` FOREIGN KEY (`instance_uuid`) REFERENCES `instances` (`uuid`))
    在执行命令时,依次替换3个下划线的位置。第1个是关联外键所在表,第2个是该表中相关联的字段,第3个是被引用的表中对应的字段,就是前面查询到的instance_id。前两条直接复制,后面instance_id根据实际需要删除的实例的uuid去替换。执行的实际命令如下:
    mysql -uroot -pPASSWORD -e "USE nova; DELETE FROM instance_system_metadata WHERE instance_uuid='38887ca5-b697-451f-8d95-36b8b64aae3e' ;"

  6. 接下来,删除实例所使用的镜像。默认位于 /var/lib/nova/instances 目录中,镜像文件仍然是以instance_id命名,删除整个instance_id的文件夹即可。保险起见,可以将文件夹先备份到其他位置保留一段时间。


最后,就是前面提到的,手动去处理配额用量信息。