Merge "Ceph driver should respect the --incremental
option for backups"
This commit is contained in:
commit
aef61e5df7
@ -169,9 +169,9 @@ class CephBackupDriver(driver.BackupDriver):
|
|||||||
Backups may be stored in their own pool or even cluster. Store location is
|
Backups may be stored in their own pool or even cluster. Store location is
|
||||||
defined by the Ceph conf file and service config options supplied.
|
defined by the Ceph conf file and service config options supplied.
|
||||||
|
|
||||||
If the source volume is itself an RBD volume, the backup will be performed
|
Only if the incremental option is specified and the source volume is itself
|
||||||
using incremental differential backups which *should* give a performance
|
an RBD volume, the backup will be performed using incremental differential
|
||||||
gain.
|
backups which *should* give a performance gain.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, context, db=None, execute=None):
|
def __init__(self, context, db=None, execute=None):
|
||||||
@ -910,8 +910,9 @@ class CephBackupDriver(driver.BackupDriver):
|
|||||||
def backup(self, backup, volume_file, backup_metadata=True):
|
def backup(self, backup, volume_file, backup_metadata=True):
|
||||||
"""Backup volume and metadata (if available) to Ceph object store.
|
"""Backup volume and metadata (if available) to Ceph object store.
|
||||||
|
|
||||||
If the source volume is an RBD we will attempt to do an
|
If the source volume is an RBD and we use the `incremental`
|
||||||
incremental/differential backup, otherwise a full copy is performed.
|
option we will attempt to do an incremental/differential backup,
|
||||||
|
otherwise a full copy is performed.
|
||||||
If this fails we will attempt to fall back to full copy.
|
If this fails we will attempt to fall back to full copy.
|
||||||
"""
|
"""
|
||||||
volume = self.db.volume_get(self.context, backup.volume_id)
|
volume = self.db.volume_get(self.context, backup.volume_id)
|
||||||
@ -926,13 +927,13 @@ class CephBackupDriver(driver.BackupDriver):
|
|||||||
volume_file.seek(0)
|
volume_file.seek(0)
|
||||||
length = self._get_volume_size_gb(volume)
|
length = self._get_volume_size_gb(volume)
|
||||||
|
|
||||||
do_full_backup = False
|
if backup.parent_id and self._file_is_rbd(volume_file):
|
||||||
if self._file_is_rbd(volume_file):
|
|
||||||
# If volume an RBD, attempt incremental backup.
|
# If volume an RBD, attempt incremental backup.
|
||||||
LOG.debug("Volume file is RBD: attempting incremental backup.")
|
LOG.debug("Volume file is RBD: attempting incremental backup.")
|
||||||
try:
|
try:
|
||||||
updates = self._backup_rbd(backup, volume_file,
|
updates = self._backup_rbd(backup, volume_file,
|
||||||
volume.name, length)
|
volume.name, length)
|
||||||
|
do_full_backup = False
|
||||||
except exception.BackupRBDOperationFailed:
|
except exception.BackupRBDOperationFailed:
|
||||||
LOG.debug("Forcing full backup of volume %s.", volume.id)
|
LOG.debug("Forcing full backup of volume %s.", volume.id)
|
||||||
do_full_backup = True
|
do_full_backup = True
|
||||||
|
@ -483,8 +483,15 @@ class BackupCephTestCase(test.TestCase):
|
|||||||
{'name': 'backup.mock.snap.15341241.90'},
|
{'name': 'backup.mock.snap.15341241.90'},
|
||||||
{'name': 'backup.mock.snap.199994362.10'}])
|
{'name': 'backup.mock.snap.199994362.10'}])
|
||||||
|
|
||||||
|
self.backup.parent_id = fake.UUID1
|
||||||
output = self.service.backup(self.backup, rbdio)
|
output = self.service.backup(self.backup, rbdio)
|
||||||
self.assertDictEqual({}, output)
|
|
||||||
|
# Confirm that the backup process is not able to
|
||||||
|
# find the parent backup for incremental (creates
|
||||||
|
# a full backup) and requests the DB to be changed
|
||||||
|
# to reflect that there's no parent (is full
|
||||||
|
# backup).
|
||||||
|
self.assertIsNone(output['parent_id'])
|
||||||
|
|
||||||
self.assertEqual(['popen_init',
|
self.assertEqual(['popen_init',
|
||||||
'read',
|
'read',
|
||||||
@ -502,10 +509,16 @@ class BackupCephTestCase(test.TestCase):
|
|||||||
|
|
||||||
@common_mocks
|
@common_mocks
|
||||||
def test_backup_volume_from_rbd_set_parent_id(self):
|
def test_backup_volume_from_rbd_set_parent_id(self):
|
||||||
|
"""Test volume from rbd with parent id.
|
||||||
|
|
||||||
|
If the backup has parent_id an incremental backup should
|
||||||
|
be performance.
|
||||||
|
"""
|
||||||
with mock.patch.object(self.service, '_backup_rbd') as \
|
with mock.patch.object(self.service, '_backup_rbd') as \
|
||||||
mock_backup_rbd, mock.patch.object(self.service,
|
mock_backup_rbd, mock.patch.object(self.service,
|
||||||
'_backup_metadata'):
|
'_backup_metadata'):
|
||||||
mock_backup_rbd.return_value = {'parent_id': 'mock'}
|
self.backup.parent_id = fake.UUID1
|
||||||
|
mock_backup_rbd.return_value = {'parent_id': fake.UUID1}
|
||||||
image = self.service.rbd.Image()
|
image = self.service.rbd.Image()
|
||||||
meta = linuxrbd.RBDImageMetadata(image,
|
meta = linuxrbd.RBDImageMetadata(image,
|
||||||
'pool_foo',
|
'pool_foo',
|
||||||
@ -513,7 +526,7 @@ class BackupCephTestCase(test.TestCase):
|
|||||||
'conf_foo')
|
'conf_foo')
|
||||||
rbdio = linuxrbd.RBDVolumeIOWrapper(meta)
|
rbdio = linuxrbd.RBDVolumeIOWrapper(meta)
|
||||||
output = self.service.backup(self.backup, rbdio)
|
output = self.service.backup(self.backup, rbdio)
|
||||||
self.assertDictEqual({'parent_id': 'mock'}, output)
|
self.assertDictEqual({'parent_id': fake.UUID1}, output)
|
||||||
|
|
||||||
@common_mocks
|
@common_mocks
|
||||||
def test_backup_volume_from_rbd_set_parent_id_none(self):
|
def test_backup_volume_from_rbd_set_parent_id_none(self):
|
||||||
@ -596,6 +609,7 @@ class BackupCephTestCase(test.TestCase):
|
|||||||
"""
|
"""
|
||||||
backup_name = self.service._get_backup_base_name(self.backup_id,
|
backup_name = self.service._get_backup_base_name(self.backup_id,
|
||||||
diff_format=True)
|
diff_format=True)
|
||||||
|
self.backup.parent_id = fake.UUID1
|
||||||
|
|
||||||
def mock_write_data():
|
def mock_write_data():
|
||||||
self.volume_file.seek(0)
|
self.volume_file.seek(0)
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- Default behavior of ceph backups upgraded (no longer incremental by
|
||||||
|
default) to keep consistency between drivers.
|
||||||
|
fixes:
|
||||||
|
- Volume backup service with Ceph driver will now respect the `--incremental`
|
||||||
|
option for backups (this new behavior will be only available for Ceph
|
||||||
|
volumes, we still don't support incremental for non Ceph volumes).
|
||||||
|
If the incremental flag is not specified then a new full backup will
|
||||||
|
always be created.
|
Loading…
x
Reference in New Issue
Block a user