Merge "Introduce mariadb_backup backup_strategy"

This commit is contained in:
Zuul 2025-05-27 14:32:08 +00:00 committed by Gerrit Code Review
commit 00aa57453a
4 changed files with 139 additions and 9 deletions

View File

@ -25,17 +25,19 @@ CONF = cfg.CONF
class MariaBackup(mysql_base.MySQLBaseRunner):
"""Implementation of Backup and Restore using mariabackup."""
backup_binary = 'mariabackup'
restore_cmd = ('mbstream -x -C %(restore_location)s')
prepare_cmd = 'mariabackup --prepare --target-dir=%(restore_location)s'
prepare_cmd = \
f'{backup_binary} --prepare --target-dir=%(restore_location)s'
def __init__(self, *args, **kwargs):
super(MariaBackup, self).__init__(*args, **kwargs)
self.backup_log = '/tmp/mariabackup.log'
self.backup_log = f'/tmp/{self.backup_binary}.log'
self._gzip = True
@property
def cmd(self):
cmd = ('mariabackup --backup --stream=xbstream ' +
cmd = (f'{self.backup_binary} --backup --stream=xbstream ' +
self.user_and_pass)
return cmd
@ -64,9 +66,15 @@ class MariaBackup(mysql_base.MySQLBaseRunner):
raise Exception(msg)
class MariaDBBackup(MariaBackup):
"""Implementation of Backup and Restore using mariadb-backup."""
backup_binary = 'mariadb-backup'
class MariaBackupIncremental(MariaBackup):
"""Incremental backup and restore using mariabackup."""
incremental_prep = ('mariabackup --prepare '
incremental_prep_binary = MariaBackup.backup_binary
incremental_prep = (f'{incremental_prep_binary} --prepare '
'--target-dir=%(restore_location)s '
'%(incremental_args)s')
@ -81,7 +89,7 @@ class MariaBackupIncremental(MariaBackup):
@property
def cmd(self):
cmd = (
'mariabackup --backup --stream=xbstream'
f'{self.incremental_prep_binary} --backup --stream=xbstream'
' --incremental-lsn=%(lsn)s ' +
self.user_and_pass
)
@ -102,3 +110,8 @@ class MariaBackupIncremental(MariaBackup):
LOG.info('Running incremental restore')
self.incremental_restore(self.location, self.checksum)
return self.restore_content_length
class MariaDBBackupIncremental(MariaBackupIncremental):
"""Incremental backup and restore using mariadb-backup."""
incremental_prep_binary = MariaDBBackup.backup_binary

View File

@ -19,6 +19,7 @@ import sys
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import importutils
from semantic_version import Version
topdir = os.path.normpath(
os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir))
@ -37,7 +38,13 @@ cli_opts = [
cfg.StrOpt(
'driver',
default='innobackupex',
choices=['innobackupex', 'mariabackup', 'pg_basebackup', 'xtrabackup']
choices=[
'innobackupex',
'mariabackup',
'mariadb_backup',
'pg_basebackup',
'xtrabackup'
]
),
cfg.BoolOpt('backup'),
cfg.StrOpt(
@ -72,7 +79,10 @@ driver_mapping = {
'innobackupex': 'backup.drivers.innobackupex.InnoBackupEx',
'innobackupex_inc': 'backup.drivers.innobackupex.InnoBackupExIncremental',
'mariabackup': 'backup.drivers.mariabackup.MariaBackup',
'mariadb_backup': 'backup.drivers.mariabackup.MariaDBBackup',
'mariabackup_inc': 'backup.drivers.mariabackup.MariaBackupIncremental',
'mariadb_backup_inc':
'backup.drivers.mariabackup.MariaDBBackupIncremental',
'pg_basebackup': 'backup.drivers.postgres.PgBasebackup',
'pg_basebackup_inc': 'backup.drivers.postgres.PgBasebackupIncremental',
'xtrabackup': 'backup.drivers.xtrabackup.XtraBackup',
@ -148,13 +158,19 @@ def main():
CONF(sys.argv[1:], project='trove-backup')
logging.setup(CONF, 'trove-backup')
runner_cls = importutils.import_class(driver_mapping[CONF.driver])
driver = CONF.driver
if driver == "mariabackup":
ds_version = CONF.swift_extra_metadata.get('datastore_version', '0.0')
if Version.coerce(ds_version) >= Version.coerce("10.4"):
driver = "mariadb_backup"
runner_cls = importutils.import_class(driver_mapping[driver])
storage = importutils.import_class(storage_mapping[CONF.storage_driver])()
if CONF.backup:
if CONF.incremental:
runner_cls = importutils.import_class(
driver_mapping['%s_inc' % CONF.driver])
driver_mapping['%s_inc' % driver])
LOG.info('Starting backup database to %s, backup ID %s',
CONF.storage_driver, CONF.backup_id)
@ -163,7 +179,7 @@ def main():
if storage.is_incremental_backup(CONF.restore_from):
LOG.debug('Restore from incremental backup')
runner_cls = importutils.import_class(
driver_mapping['%s_inc' % CONF.driver])
driver_mapping['%s_inc' % driver])
LOG.info('Starting restore database from %s, location: %s',
CONF.storage_driver, CONF.restore_from)

View File

@ -31,7 +31,10 @@ driver_mapping = {
'innobackupex': 'backup.drivers.innobackupex.InnoBackupEx',
'innobackupex_inc': 'backup.drivers.innobackupex.InnoBackupExIncremental',
'mariabackup': 'backup.drivers.mariabackup.MariaBackup',
'mariadb_backup': 'backup.drivers.mariabackup.MariaDBBackup',
'mariabackup_inc': 'backup.drivers.mariabackup.MariaBackupIncremental',
'mariadb_backup_inc':
'backup.drivers.mariabackup.MariaDBBackupIncremental',
'pg_basebackup': 'backup.drivers.postgres.PgBasebackup',
'pg_basebackup_inc': 'backup.drivers.postgres.PgBasebackupIncremental',
'xtrabackup': 'backup.drivers.xtrabackup.XtraBackup',
@ -80,6 +83,47 @@ class TestMariaBackup(unittest.TestCase):
self.assertEqual(runner.check_restore_process(), True)
class TestMariaDBBackup(unittest.TestCase):
def setUp(self):
self.runner_cls = importutils.import_class(
driver_mapping['mariadb_backup'])
self.params = {}
# assertions
self.assertIsNotNone(self.runner_cls)
def tearDown(self):
pass
def test_instance(self):
'''Check instance'''
# call the method
runner = self.runner_cls(**self.params)
# assertions
self.assertIsNotNone(runner)
def test_cmd(self):
'''Check cmd property'''
# call the method
runner = self.runner_cls(**self.params)
# assertions
cmd = ("mariadb-backup --backup --stream=xbstream {}".format(
runner.user_and_pass))
self.assertEqual(runner.cmd, cmd)
def test_check_restore_process(self):
'''Check manifest'''
runner = self.runner_cls(**self.params)
runner.process = MagicMock()
returncode = PropertyMock(return_value=0)
type(runner.process).returncode = returncode
# call the method
self.assertEqual(runner.check_restore_process(), True)
class TestMariaBackupIncremental(unittest.TestCase):
def setUp(self):
self.runner_cls = importutils.import_class(
@ -131,5 +175,56 @@ class TestMariaBackupIncremental(unittest.TestCase):
self.assertEqual(ret, length)
class TestMariaDBBackupIncremental(unittest.TestCase):
def setUp(self):
self.runner_cls = importutils.import_class(
driver_mapping['mariadb_backup_inc'])
self.params = {
'lsn': '1234567890',
'incremental_dir': './'
}
self.metadata = {}
def tearDown(self):
pass
def test_cmd(self):
'''Check cmd property'''
# call the method
runner = self.runner_cls(**self.params)
# assertions
cmd = (
'mariadb-backup --backup --stream=xbstream'
' --incremental-lsn=%(lsn)s ' +
runner.user_and_pass
)
self.assertEqual(runner.cmd, cmd)
def test_get_metadata(self):
# prepare the test
runner = self.runner_cls(**self.params)
runner.get_metadata = MagicMock(return_value=self.metadata)
# call the method
ret = runner.get_metadata()
# assertions
self.assertEqual(ret, self.metadata)
def test_run_restore(self):
# prepare the test
runner = self.runner_cls(**self.params)
length = 10
runner.incremental_restore = MagicMock(return_value=length)
runner.restore_content_length = length
# call the method
ret = runner.run_restore()
# assertions
self.assertEqual(ret, length)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,6 @@
---
fixes:
- |
For MariaDB datastore of versions equal or higher then 10.4,
`mariadb-backup` binary will be executed instead of `mariabackup`
when performing backup or restore process.