def restore_from_mysql(config,
                       copy,
                       dst_dir,
                       tmp_dir=None,
                       cache=None,
                       hostname=None):
    """
    Restore MySQL datadir in a given directory

    :param config: Tool configuration.
    :type config: ConfigParser.ConfigParser
    :param copy: Backup copy instance.
    :type copy: MySQLCopy
    :param dst_dir: Destination directory. Must exist and be empty.
    :type dst_dir: str
    :param tmp_dir: Path to temp directory
    :type tmp_dir: str
    :param cache: Local cache object.
    :type cache: Cache
    :param hostname: Hostname
    :type hostname: str

    """
    LOG.info('Restoring %s in %s', copy, dst_dir)
    mkdir_p(dst_dir)

    dst = None
    restore_start = time.time()

    try:
        xtrabackup_binary = config.get('mysql', 'xtrabackup_binary')
    except ConfigParser.NoOptionError:
        xtrabackup_binary = XTRABACKUP_BINARY
    try:
        xbstream_binary = config.get('mysql', 'xbstream_binary')
    except ConfigParser.NoOptionError:
        xbstream_binary = XBSTREAM_BINARY

    try:
        keep_local_path = config.get('destination', 'keep_local_path')
        if osp.exists(osp.join(keep_local_path, copy.key)):
            dst = Local(keep_local_path)
    except ConfigParser.NoOptionError:
        pass

    if not dst:
        if not hostname:
            hostname = copy.host
            if not hostname:
                raise DestinationError('Failed to get hostname from %s' % copy)
        dst = get_destination(config, hostname=hostname)

    key = copy.key
    status = dst.status()

    stream = dst.get_stream(copy)

    if status[key].type == "full":

        cache_key = os.path.basename(key)
        if cache:
            if cache_key in cache:
                # restore from cache
                cache.restore_in(cache_key, dst_dir)
            else:
                restore_from_mysql_full(stream,
                                        dst_dir,
                                        config,
                                        redo_only=False,
                                        xtrabackup_binary=xtrabackup_binary,
                                        xbstream_binary=xbstream_binary)
                cache.add(dst_dir, cache_key)
        else:
            restore_from_mysql_full(stream,
                                    dst_dir,
                                    config,
                                    redo_only=False,
                                    xtrabackup_binary=xtrabackup_binary,
                                    xbstream_binary=xbstream_binary)

    else:
        full_copy = status.candidate_parent(copy.run_type)
        full_stream = dst.get_stream(full_copy)
        LOG.debug("Full parent copy is %s", full_copy.key)
        cache_key = os.path.basename(full_copy.key)

        if cache:
            if cache_key in cache:
                # restore from cache
                cache.restore_in(cache_key, dst_dir)
            else:
                restore_from_mysql_full(full_stream,
                                        dst_dir,
                                        config,
                                        redo_only=True,
                                        xtrabackup_binary=xtrabackup_binary,
                                        xbstream_binary=xbstream_binary)
                cache.add(dst_dir, cache_key)
        else:
            restore_from_mysql_full(full_stream,
                                    dst_dir,
                                    config,
                                    redo_only=True,
                                    xtrabackup_binary=xtrabackup_binary,
                                    xbstream_binary=xbstream_binary)

        restore_from_mysql_incremental(stream,
                                       dst_dir,
                                       config,
                                       tmp_dir,
                                       xtrabackup_binary=xtrabackup_binary,
                                       xbstream_binary=xbstream_binary)

    config_dir = os.path.join(dst_dir, "_config")

    for path, content in get_my_cnf(status, key):
        config_sub_dir = os.path.join(config_dir,
                                      os.path.dirname(path).lstrip('/'))
        mkdir_p(config_sub_dir, mode=0755)

        with open(os.path.join(config_sub_dir, os.path.basename(path)),
                  'w') as mysql_config:
            mysql_config.write(content)

    update_grastate(dst_dir, status, key)
    export_info(config,
                data=time.time() - restore_start,
                category=ExportCategory.mysql,
                measure_type=ExportMeasureType.restore)
    LOG.info('Successfully restored %s in %s.', copy.key, dst_dir)
    LOG.info(
        'Now copy content of %s to MySQL datadir: '
        'cp -R %s /var/lib/mysql/', dst_dir, osp.join(dst_dir, '*'))
    LOG.info('Fix permissions: chown -R mysql:mysql /var/lib/mysql/')
    LOG.info(
        'Make sure innodb_log_file_size and innodb_log_files_in_group '
        'in %s/backup-my.cnf and in /etc/my.cnf are same.', dst_dir)

    if osp.exists(config_dir):
        LOG.info('Original my.cnf is restored in %s.', config_dir)

    LOG.info('Then you can start MySQL normally.')
