backup-export
cinder backup支持將元數(shù)據(jù)序列化導(dǎo)出(export record)柠横,這樣即使數(shù)據(jù)庫中的數(shù)據(jù)丟失了悼潭,也能從導(dǎo)出的元數(shù)據(jù)中快速恢復(fù)腐螟。
usage: cinder backup-export <backup>
范例:
[root@node1 ~]# cinder backup-export 51e2c303-6490-433c-a097-cf3742a7e991
+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Property | Value |
+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| backup_service | cinder.backup.drivers.nfs |
| backup_url | eyJzdGF0dXMiOiAiYXZhaWxhYmxlIiwgInRlbXBfc25hcHNob3RfaWQiOiBudWxsLCAiZGlzcGxheV9uYW1lIjogbnVsbCwgImF2YWlsYWJpbGl0eV96b25lIjogIm5vdmEiLCAiZGVsZXRlZCI6IGZhbHNlLCAidm9sdW1lX2lkIjogIjA0ODAyZDQ4LWJmYTktNDY2Yy1iM2E4LTQyNGIwMTRkNzVkNSIsICJyZXN0b3JlX3ZvbHVtZV9pZCI6IG51bGwsICJ1cGRhdGVkX2F0IjogIjIwMTctMDctMTdUMDQ6NTM6MTZaIiwgImhvc3QiOiAibm9kZTEiLCAic25hcHNob3RfaWQiOiBudWxsLCAidXNlcl9pZCI6ICIzZjU2ZDI5NzZlYWM0NjhkYmU4MzZlYmNjNDQwMDg1OCIsICJzZXJ2aWNlX21ldGFkYXRhIjogImJhY2t1cCIsICJpZCI6ICI1MWUyYzMwMy02NDkwLTQzM2MtYTA5Ny1jZjM3NDJhN2U5OTEiLCAic2l6ZSI6IDEsICJvYmplY3RfY291bnQiOiA1LCAiZGVsZXRlZF9hdCI6IG51bGwsICJjb250YWluZXIiOiAiNTEvZTIvNTFlMmMzMDMtNjQ5MC00MzNjLWEwOTctY2YzNzQyYTdlOTkxIiwgInNlcnZpY2UiOiAiY2luZGVyLmJhY2t1cC5kcml2ZXJzLm5mcyIsICJkcml2ZXJfaW5mbyI6IHt9LCAiY3JlYXRlZF9hdCI6ICIyMDE3LTA3LTE3VDA0OjUyOjM4WiIsICJkaXNwbGF5X2Rlc2NyaXB0aW9uIjogbnVsbCwgImRhdGFfdGltZXN0YW1wIjogIjIwMTctMDctMTdUMDQ6NTI6MzhaIiwgInBhcmVudF9pZCI6IG51bGwsICJudW1fZGVwZW5kZW50X2JhY2t1cHMiOiAwLCAiZmFpbF9yZWFzb24iOiBudWxsLCAicHJvamVjdF9pZCI6ICI3YjdkNjYyN2NmMDQ0ZDgwYWE2ZWMzZjJmNGFkZTJhYiIsICJ0ZW1wX3ZvbHVtZV9pZCI6IG51bGx9 |
+----------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
cinder.backup.manager.BackupManager#export_record:
<!--忽略部分代碼-->
backup_service = self.service.get_backup_driver(context)
# 得到 cinder.backup.drivers.nfs.NFSBackupDriver 服務(wù)
driver_info = backup_service.export_record(backup)
# 如果特殊的后端驅(qū)動(dòng)需要補(bǔ)充其他必要信息坷襟,需要通過這個(gè)方法導(dǎo)出裁眯。默認(rèn)驅(qū)動(dòng)沒有額外信息。cinder.backup.driver.BackupDriver#export_record 返回一個(gè){}
backup_url = backup.encode_record(driver_info=driver_info)
# 把backup對(duì)象信息和driver_info 做Base64序列號(hào)成字符串蠢终,實(shí)例如下
backup_record['backup_url'] = backup_url
cinder.objects.backup.Backup#encode_record:
def encode_record(self, **kwargs):
"""Serialize backup object, with optional extra info, into a string."""
# We don't want to export extra fields and we want to force lazy
# loading, so we can't use dict(self) or self.obj_to_primitive
record = {name: field.to_primitive(self, name, getattr(self, name))
for name, field in self.fields.items()}
# We must update kwargs instead of record to ensure we don't overwrite
# "real" data from the backup
kwargs.update(record)
retval = jsonutils.dump_as_bytes(kwargs)
return base64.encode_as_text(retval)
record:
{
'availability_zone': u'nova',
'updated_at': '2017-07-17T04: 53: 16Z',
'container': u'51/e2/51e2c303-6490-433c-a097-cf3742a7e991',
'snapshot_id': None,
'service_metadata': u'backup',
'id': '51e2c303-6490-433c-a097-cf3742a7e991',
'size': 1,
'object_count': 5,
'deleted_at': None,
'user_id': u'3f56d2976eac468dbe836ebcc4400858',
'service': u'cinder.backup.drivers.nfs',
'display_description': None,
'data_timestamp': '2017-07-17T04: 52: 38Z',
'parent_id': None,
'project_id': u'7b7d6627cf044d80aa6ec3f2f4ade2ab',
'temp_volume_id': None,
'status': u'available',
'deleted': False,
'restore_volume_id': None,
'host': u'node1',
'volume_id': '04802d48-bfa9-466c-b3a8-424b014d75d5',
'display_name': None,
'temp_snapshot_id': None,
'fail_reason': None,
'created_at': '2017-07-17T04: 52: 38Z',
'num_dependent_backups': 0
}
序列化后:
u'eyJzdGF0dXMiOiAiYXZhaWxhYmxlIiwgInRlbXBfc25hcHNob3RfaWQiOiBudWxsLCAiZGlzcGxheV9uYW1lIjogbnVsbCwgImF2YWlsYWJpbGl0eV96b25lIjogIm5vdmEiLCAiZGVsZXRlZCI6IGZhbHNlLCAidm9sdW1lX2lkIjogIjA0ODAyZDQ4LWJmYTktNDY2Yy1iM2E4LTQyNGIwMTRkNzVkNSIsICJyZXN0b3JlX3ZvbHVtZV9pZCI6IG51bGwsICJ1cGRhdGVkX2F0IjogIjIwMTctMDctMTdUMDQ6NTM6MTZaIiwgImhvc3QiOiAibm9kZTEiLCAic25hcHNob3RfaWQiOiBudWxsLCAidXNlcl9pZCI6ICIzZjU2ZDI5NzZlYWM0NjhkYmU4MzZlYmNjNDQwMDg1OCIsICJzZXJ2aWNlX21ldGFkYXRhIjogImJhY2t1cCIsICJpZCI6ICI1MWUyYzMwMy02NDkwLTQzM2MtYTA5Ny1jZjM3NDJhN2U5OTEiLCAic2l6ZSI6IDEsICJvYmplY3RfY291bnQiOiA1LCAiZGVsZXRlZF9hdCI6IG51bGwsICJjb250YWluZXIiOiAiNTEvZTIvNTFlMmMzMDMtNjQ5MC00MzNjLWEwOTctY2YzNzQyYTdlOTkxIiwgInNlcnZpY2UiOiAiY2luZGVyLmJhY2t1cC5kcml2ZXJzLm5mcyIsICJkcml2ZXJfaW5mbyI6IHt9LCAiY3JlYXRlZF9hdCI6ICIyMDE3LTA3LTE3VDA0OjUyOjM4WiIsICJkaXNwbGF5X2Rlc2NyaXB0aW9uIjogbnVsbCwgImRhdGFfdGltZXN0YW1wIjogIjIwMTctMDctMTdUMDQ6NTI6MzhaIiwgInBhcmVudF9pZCI6IG51bGwsICJudW1fZGVwZW5kZW50X2JhY2t1cHMiOiAwLCAiZmFpbF9yZWFzb24iOiBudWxsLCAicHJvamVjdF9pZCI6ICI3YjdkNjYyN2NmMDQ0ZDgwYWE2ZWMzZjJmNGFkZTJhYiIsICJ0ZW1wX3ZvbHVtZV9pZCI6IG51bGx9'
cinder.objects.backup.Backup#encode_record 這個(gè)方法注意下序攘,以后可以用于對(duì)象序列化!寻拂!
backup-import
如果backup記錄信息被從數(shù)據(jù)庫里刪除了程奠,可以通過之前export出的backup_url做恢復(fù),恢復(fù)出的數(shù)據(jù)連backup_id都跟之前一樣祭钉。
usage: cinder backup-import <backup_service> <backup_url>
backup_service : 驅(qū)動(dòng)的名字
backup_url : export出的序列化元數(shù)據(jù)
范例:
[root@node1 ~]# cinder backup-import cinder.backup.drivers.nfs eyJzdGF0dXMiOiAiYXZhaWxhYmxlIiwgInRlbXBfc25hcHNob3RfaWQiOiBudWxsLCAiZGlzcGxheV9uYW1lIjogbnVsbCwgImF2YWlsYWJpbGl0eV96b25lIjogIm5vdmEiLCAiZGVsZXRlZCI6IGZhbHNlLCAidm9sdW1lX2lkIjogIjA0ODAyZDQ4LWJmYTktNDY2Yy1iM2E4LTQyNGIwMTRkNzVkNSIsICJyZXN0b3JlX3ZvbHVtZV9pZCI6IG51bGwsICJ1cGRhdGVkX2F0IjogIjIwMTctMDctMTdUMDQ6NTM6MTZaIiwgImhvc3QiOiAibm9kZTEiLCAic25hcHNob3RfaWQiOiBudWxsLCAidXNlcl9pZCI6ICIzZjU2ZDI5NzZlYWM0NjhkYmU4MzZlYmNjNDQwMDg1OCIsICJzZXJ2aWNlX21ldGFkYXRhIjogImJhY2t1cCIsICJpZCI6ICI1MWUyYzMwMy02NDkwLTQzM2MtYTA5Ny1jZjM3NDJhN2U5OTEiLCAic2l6ZSI6IDEsICJvYmplY3RfY291bnQiOiA1LCAiZGVsZXRlZF9hdCI6IG51bGwsICJjb250YWluZXIiOiAiNTEvZTIvNTFlMmMzMDMtNjQ5MC00MzNjLWEwOTctY2YzNzQyYTdlOTkxIiwgInNlcnZpY2UiOiAiY2luZGVyLmJhY2t1cC5kcml2ZXJzLm5mcyIsICJkcml2ZXJfaW5mbyI6IHt9LCAiY3JlYXRlZF9hdCI6ICIyMDE3LTA3LTE3VDA0OjUyOjM4WiIsICJkaXNwbGF5X2Rlc2NyaXB0aW9uIjogbnVsbCwgImRhdGFfdGltZXN0YW1wIjogIjIwMTctMDctMTdUMDQ6NTI6MzhaIiwgInBhcmVudF9pZCI6IG51bGwsICJudW1fZGVwZW5kZW50X2JhY2t1cHMiOiAwLCAiZmFpbF9yZWFzb24iOiBudWxsLCAicHJvamVjdF9pZCI6ICI3YjdkNjYyN2NmMDQ0ZDgwYWE2ZWMzZjJmNGFkZTJhYiIsICJ0ZW1wX3ZvbHVtZV9pZCI6IG51bGx9
+----------+--------------------------------------+
| Property | Value |
+----------+--------------------------------------+
| id | 51e2c303-6490-433c-a097-cf3742a7e991 |
| name | None |
+----------+--------------------------------------+
邏輯:
- backup_url 反序列化 backup_option瞄沙,檢查數(shù)據(jù)庫里是否存在有效的backup_option['id']記錄,如果不存在則創(chuàng)建一個(gè)id = backup_option['id']的back記錄。并且'user_id'= context.user_id,'project_id'= context.project_id,'volume_id'= IMPORT_VOLUME_ID,'status'= fields.BackupStatus.CREATING,
- 把backup_url的其它元數(shù)據(jù)保存至步驟1創(chuàng)建的back記錄中距境。
代碼分析:
cinder.backup.manager.BackupManager#import_record
def import_record(self,
context,
backup,
backup_service,
backup_url,
backup_hosts):
backup_options = backup.decode_record(backup_url) # backup_url反序列化
# Extract driver specific info and pass it to the driver
driver_options = backup_options.pop('driver_info', {}) # 拿到驅(qū)動(dòng)的額外信息
backup_service = self.service.get_backup_driver(context)
backup_service.import_record(backup, driver_options) # 把驅(qū)動(dòng)的額外信息導(dǎo)入
# 檢查 backup_options 里包含必須元素
required_import_options = {
'display_name',
'display_description',
'container',
'size',
'service_metadata',
'object_count',
'id'
}
# Check for missing fields in imported data
missing_opts = required_import_options - set(backup_options)
if missing_opts:
raise exception.InvalidBackup(reason=msg)
# 檢查backup_options['id'] 和 數(shù)據(jù)庫的一致
backup_id = backup_options['id']
if backup_id != backup.id:
raise exception.InvalidBackup(reason=msg)
# 復(fù)寫一些元素值
backup_options['status'] = fields.BackupStatus.AVAILABLE
backup_options['service'] = self.driver_name
backup_options['availability_zone'] = self.az
backup_options['host'] = self.host
# 移除一些元素值
for key in ('name', 'user_id', 'project_id', 'deleted_at',
'deleted', 'fail_reason'):
backup_options.pop(key, None)
# 更新進(jìn)數(shù)據(jù)庫
backup.update(backup_options)
backup.save()