def _move_binlogs(source, destination, log_type, options, basename=None, index_file=None, skip_latest=False): """Move binary log files of the specified type. This auxiliary function moves the binary log files of a specific type (i.e., binary or relay) from the given source to the specified destination directory. It gets the files only for the specified binary log type and applies any filtering in accordance to the specified options. Resulting files are moved and the respective index file updated accordingly. source[in] Source location of the binary log files to move. destination[in] Destination directory for the binary log files. log_type[in] Type of the binary log files ('bin' or 'relay'). options[in] Dictionary of options (modified_before, sequence, verbosity). basename[in] Base name for the binary log files, i.e. filename without the extension (sequence number). index_file[in] Path of the binary log index file. If not specified it is assumed to be located in the source directory and determined based on the basename of the first found binary log file. skip_latest[in] Bool value indication if the latest binary log file (with the higher sequence value; in use by the server) will be skipped or not. By default = False, meaning that no binary log file is skipped. Returns the number of files moved. """ verbosity = options['verbosity'] binlog_files = [] file_type = '{0}-log'.format(log_type) if basename: # Ignore path from basename if specified, source is used instead. _, basename = os.path.split(basename) # Get binary log files to move. for _, _, filenames in os.walk(source): for f_name in sorted(filenames): if is_binary_log_filename(f_name, log_type, basename): binlog_files.append(f_name) break if skip_latest: # Skip last file (with the highest sequence). # Note; filenames are sorted by ascending order. binlog_files = binlog_files[:-1] if not binlog_files: # No binary log files found to move. print(_WARN_MSG_NO_FILE.format(file_type=file_type)) else: # Apply filters. sequence = options.get('sequence', None) if sequence: print("#") print(_INFO_MSG_APPLY_FILTERS.format(filter_type='sequence', file_type=file_type)) binlog_files = filter_binary_logs_by_sequence(binlog_files, sequence) modified_before = options.get('modified_before', None) if modified_before: print("#") print(_INFO_MSG_APPLY_FILTERS.format(filter_type='modified date', file_type=file_type)) binlog_files = filter_binary_logs_by_date(binlog_files, source, modified_before) # Move files. print("#") if binlog_files: if index_file is None: # Get binary log index file. index_file = get_index_file(source, binlog_files[0]) if verbosity > 0: print(_INFO_MSG_INDEX_FILE.format(file_type=file_type, index_file=index_file)) print("#") print(_INFO_MSG_MOVE_FILES.format(file_type=file_type)) for f_name in binlog_files: try: print("# - {0}".format(f_name)) move_binary_log(source, destination, f_name, index_file) except (shutil.Error, IOError) as err: raise UtilError(_ERR_MSG_MOVE_FILE.format(filename=f_name, error=err)) return len(binlog_files) else: print(_INFO_MSG_NO_FILES_TO_MOVE.format(file_type=file_type)) return 0
def _move_binlogs(source, destination, log_type, options, basename=None, index_file=None, skip_latest=False): """Move binary log files of the specified type. This auxiliary function moves the binary log files of a specific type (i.e., binary or relay) from the given source to the specified destination directory. It gets the files only for the specified binary log type and applies any filtering in accordance to the specified options. Resulting files are moved and the respective index file updated accordingly. source[in] Source location of the binary log files to move. destination[in] Destination directory for the binary log files. log_type[in] Type of the binary log files ('bin' or 'relay'). options[in] Dictionary of options (modified_before, sequence, verbosity). basename[in] Base name for the binary log files, i.e. filename without the extension (sequence number). index_file[in] Path of the binary log index file. If not specified it is assumed to be located in the source directory and determined based on the basename of the first found binary log file. skip_latest[in] Bool value indication if the latest binary log file (with the higher sequence value; in use by the server) will be skipped or not. By default = False, meaning that no binary log file is skipped. Returns the number of files moved. """ verbosity = options['verbosity'] binlog_files = [] file_type = '{0}-log'.format(log_type) if basename: # Ignore path from basename if specified, source is used instead. _, basename = os.path.split(basename) # Get binary log files to move. for _, _, filenames in os.walk(source): for f_name in sorted(filenames): if is_binary_log_filename(f_name, log_type, basename): binlog_files.append(f_name) break if skip_latest: # Skip last file (with the highest sequence). # Note; filenames are sorted by ascending order. binlog_files = binlog_files[:-1] if not binlog_files: # No binary log files found to move. print(_WARN_MSG_NO_FILE.format(file_type=file_type)) else: # Apply filters. sequence = options.get('sequence', None) if sequence: print("#") print( _INFO_MSG_APPLY_FILTERS.format(filter_type='sequence', file_type=file_type)) binlog_files = filter_binary_logs_by_sequence( binlog_files, sequence) modified_before = options.get('modified_before', None) if modified_before: print("#") print( _INFO_MSG_APPLY_FILTERS.format(filter_type='modified date', file_type=file_type)) binlog_files = filter_binary_logs_by_date(binlog_files, source, modified_before) # Move files. print("#") if binlog_files: if index_file is None: # Get binary log index file. index_file = get_index_file(source, binlog_files[0]) if verbosity > 0: print( _INFO_MSG_INDEX_FILE.format(file_type=file_type, index_file=index_file)) print("#") print(_INFO_MSG_MOVE_FILES.format(file_type=file_type)) for f_name in binlog_files: try: print("# - {0}".format(f_name)) move_binary_log(source, destination, f_name, index_file) except (shutil.Error, IOError) as err: raise UtilError( _ERR_MSG_MOVE_FILE.format(filename=f_name, error=err)) return len(binlog_files) else: print(_INFO_MSG_NO_FILES_TO_MOVE.format(file_type=file_type)) return 0
def test_is_binary_log_filename(self): # Check valid default binlog filenames. binlogs = ('foo-bin.000001', 'mysql-bin.999999') for filename in binlogs: self.assertTrue( is_binary_log_filename(filename, log_type=LOG_TYPE_BIN) ) # Check valid default relay log filenames. relay_logs = ('foo-relay-bin.000001', 'mysql-relay-bin.999999') for filename in relay_logs: self.assertTrue( is_binary_log_filename(filename, log_type=LOG_TYPE_RELAY) ) # Check valid default binary log (binlog and relay log) filenames. binary_logs = binlogs + relay_logs for filename in binary_logs: self.assertTrue( is_binary_log_filename(filename, log_type=LOG_TYPE_ALL) ) # Check valid binary logs with a specific basename. basename = 'my-custom_filename' filename = '{0}.004321'.format(basename) for log_type in LOG_TYPES: self.assertTrue( is_binary_log_filename(filename, log_type=log_type, basename=basename) ) # Check invalid default binlog filenames. not_binlogs = ('bin-foo.000001', 'foo_bin.000001', 'foo.bin.', 'mysql-bin.log') not_binlogs = not_binlogs + relay_logs for filename in not_binlogs: self.assertFalse( is_binary_log_filename(filename, log_type=LOG_TYPE_BIN) ) # Check invalid default relay log filenames. not_relay_logs = ('relay-bin-foo.000001', 'foo_relay-bin.000001', 'foo.relay-bin', 'mysql-relay-bin.log') not_relay_logs = not_relay_logs + binlogs for filename in not_relay_logs: self.assertFalse( is_binary_log_filename(filename, log_type=LOG_TYPE_RELAY) ) # Check invalid default binary log (binlog and relay log) filenames. not_binary_logs = ('bin-foo.000001', 'foo_bin.000001', 'foo.bin.', 'mysql-bin.log', 'relay-bin-foo.000001', 'foo_relay_bin.000001', 'foo.relay-bin', 'mysql-relay-bin.log') for filename in not_binary_logs: self.assertFalse( is_binary_log_filename(filename, log_type=LOG_TYPE_ALL) ) # Check invalid binary logs with a specific basename. basename = 'my-custom_filename' not_custom_logs = ('{0}.log'.format(basename),) + binlogs + relay_logs for log_type in LOG_TYPES: for filename in not_custom_logs: self.assertFalse( is_binary_log_filename(filename, log_type=log_type, basename=basename) ) # Check invalid log type. self.assertRaises(UtilError, is_binary_log_filename, 'mysql-bin.0000001', log_type='invalid-type')