Esempio n. 2
0
 def callback(self, **kwargs):
     local_dst = Local(kwargs['keep_local_path'])
     local_dst.status(kwargs['dst'].status())
Esempio n. 3
0
def restore_from_mysql(config, backup_copy, dst_dir, cache=None):
    """
    Restore MySQL datadir in a given directory

    :param config: Tool configuration.
    :type config: ConfigParser.ConfigParser
    :param backup_copy: Backup copy name.
    :type backup_copy: str
    :param dst_dir: Destination directory. Must exist and be empty.
    :type dst_dir: str
    :param cache: Local cache object.
    :type cache: Cache
    """
    LOG.info('Restoring %s in %s', backup_copy, dst_dir)
    mkdir_p(dst_dir)

    dst = None

    try:
        keep_local_path = config.get('destination', 'keep_local_path')
        if os.path.exists(backup_copy) \
                and backup_copy.startswith(keep_local_path):
            dst = Local(keep_local_path)
    except ConfigParser.NoOptionError:
        pass

    if not dst:
        hostname = get_hostname_from_backup_copy(backup_copy)
        if not hostname:
            raise DestinationError('Failed to get hostname from %s'
                                   % backup_copy)
        dst = get_destination(config, hostname=hostname)

    key = dst.basename(backup_copy)
    status = dst.status()

    stream = dst.get_stream(backup_copy)

    if get_backup_type(status, key) == "full":

        cache_key = os.path.basename(key)
        if cache:
            if cache_key in cache:
                # restore from cache
                cache.restore_in(cache_key, dst_dir)
            else:
                restore_from_mysql_full(stream, dst_dir, config)
                cache.add(dst_dir, cache_key)
        else:
            restore_from_mysql_full(stream, dst_dir, config)

    else:
        full_copy = dst.get_full_copy_name(backup_copy)

        full_stream = dst.get_stream(full_copy)

        cache_key = os.path.basename(full_copy)

        if cache:
            if cache_key in cache:
                # restore from cache
                cache.restore_in(cache_key, dst_dir)
            else:
                restore_from_mysql_full(full_stream, dst_dir,
                                        config, redo_only=True)
                cache.add(dst_dir, cache_key)
        else:
            restore_from_mysql_full(full_stream, dst_dir,
                                    config, redo_only=True)

        restore_from_mysql_incremental(stream, dst_dir, config)

    config_dir = os.path.join(dst_dir, "_config")

    for path, content in get_my_cnf(status, key):
        config_sub_dir = os.path.join(config_dir,
                                      os.path.dirname(path).lstrip('/'))
        os.makedirs(config_sub_dir)

        with open(os.path.join(config_sub_dir,
                               os.path.basename(path)), 'w') as mysql_config:
            mysql_config.write(content)

    update_grastate(dst_dir, status, key)

    LOG.info('Successfully restored %s in %s.', backup_copy, dst_dir)
    LOG.info('Now copy content of %s to MySQL datadir: '
             'cp -R %s/* /var/lib/mysql/', dst_dir, dst_dir)
    LOG.info('Fix permissions: chown -R mysql:mysql /var/lib/mysql/')
    LOG.info('Make sure innodb_log_file_size and innodb_log_files_in_group '
             'in %s/backup-my.cnf and in /etc/my.cnf are same.', dst_dir)

    if os.path.exists(config_dir):
        LOG.info('Original my.cnf is restored in %s.', config_dir)

    LOG.info('Then you can start MySQL normally.')