File: innobackupex.py

package info (click to toggle)
openstack-trove 1%3A24.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,976 kB
  • sloc: python: 50,665; sh: 2,866; makefile: 71
file content (119 lines) | stat: -rw-r--r-- 4,344 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Copyright 2020 Catalyst Cloud
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

import re

from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log as logging

from backup.drivers import mysql_base

LOG = logging.getLogger(__name__)
CONF = cfg.CONF


class InnoBackupEx(mysql_base.MySQLBaseRunner):
    """Implementation of Backup and Restore for InnoBackupEx."""
    restore_cmd = ('xbstream -x -C %(restore_location)s --parallel=2')
    prepare_cmd = ('innobackupex'
                   ' --defaults-file=%(restore_location)s/backup-my.cnf'
                   ' --ibbackup=xtrabackup'
                   ' --apply-log'
                   ' %(restore_location)s')

    def __init__(self, *args, **kwargs):
        super(InnoBackupEx, self).__init__(*args, **kwargs)
        self.backup_log = '/tmp/innobackupex.log'
        self._gzip = True

    @property
    def cmd(self):
        cmd = ('innobackupex'
               ' --stream=xbstream'
               ' --parallel=2 ' +
               self.user_and_pass + ' %s' % self.datadir)
        return cmd

    def check_restore_process(self):
        """Check whether xbstream restore is successful."""
        LOG.info('Checking return code of xbstream restore process.')
        return_code = self.process.returncode
        if return_code != 0:
            LOG.error('xbstream exited with %s', return_code)
            return False
        return True

    def post_restore(self):
        """Hook that is called after the restore command."""
        LOG.info("Running innobackupex prepare: %s.", self.prepare_command)
        stdout, stderr = processutils.execute(*self.prepare_command.split())
        LOG.info("the prepare command stdout: %s, stderr: %s", stdout, stderr)
        if not stderr:
            msg = "innobackupex prepare log file empty"
            raise Exception(msg)

        last_line = stderr.splitlines()[-1].strip()
        if not re.search('completed OK!', last_line):
            msg = "innobackupex prepare did not complete successfully"
            raise Exception(msg)


class InnoBackupExIncremental(InnoBackupEx):
    """InnoBackupEx incremental backup."""

    incremental_prep = ('innobackupex'
                        ' --defaults-file=%(restore_location)s/backup-my.cnf'
                        ' --ibbackup=xtrabackup'
                        ' --apply-log'
                        ' --redo-only'
                        ' %(restore_location)s'
                        ' %(incremental_args)s')

    def __init__(self, *args, **kwargs):
        if not kwargs.get('lsn'):
            raise AttributeError('lsn attribute missing')
        self.parent_location = kwargs.pop('parent_location', '')
        self.parent_checksum = kwargs.pop('parent_checksum', '')

        super(InnoBackupExIncremental, self).__init__(*args, **kwargs)

    @property
    def cmd(self):
        cmd = ('innobackupex'
               ' --stream=xbstream'
               ' --incremental'
               ' --incremental-lsn=%(lsn)s ' +
               self.user_and_pass + ' %s' % self.datadir)
        return cmd

    def get_metadata(self):
        _meta = super(InnoBackupExIncremental, self).get_metadata()

        _meta.update({
            'parent_location': self.parent_location,
            'parent_checksum': self.parent_checksum,
        })
        return _meta

    def run_restore(self):
        """Run incremental restore.

        First grab all parents and prepare them with '--redo-only'. After
        all backups are restored the super class InnoBackupEx post_restore
        method is called to do the final prepare with '--apply-log'
        """
        LOG.debug('Running incremental restore')
        self.incremental_restore(self.location, self.checksum)
        return self.restore_content_length