mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge 10.2 into 10.3
This commit is contained in:
commit
950a220060
37 changed files with 986 additions and 778 deletions
|
@ -214,7 +214,7 @@ ibx_mode_t ibx_mode = IBX_MODE_BACKUP;
|
|||
|
||||
static struct my_option ibx_long_options[] =
|
||||
{
|
||||
{"version", 'v', "print xtrabackup version information",
|
||||
{"version", 'v', "print version information",
|
||||
(uchar *) &opt_ibx_version, (uchar *) &opt_ibx_version, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
|
@ -257,12 +257,11 @@ static struct my_option ibx_long_options[] =
|
|||
(uchar *) &opt_ibx_slave_info, (uchar *) &opt_ibx_slave_info, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"incremental", OPT_INCREMENTAL, "This option tells xtrabackup to "
|
||||
"create an incremental backup, rather than a full one. It is passed "
|
||||
"to the xtrabackup child process. When this option is specified, "
|
||||
{"incremental", OPT_INCREMENTAL,
|
||||
"Create an incremental backup, rather than a full one. When this option is specified, "
|
||||
"either --incremental-lsn or --incremental-basedir can also be given. "
|
||||
"If neither option is given, option --incremental-basedir is passed "
|
||||
"to xtrabackup by default, set to the first timestamped backup "
|
||||
"If neither option is given, option --incremental-basedir is used "
|
||||
"by default, set to the first timestamped backup "
|
||||
"directory in the backup base directory.",
|
||||
(uchar *) &opt_ibx_incremental, (uchar *) &opt_ibx_incremental, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
@ -377,14 +376,14 @@ static struct my_option ibx_long_options[] =
|
|||
{"incremental-history-name", OPT_INCREMENTAL_HISTORY_NAME,
|
||||
"This option specifies the name of the backup series stored in the "
|
||||
"PERCONA_SCHEMA.xtrabackup_history history record to base an "
|
||||
"incremental backup on. Xtrabackup will search the history table "
|
||||
"incremental backup on. Backup will search the history table "
|
||||
"looking for the most recent (highest innodb_to_lsn), successful "
|
||||
"backup in the series and take the to_lsn value to use as the "
|
||||
"starting lsn for the incremental backup. This will be mutually "
|
||||
"exclusive with --incremental-history-uuid, --incremental-basedir "
|
||||
"and --incremental-lsn. If no valid lsn can be found (no series by "
|
||||
"that name, no successful backups by that name) xtrabackup will "
|
||||
"return with an error. It is used with the --incremental option.",
|
||||
"that name, no successful backups by that name), "
|
||||
"an error will be returned. It is used with the --incremental option.",
|
||||
(uchar*) &opt_ibx_incremental_history_name,
|
||||
(uchar*) &opt_ibx_incremental_history_name, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
@ -394,8 +393,8 @@ static struct my_option ibx_long_options[] =
|
|||
"stored in the PERCONA_SCHEMA.xtrabackup_history to base an "
|
||||
"incremental backup on. --incremental-history-name, "
|
||||
"--incremental-basedir and --incremental-lsn. If no valid lsn can be "
|
||||
"found (no success record with that uuid) xtrabackup will return "
|
||||
"with an error. It is used with the --incremental option.",
|
||||
"found (no success record with that uuid), an error will be returned."
|
||||
" It is used with the --incremental option.",
|
||||
(uchar*) &opt_ibx_incremental_history_uuid,
|
||||
(uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
@ -424,7 +423,7 @@ static struct my_option ibx_long_options[] =
|
|||
{"include", OPT_INCLUDE,
|
||||
"This option is a regular expression to be matched against table "
|
||||
"names in databasename.tablename format. It is passed directly to "
|
||||
"xtrabackup's --tables option. See the xtrabackup documentation for "
|
||||
"--tables option. See the documentation for "
|
||||
"details.",
|
||||
(uchar*) &opt_ibx_include,
|
||||
(uchar*) &opt_ibx_include, 0, GET_STR,
|
||||
|
@ -474,12 +473,6 @@ static struct my_option ibx_long_options[] =
|
|||
(uchar*) &opt_ibx_lock_wait_threshold, 0, GET_UINT,
|
||||
REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
|
||||
|
||||
{"debug-sleep-before-unlock", OPT_DEBUG_SLEEP_BEFORE_UNLOCK,
|
||||
"This is a debug-only option used by the XtraBackup test suite.",
|
||||
(uchar*) &opt_ibx_debug_sleep_before_unlock,
|
||||
(uchar*) &opt_ibx_debug_sleep_before_unlock, 0, GET_UINT,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT,
|
||||
"How many seconds --safe-slave-backup should wait for "
|
||||
"Slave_open_temp_tables to become zero. (default 300)",
|
||||
|
@ -492,22 +485,20 @@ static struct my_option ibx_long_options[] =
|
|||
We put them here with only purpose for them to showup in
|
||||
innobackupex --help output */
|
||||
|
||||
{"close_files", OPT_CLOSE_FILES, "Do not keep files opened. This "
|
||||
"option is passed directly to xtrabackup. Use at your own risk.",
|
||||
{"close_files", OPT_CLOSE_FILES, "Do not keep files opened."
|
||||
" Use at your own risk.",
|
||||
(uchar*) &ibx_xb_close_files, (uchar*) &ibx_xb_close_files, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"compress", OPT_COMPRESS, "This option instructs xtrabackup to "
|
||||
"compress backup copies of InnoDB data files. It is passed directly "
|
||||
"to the xtrabackup child process. Try 'xtrabackup --help' for more "
|
||||
"details.", (uchar*) &ibx_xtrabackup_compress_alg,
|
||||
{"compress", OPT_COMPRESS, "This option instructs backup to "
|
||||
"compress backup copies of InnoDB data files."
|
||||
, (uchar*) &ibx_xtrabackup_compress_alg,
|
||||
(uchar*) &ibx_xtrabackup_compress_alg, 0,
|
||||
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"compress-threads", OPT_COMPRESS_THREADS,
|
||||
"This option specifies the number of worker threads that will be used "
|
||||
"for parallel compression. It is passed directly to the xtrabackup "
|
||||
"child process. Try 'xtrabackup --help' for more details.",
|
||||
"for parallel compression.",
|
||||
(uchar*) &ibx_xtrabackup_compress_threads,
|
||||
(uchar*) &ibx_xtrabackup_compress_threads,
|
||||
0, GET_UINT, REQUIRED_ARG, 1, 1, UINT_MAX, 0, 0, 0},
|
||||
|
@ -518,17 +509,15 @@ static struct my_option ibx_long_options[] =
|
|||
(uchar*) &ibx_xtrabackup_compress_chunk_size,
|
||||
0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0},
|
||||
|
||||
{"export", OPT_EXPORT, "This option is passed directly to xtrabackup's "
|
||||
"--export option. It enables exporting individual tables for import "
|
||||
"into another server. See the xtrabackup documentation for details.",
|
||||
{"export", OPT_EXPORT, " enables exporting individual tables for import "
|
||||
"into another server.",
|
||||
(uchar*) &ibx_xtrabackup_export, (uchar*) &ibx_xtrabackup_export,
|
||||
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"extra-lsndir", OPT_EXTRA_LSNDIR, "This option specifies the "
|
||||
"directory in which to save an extra copy of the "
|
||||
"\"xtrabackup_checkpoints\" file. The option accepts a string "
|
||||
"argument. It is passed directly to xtrabackup's --extra-lsndir "
|
||||
"option. See the xtrabackup documentation for details.",
|
||||
"argument.",
|
||||
(uchar*) &ibx_xtrabackup_extra_lsndir,
|
||||
(uchar*) &ibx_xtrabackup_extra_lsndir,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
@ -550,7 +539,7 @@ static struct my_option ibx_long_options[] =
|
|||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"incremental-force-scan", OPT_INCREMENTAL_FORCE_SCAN,
|
||||
"This options tells xtrabackup to perform full scan of data files "
|
||||
"Perform full scan of data files "
|
||||
"for taking an incremental backup even if full changed page bitmap "
|
||||
"data is available to enable the backup without the full scan.",
|
||||
(uchar*)&ibx_xtrabackup_incremental_force_scan,
|
||||
|
@ -576,10 +565,8 @@ static struct my_option ibx_long_options[] =
|
|||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"parallel", OPT_PARALLEL, "On backup, this option specifies the "
|
||||
"number of threads the xtrabackup child process should use to back "
|
||||
"up files concurrently. The option accepts an integer argument. It "
|
||||
"is passed directly to xtrabackup's --parallel option. See the "
|
||||
"xtrabackup documentation for details.",
|
||||
"number of threads to use to back "
|
||||
"up files concurrently. The option accepts an integer argument.",
|
||||
(uchar*) &ibx_xtrabackup_parallel, (uchar*) &ibx_xtrabackup_parallel,
|
||||
0, GET_INT, REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0},
|
||||
|
||||
|
@ -587,23 +574,21 @@ static struct my_option ibx_long_options[] =
|
|||
{"stream", OPT_STREAM, "This option specifies the format in which to "
|
||||
"do the streamed backup. The option accepts a string argument. The "
|
||||
"backup will be done to STDOUT in the specified format. Currently, "
|
||||
"the only supported formats are tar and mbstream/xbstream. This "
|
||||
"option is passed directly to xtrabackup's --stream option.",
|
||||
"the only supported formats are tar and mbstream/xbstream.",
|
||||
(uchar*) &ibx_xtrabackup_stream_str,
|
||||
(uchar*) &ibx_xtrabackup_stream_str, 0, GET_STR,
|
||||
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"tables-file", OPT_TABLES_FILE, "This option specifies the file in "
|
||||
"which there are a list of names of the form database. The option "
|
||||
"accepts a string argument.table, one per line. The option is passed "
|
||||
"directly to xtrabackup's --tables-file option.",
|
||||
"accepts a string argument.table, one per line.",
|
||||
(uchar*) &ibx_xtrabackup_tables_file,
|
||||
(uchar*) &ibx_xtrabackup_tables_file,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"throttle", OPT_THROTTLE, "This option specifies a number of I/O "
|
||||
"operations (pairs of read+write) per second. It accepts an integer "
|
||||
"argument. It is passed directly to xtrabackup's --throttle option.",
|
||||
"argument.",
|
||||
(uchar*) &ibx_xtrabackup_throttle, (uchar*) &ibx_xtrabackup_throttle,
|
||||
0, GET_LONG, REQUIRED_ARG, 0, 0, LONG_MAX, 0, 1, 0},
|
||||
|
||||
|
@ -615,11 +600,10 @@ static struct my_option ibx_long_options[] =
|
|||
0, 0, 0, 0, 0, 0},
|
||||
|
||||
{"use-memory", OPT_USE_MEMORY, "This option accepts a string argument "
|
||||
"that specifies the amount of memory in bytes for xtrabackup to use "
|
||||
"that specifies the amount of memory in bytes to use "
|
||||
"for crash recovery while preparing a backup. Multiples are supported "
|
||||
"providing the unit (e.g. 1MB, 1GB). It is used only with the option "
|
||||
"--apply-log. It is passed directly to xtrabackup's --use-memory "
|
||||
"option. See the xtrabackup documentation for details.",
|
||||
"--apply-log.",
|
||||
(uchar*) &ibx_xtrabackup_use_memory,
|
||||
(uchar*) &ibx_xtrabackup_use_memory,
|
||||
0, GET_LL, REQUIRED_ARG, 100*1024*1024L, 1024*1024L, LONGLONG_MAX, 0,
|
||||
|
@ -641,7 +625,7 @@ static struct my_option ibx_long_options[] =
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("Open source backup tool for InnoDB and XtraDB\n\
|
||||
puts("Open source backup tool\n\
|
||||
\n\
|
||||
Copyright (C) 2009-2015 Percona LLC and/or its affiliates.\n\
|
||||
Portions Copyright (C) 2000, 2011, MySQL AB & Innobase Oy. All Rights Reserved.\n\
|
||||
|
@ -692,7 +676,7 @@ innobackupex [--decompress]\n\
|
|||
\n\
|
||||
DESCRIPTION\n\
|
||||
\n\
|
||||
The first command line above makes a hot backup of a MySQL database.\n\
|
||||
The first command line above makes a hot backup of a database.\n\
|
||||
By default it creates a backup directory (named by the current date\n\
|
||||
and time) in the given backup root directory. With the --no-timestamp\n\
|
||||
option it does not create a time-stamped backup directory, but it puts\n\
|
||||
|
@ -702,22 +686,18 @@ indexes in all databases or in all of the databases specified with the\n\
|
|||
--databases option. The created backup contains .frm, .MRG, .MYD,\n\
|
||||
.MYI, .MAD, .MAI, .TRG, .TRN, .ARM, .ARZ, .CSM, CSV, .opt, .par, and\n\
|
||||
InnoDB data and log files. The MY.CNF options file defines the\n\
|
||||
location of the database. This command connects to the MySQL server\n\
|
||||
using the mysql client program, and runs xtrabackup as a child\n\
|
||||
process.\n\
|
||||
location of the database.\n\
|
||||
\n\
|
||||
The --apply-log command prepares a backup for starting a MySQL\n\
|
||||
server on the backup. This command recovers InnoDB data files as specified\n\
|
||||
in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/ib_logfile0,\n\
|
||||
and creates new InnoDB log files as specified in BACKUP-DIR/backup-my.cnf.\n\
|
||||
The BACKUP-DIR should be the path to a backup directory created by\n\
|
||||
xtrabackup. This command runs xtrabackup as a child process, but it does not \n\
|
||||
connect to the database server.\n\
|
||||
The BACKUP-DIR should be the path to a backup directory\n\
|
||||
\n\
|
||||
The --copy-back command copies data, index, and log files\n\
|
||||
from the backup directory back to their original locations.\n\
|
||||
The MY.CNF options file defines the original location of the database.\n\
|
||||
The BACKUP-DIR is the path to a backup directory created by xtrabackup.\n\
|
||||
The BACKUP-DIR is the path to a backup directory.\n\
|
||||
\n\
|
||||
The --move-back command is similar to --copy-back with the only difference that\n\
|
||||
it moves files to their original locations rather than copies them. As this\n\
|
||||
|
|
|
@ -261,9 +261,6 @@ it every INNOBASE_WAKE_INTERVAL'th step. */
|
|||
#define INNOBASE_WAKE_INTERVAL 32
|
||||
ulong innobase_active_counter = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
static char *xtrabackup_debug_sync = NULL;
|
||||
#endif
|
||||
|
||||
my_bool xtrabackup_incremental_force_scan = FALSE;
|
||||
|
||||
|
@ -1056,7 +1053,7 @@ enum options_xtrabackup
|
|||
struct my_option xb_client_options[]= {
|
||||
{"verbose", 'V', "display verbose output", (G_PTR *) &verbose,
|
||||
(G_PTR *) &verbose, 0, GET_BOOL, NO_ARG, FALSE, 0, 0, 0, 0, 0},
|
||||
{"version", 'v', "print xtrabackup version information",
|
||||
{"version", 'v', "print version information",
|
||||
(G_PTR *) &xtrabackup_version, (G_PTR *) &xtrabackup_version, 0, GET_BOOL,
|
||||
NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"target-dir", OPT_XTRA_TARGET_DIR, "destination directory",
|
||||
|
@ -1353,8 +1350,8 @@ struct my_option xb_client_options[]= {
|
|||
"starting lsn for the incremental backup. This will be mutually "
|
||||
"exclusive with --incremental-history-uuid, --incremental-basedir "
|
||||
"and --incremental-lsn. If no valid lsn can be found (no series by "
|
||||
"that name, no successful backups by that name) xtrabackup will "
|
||||
"return with an error. It is used with the --incremental option.",
|
||||
"that name, no successful backups by that name), an error will be returned."
|
||||
" It is used with the --incremental option.",
|
||||
(uchar *) &opt_incremental_history_name,
|
||||
(uchar *) &opt_incremental_history_name, 0, GET_STR, REQUIRED_ARG, 0, 0,
|
||||
0, 0, 0, 0},
|
||||
|
@ -1364,8 +1361,8 @@ struct my_option xb_client_options[]= {
|
|||
"stored in the PERCONA_SCHEMA.xtrabackup_history to base an "
|
||||
"incremental backup on. --incremental-history-name, "
|
||||
"--incremental-basedir and --incremental-lsn. If no valid lsn can be "
|
||||
"found (no success record with that uuid) xtrabackup will return "
|
||||
"with an error. It is used with the --incremental option.",
|
||||
"found (no success record with that uuid), an error will be returned."
|
||||
" It is used with the --incremental option.",
|
||||
(uchar *) &opt_incremental_history_uuid,
|
||||
(uchar *) &opt_incremental_history_uuid, 0, GET_STR, REQUIRED_ARG, 0, 0,
|
||||
0, 0, 0, 0},
|
||||
|
@ -1422,11 +1419,6 @@ struct my_option xb_client_options[]= {
|
|||
(uchar *) &opt_lock_wait_threshold, (uchar *) &opt_lock_wait_threshold, 0,
|
||||
GET_UINT, REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
|
||||
|
||||
{"debug-sleep-before-unlock", OPT_DEBUG_SLEEP_BEFORE_UNLOCK,
|
||||
"This is a debug-only option used by the XtraBackup test suite.",
|
||||
(uchar *) &opt_debug_sleep_before_unlock,
|
||||
(uchar *) &opt_debug_sleep_before_unlock, 0, GET_UINT, REQUIRED_ARG, 0, 0,
|
||||
0, 0, 0, 0},
|
||||
|
||||
{"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT,
|
||||
"How many seconds --safe-slave-backup should wait for "
|
||||
|
@ -1436,9 +1428,9 @@ struct my_option xb_client_options[]= {
|
|||
0, 0, 0, 0, 0},
|
||||
|
||||
{"binlog-info", OPT_BINLOG_INFO,
|
||||
"This option controls how XtraBackup should retrieve server's binary log "
|
||||
"This option controls how backup should retrieve server's binary log "
|
||||
"coordinates corresponding to the backup. Possible values are OFF, ON, "
|
||||
"LOCKLESS and AUTO. See the XtraBackup manual for more information",
|
||||
"LOCKLESS and AUTO.",
|
||||
&opt_binlog_info, &opt_binlog_info, &binlog_info_typelib, GET_ENUM,
|
||||
OPT_ARG, BINLOG_INFO_AUTO, 0, 0, 0, 0, 0},
|
||||
|
||||
|
@ -1609,13 +1601,6 @@ struct my_option xb_server_options[] =
|
|||
&dbug_option, &dbug_option, 0, GET_STR, OPT_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
#ifndef __WIN__
|
||||
{"debug-sync", OPT_XTRA_DEBUG_SYNC,
|
||||
"Debug sync point. This is only used by the xtrabackup test suite",
|
||||
(G_PTR*) &xtrabackup_debug_sync,
|
||||
(G_PTR*) &xtrabackup_debug_sync,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
|
||||
{"innodb_checksum_algorithm", OPT_INNODB_CHECKSUM_ALGORITHM,
|
||||
"The algorithm InnoDB uses for page checksumming. [CRC32, STRICT_CRC32, "
|
||||
|
@ -1659,7 +1644,7 @@ struct my_option xb_server_options[] =
|
|||
REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
|
||||
|
||||
{"lock-ddl-per-table", OPT_LOCK_DDL_PER_TABLE, "Lock DDL for each table "
|
||||
"before xtrabackup starts to copy it and until the backup is completed.",
|
||||
"before backup starts to copy it and until the backup is completed.",
|
||||
(uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
|
||||
|
@ -1690,60 +1675,6 @@ struct my_option xb_server_options[] =
|
|||
|
||||
uint xb_server_options_count = array_elements(xb_server_options);
|
||||
|
||||
#ifndef __WIN__
|
||||
static int debug_sync_resumed;
|
||||
|
||||
static void sigcont_handler(int sig);
|
||||
|
||||
static void sigcont_handler(int sig __attribute__((unused)))
|
||||
{
|
||||
debug_sync_resumed= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline
|
||||
void
|
||||
debug_sync_point(const char *name)
|
||||
{
|
||||
#ifndef __WIN__
|
||||
FILE *fp;
|
||||
pid_t pid;
|
||||
char pid_path[FN_REFLEN];
|
||||
|
||||
if (xtrabackup_debug_sync == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(xtrabackup_debug_sync, name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pid = getpid();
|
||||
|
||||
snprintf(pid_path, sizeof(pid_path), "%s/xtrabackup_debug_sync",
|
||||
xtrabackup_target_dir);
|
||||
fp = fopen(pid_path, "w");
|
||||
if (fp == NULL) {
|
||||
die("Can't open open %s", pid_path);
|
||||
}
|
||||
fprintf(fp, "%u\n", (uint) pid);
|
||||
fclose(fp);
|
||||
|
||||
msg("mariabackup: DEBUG: Suspending at debug sync point '%s'. "
|
||||
"Resume with 'kill -SIGCONT %u'.", name, (uint) pid);
|
||||
|
||||
debug_sync_resumed= 0;
|
||||
kill(pid, SIGSTOP);
|
||||
while (!debug_sync_resumed) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
/* On resume */
|
||||
msg("mariabackup: DEBUG: removing the pid file.");
|
||||
my_delete(pid_path, MYF(MY_WME));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static std::set<std::string> tables_for_export;
|
||||
|
||||
|
@ -3106,8 +3037,6 @@ static bool xtrabackup_copy_logfile(bool last = false)
|
|||
log_copy_scanned_lsn = start_lsn;
|
||||
pthread_cond_broadcast(&scanned_lsn_cond);
|
||||
pthread_mutex_unlock(&backup_mutex);
|
||||
|
||||
debug_sync_point("xtrabackup_copy_logfile_pause");
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
@ -3239,8 +3168,6 @@ DECLARE_THREAD(data_copy_thread_func)(
|
|||
*/
|
||||
my_thread_init();
|
||||
|
||||
debug_sync_point("data_copy_thread_func");
|
||||
|
||||
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
|
||||
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
|
||||
DBUG_EXECUTE_FOR_KEY("wait_innodb_redo_before_copy", node->space->name,
|
||||
|
@ -3771,8 +3698,6 @@ xb_load_tablespaces()
|
|||
if (err != DB_SUCCESS) {
|
||||
return(err);
|
||||
}
|
||||
|
||||
debug_sync_point("xtrabackup_load_tablespaces_pause");
|
||||
DBUG_MARIABACKUP_EVENT("after_load_tablespaces", 0);
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
@ -4607,8 +4532,6 @@ fail_before_log_copying_thread_start:
|
|||
if (!flush_changed_page_bitmaps()) {
|
||||
goto fail;
|
||||
}
|
||||
debug_sync_point("xtrabackup_suspend_at_start");
|
||||
|
||||
|
||||
ut_a(xtrabackup_parallel > 0);
|
||||
|
||||
|
@ -6818,12 +6741,6 @@ static int main_low(char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef __WIN__
|
||||
if (xtrabackup_debug_sync) {
|
||||
signal(SIGCONT, sigcont_handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* --backup */
|
||||
if (xtrabackup_backup && !xtrabackup_backup_func()) {
|
||||
return(EXIT_FAILURE);
|
||||
|
|
|
@ -628,7 +628,7 @@ sub self2str {
|
|||
|
||||
sub _verbose {
|
||||
return unless $_verbose;
|
||||
print STDERR " ## ". @_. "\n";
|
||||
print STDERR " ## @_\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5533,5 +5533,23 @@ Note 1003 /* select#1 */ select (/* select#2 */ select 1 from `test`.`t2` where
|
|||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# MDEV-25576: The statement EXPLAIN running as regular statement and
|
||||
# as prepared statement produces different results for
|
||||
# UPDATE with subquery
|
||||
#
|
||||
CREATE TABLE t1 (c1 INT KEY) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (c3 INT) ENGINE=MyISAM;
|
||||
EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 );
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
PREPARE stmt FROM "EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 )";
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 0 100.00
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1, t2, t3;
|
||||
# End of 10.2 tests
|
||||
#
|
||||
|
|
|
@ -4983,6 +4983,20 @@ SHOW WARNINGS;
|
|||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25576: The statement EXPLAIN running as regular statement and
|
||||
--echo # as prepared statement produces different results for
|
||||
--echo # UPDATE with subquery
|
||||
--echo #
|
||||
CREATE TABLE t1 (c1 INT KEY) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (c2 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (c3 INT) ENGINE=MyISAM;
|
||||
EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 );
|
||||
PREPARE stmt FROM "EXPLAIN EXTENDED UPDATE t3 SET c3 = ( SELECT COUNT(d1.c1) FROM ( SELECT a11.c1 FROM t1 AS a11 STRAIGHT_JOIN t2 AS a21 ON a21.c2 = a11.c1 JOIN t1 AS a12 ON a12.c1 = a11.c1 ) d1 )";
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
|
|
@ -9,4 +9,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
|||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
|
|
@ -11,4 +11,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
|||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
|
|
@ -8,5 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
|||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
||||
|
|
|
@ -13,4 +13,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
|
|||
|
||||
[sst]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
streamfmt=mbstream
|
||||
|
|
|
@ -10,3 +10,4 @@ transferfmt=@ENV.MTR_GALERA_TFMT
|
|||
compress=quicklz
|
||||
compress-threads=2
|
||||
compress-chunk-size=32768
|
||||
backup-threads=2
|
||||
|
|
|
@ -15,4 +15,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
|
|||
|
||||
[sst]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
streamfmt=mbstream
|
||||
|
|
|
@ -8,4 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
|||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
|
||||
|
|
|
@ -12,4 +12,3 @@ log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server1_binlog_index.index
|
|||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
log_bin=@ENV.MYSQLTEST_VARDIR/server2_binlog
|
||||
log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index
|
||||
|
||||
|
|
|
@ -9,3 +9,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
|||
[mysqld.2]
|
||||
innodb_data_home_dir=@ENV.MYSQL_TMP_DIR/rsync_test_2
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
|
||||
[sst]
|
||||
backup_threads=2
|
||||
|
|
|
@ -34,4 +34,3 @@ bind-address=::
|
|||
[SST]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
sockopt=",pf=ip6"
|
||||
|
|
|
@ -38,4 +38,5 @@ bind-address=::
|
|||
[SST]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
# Not needed, but left here for debugging:
|
||||
sockopt=",pf=ip6"
|
||||
|
|
|
@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
|
|||
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
|
||||
wsrep_node_incoming_address='[::1]:@mysqld.3.port'
|
||||
bind-address=::
|
||||
|
||||
[SST]
|
||||
sockopt=",pf=ip6"
|
||||
|
|
|
@ -24,6 +24,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
|
|||
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
|
||||
wsrep_node_incoming_address='[::1]:@mysqld.3.port'
|
||||
bind-address=::
|
||||
|
||||
[SST]
|
||||
sockopt=",pf=ip6"
|
||||
|
|
|
@ -29,6 +29,3 @@ wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.
|
|||
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
|
||||
wsrep_node_incoming_address='[::1]:@mysqld.3.port'
|
||||
bind-address=::
|
||||
|
||||
[SST]
|
||||
sockopt=",pf=ip6"
|
||||
|
|
|
@ -1480,9 +1480,20 @@ FROM buildings, bridges
|
|||
WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
|
||||
count(*)
|
||||
1
|
||||
DROP DATABASE gis_ogs;
|
||||
#
|
||||
# Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE
|
||||
#
|
||||
SELECT ST_Union('', ''), md5(1);
|
||||
ERROR HY000: Illegal parameter data type varchar for operation 'st_union'
|
||||
#
|
||||
# MDEV-25758 InnoDB spatial indexes miss large geometry
|
||||
# fields after MDEV-25459
|
||||
#
|
||||
CREATE TABLE t1(l LINESTRING NOT NULL, SPATIAL INDEX(l))ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
||||
SELECT GROUP_CONCAT(CONCAT(seq, ' ', seq) SEPARATOR ',') INTO @g FROM seq_0_to_190;
|
||||
INSERT INTO t1 SET l=ST_GeomFromText(CONCAT('LINESTRING(',@g,',0 0)'));
|
||||
SELECT COUNT(*) FROM t1 WHERE MBRIntersects(GeomFromText('Polygon((0 0,0 10,10 10,10 0,0 0))'), l);
|
||||
COUNT(*)
|
||||
1
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE gis_ogs;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
--source include/have_innodb.inc
|
||||
-- source include/have_geometry.inc
|
||||
--source include/have_sequence.inc
|
||||
|
||||
SET default_storage_engine=InnoDB;
|
||||
|
||||
|
@ -1424,11 +1425,21 @@ WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
|
|||
#FROM lakes
|
||||
#WHERE lakes.name = 'Blue Lake';
|
||||
|
||||
DROP DATABASE gis_ogs;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE
|
||||
--echo #
|
||||
|
||||
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
|
||||
SELECT ST_Union('', ''), md5(1);
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-25758 InnoDB spatial indexes miss large geometry
|
||||
--echo # fields after MDEV-25459
|
||||
--echo #
|
||||
CREATE TABLE t1(l LINESTRING NOT NULL, SPATIAL INDEX(l))ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
||||
SELECT GROUP_CONCAT(CONCAT(seq, ' ', seq) SEPARATOR ',') INTO @g FROM seq_0_to_190;
|
||||
INSERT INTO t1 SET l=ST_GeomFromText(CONCAT('LINESTRING(',@g,',0 0)'));
|
||||
SELECT COUNT(*) FROM t1 WHERE MBRIntersects(GeomFromText('Polygon((0 0,0 10,10 10,10 0,0 0))'), l);
|
||||
DROP TABLE t1;
|
||||
|
||||
DROP DATABASE gis_ogs;
|
||||
|
|
|
@ -29,7 +29,9 @@ WSREP_SST_OPT_USER="${WSREP_SST_OPT_USER:-}"
|
|||
WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_PSWD:-}"
|
||||
WSREP_SST_OPT_REMOTE_AUTH="${WSREP_SST_OPT_REMOTE_AUTH:-}"
|
||||
WSREP_SST_OPT_DEFAULT=""
|
||||
WSREP_SST_OPT_DEFAULTS=""
|
||||
WSREP_SST_OPT_EXTRA_DEFAULT=""
|
||||
WSREP_SST_OPT_EXTRA_DEFAULTS=""
|
||||
WSREP_SST_OPT_SUFFIX_DEFAULT=""
|
||||
WSREP_SST_OPT_SUFFIX_VALUE=""
|
||||
WSREP_SST_OPT_MYSQLD=""
|
||||
|
@ -152,10 +154,12 @@ case "$1" in
|
|||
;;
|
||||
'--defaults-file')
|
||||
readonly WSREP_SST_OPT_DEFAULT="$1=$2"
|
||||
readonly WSREP_SST_OPT_DEFAULTS="$1='$2'"
|
||||
shift
|
||||
;;
|
||||
'--defaults-extra-file')
|
||||
readonly WSREP_SST_OPT_EXTRA_DEFAULT="$1=$2"
|
||||
readonly WSREP_SST_OPT_EXTRA_DEFAULTS="$1='$2'"
|
||||
shift
|
||||
;;
|
||||
'--defaults-group-suffix')
|
||||
|
@ -295,7 +299,7 @@ case "$1" in
|
|||
value="$1"
|
||||
fi
|
||||
fi
|
||||
if [ $option == 'h' ]; then
|
||||
if [ $option = 'h' ]; then
|
||||
if [ -z "$WSREP_SST_OPT_DATA" ]; then
|
||||
MYSQLD_OPT_DATADIR="${value%/}"
|
||||
fi
|
||||
|
@ -611,24 +615,54 @@ else
|
|||
MYSQLDUMP="$(command -v mysqldump)"
|
||||
fi
|
||||
|
||||
wsrep_log()
|
||||
{
|
||||
# echo everything to stderr so that it gets into common error log
|
||||
# deliberately made to look different from the rest of the log
|
||||
local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
|
||||
echo "WSREP_SST: $* ($tst)" >&2
|
||||
}
|
||||
|
||||
wsrep_log_error()
|
||||
{
|
||||
wsrep_log "[ERROR] $*"
|
||||
}
|
||||
|
||||
wsrep_log_warning()
|
||||
{
|
||||
wsrep_log "[WARNING] $*"
|
||||
}
|
||||
|
||||
wsrep_log_info()
|
||||
{
|
||||
wsrep_log "[INFO] $*"
|
||||
}
|
||||
|
||||
if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
|
||||
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
|
||||
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
|
||||
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
|
||||
else
|
||||
MY_PRINT_DEFAULTS="$(command -v my_print_defaults)"
|
||||
if [ -z "$MY_PRINT_DEFAULTS" ]; then
|
||||
wsrep_log_error "my_print_defaults not found in path"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
readonly MY_PRINT_DEFAULTS
|
||||
|
||||
wsrep_defaults="$WSREP_SST_OPT_DEFAULTS"
|
||||
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS"
|
||||
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
|
||||
|
||||
readonly WSREP_SST_OPT_CONF="$wsrep_defaults"
|
||||
|
||||
wsrep_defaults="$WSREP_SST_OPT_DEFAULT"
|
||||
if [ -n "$wsrep_defaults" ]; then
|
||||
wsrep_defaults="$wsrep_defaults "
|
||||
fi
|
||||
wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT"
|
||||
if [ -n "$wsrep_defaults" ]; then
|
||||
wsrep_defaults="$wsrep_defaults "
|
||||
fi
|
||||
readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT"
|
||||
readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF"
|
||||
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT"
|
||||
wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
|
||||
|
||||
readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults"
|
||||
|
||||
#
|
||||
# User can specify mariabackup specific settings that will be used during sst
|
||||
|
@ -663,13 +697,21 @@ parse_cnf()
|
|||
# If the group name is the same as the "mysqld" without "--" prefix,
|
||||
# then try to use it together with the group suffix:
|
||||
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
|
||||
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
|
||||
reval=$("$MY_PRINT_DEFAULTS" \
|
||||
${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
|
||||
${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
|
||||
${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
|
||||
"mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
|
||||
if [ -n "$reval" ]; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
# Let's try to use the group name as it is:
|
||||
reval=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern")
|
||||
reval=$("$MY_PRINT_DEFAULTS" \
|
||||
${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
|
||||
${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
|
||||
${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
|
||||
"$group" | awk "$pattern")
|
||||
if [ -n "$reval" ]; then
|
||||
break
|
||||
fi
|
||||
|
@ -710,13 +752,21 @@ in_config()
|
|||
# If the group name is the same as the "mysqld" without "--" prefix,
|
||||
# then try to use it together with the group suffix:
|
||||
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
|
||||
found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
|
||||
found=$("$MY_PRINT_DEFAULTS" \
|
||||
${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
|
||||
${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
|
||||
${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
|
||||
"mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
|
||||
if [ $found -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
# Let's try to use the group name as it is:
|
||||
found=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern")
|
||||
found=$($MY_PRINT_DEFAULTS \
|
||||
${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
|
||||
${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
|
||||
${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
|
||||
"$group" | awk "$pattern")
|
||||
if [ $found -ne 0 ]; then
|
||||
break
|
||||
fi
|
||||
|
@ -797,29 +847,6 @@ else
|
|||
SST_PROGRESS_FILE=""
|
||||
fi
|
||||
|
||||
wsrep_log()
|
||||
{
|
||||
# echo everything to stderr so that it gets into common error log
|
||||
# deliberately made to look different from the rest of the log
|
||||
local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
|
||||
echo "WSREP_SST: $* ($tst)" >&2
|
||||
}
|
||||
|
||||
wsrep_log_error()
|
||||
{
|
||||
wsrep_log "[ERROR] $*"
|
||||
}
|
||||
|
||||
wsrep_log_warning()
|
||||
{
|
||||
wsrep_log "[WARNING] $*"
|
||||
}
|
||||
|
||||
wsrep_log_info()
|
||||
{
|
||||
wsrep_log "[INFO] $*"
|
||||
}
|
||||
|
||||
wsrep_cleanup_progress_file()
|
||||
{
|
||||
[ -n "$SST_PROGRESS_FILE" -a \
|
||||
|
@ -959,6 +986,43 @@ check_sockets_utils()
|
|||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Check if the port is in the "listen" state.
|
||||
# The first parameter is the PID of the process that should
|
||||
# listen on the port - if it is not known, you can specify
|
||||
# an empty string or zero.
|
||||
# The second parameter is the port number.
|
||||
# The third parameter is a list of the names of utilities
|
||||
# (via "|") that can listen on this port during the state
|
||||
# transfer.
|
||||
#
|
||||
check_port()
|
||||
{
|
||||
local pid="$1"
|
||||
local port="$2"
|
||||
local utils="$3"
|
||||
|
||||
[ -z "$pid" ] || [ $pid -eq 0 ] && pid='[0-9]+'
|
||||
|
||||
local rc=1
|
||||
|
||||
if [ $lsof_available -ne 0 ]; then
|
||||
lsof -Pnl -i ":$port" 2>/dev/null | \
|
||||
grep -q -E "^($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*\\(LISTEN\\)" && rc=0
|
||||
elif [ $sockstat_available -ne 0 ]; then
|
||||
sockstat -p "$port" 2>/dev/null | \
|
||||
grep -q -E "[[:space:]]+($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*[[:space:]]LISTEN" && rc=0
|
||||
elif [ $ss_available -ne 0 ]; then
|
||||
ss -nlpH "( sport = :$port )" 2>/dev/null | \
|
||||
grep -q -E "users:\\(.*\\(\"($utils)[^[:space:]]*\"[^)]*,pid=$pid(,[^)]*)?\\)" && rc=0
|
||||
else
|
||||
wsrep_log_error "unknown sockets utility"
|
||||
exit 2 # ENOENT
|
||||
fi
|
||||
|
||||
return $rc
|
||||
}
|
||||
|
||||
#
|
||||
# If the ssl_dhparams variable is already set, uses that as a source
|
||||
# of dh parameters for OpenSSL. Otherwise, looks for dhparams.pem in
|
||||
|
@ -966,28 +1030,95 @@ check_sockets_utils()
|
|||
#
|
||||
check_for_dhparams()
|
||||
{
|
||||
if [ -z "$ssl_dhparams" ]; then
|
||||
ssl_dhparams="$DATA/dhparams.pem"
|
||||
if [ ! -r "$ssl_dhparams" ]; then
|
||||
get_openssl
|
||||
if [ -n "$OPENSSL_BINARY" ]; then
|
||||
wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams"
|
||||
if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error "******** ERROR *****************************************"
|
||||
wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *"
|
||||
wsrep_log_error "********************************************************"
|
||||
ssl_dhparams=""
|
||||
fi
|
||||
else
|
||||
# Rollback: if openssl is not installed, then use
|
||||
# the default parameters:
|
||||
ssl_dhparams="$DATA/dhparams.pem"
|
||||
if [ ! -r "$ssl_dhparams" ]; then
|
||||
get_openssl
|
||||
if [ -n "$OPENSSL_BINARY" ]; then
|
||||
wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams"
|
||||
if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error "******** ERROR *****************************************"
|
||||
wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *"
|
||||
wsrep_log_error "********************************************************"
|
||||
ssl_dhparams=""
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Rollback: if openssl is not installed, then use
|
||||
# the default parameters:
|
||||
ssl_dhparams=""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Verifies that the CA file verifies the certificate.
|
||||
# Doing this here lets us generate better error messages.
|
||||
#
|
||||
# 1st param: path to the CA file.
|
||||
# 2nd param: path to the certificate.
|
||||
#
|
||||
verify_ca_matches_cert()
|
||||
{
|
||||
local ca_path="$1"
|
||||
local cert_path="$2"
|
||||
|
||||
# If the openssl utility is not installed, then
|
||||
# we will not do this certificate check:
|
||||
get_openssl
|
||||
if [ -z "$OPENSSL_BINARY" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if ! "$OPENSSL_BINARY" verify -verbose -CAfile "$ca_path" "$cert_path" >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error "******** FATAL ERROR ********************************************"
|
||||
wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *"
|
||||
wsrep_log_error "* It does not appear that the certificate was issued by the CA. *"
|
||||
wsrep_log_error "* Please check your certificate and CA files. *"
|
||||
wsrep_log_error "*****************************************************************"
|
||||
exit 22
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Verifies that the certificate matches the private key.
|
||||
# Doing this will save us having to wait for a timeout that would
|
||||
# otherwise occur.
|
||||
#
|
||||
# 1st param: path to the certificate.
|
||||
# 2nd param: path to the private key.
|
||||
#
|
||||
verify_cert_matches_key()
|
||||
{
|
||||
local cert_path="$1"
|
||||
local key_path="$2"
|
||||
|
||||
# If the diff utility is not installed, then
|
||||
# we will not do this certificate check:
|
||||
if [ -z "$(command -v diff)" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# If the openssl utility is not installed, then
|
||||
# we will not do this certificate check:
|
||||
get_openssl
|
||||
if [ -z "$OPENSSL_BINARY" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# Generate the public key from the cert and the key.
|
||||
# They should match (otherwise we can't create an SSL connection).
|
||||
if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \
|
||||
<("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error "******************* FATAL ERROR ****************"
|
||||
wsrep_log_error "* The certifcate and private key do not match. *"
|
||||
wsrep_log_error "* Please check your certificate and key files. *"
|
||||
wsrep_log_error "************************************************"
|
||||
exit 22
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Compares two version strings.
|
||||
# The first parameter is the version to be checked;
|
||||
|
@ -996,22 +1127,22 @@ check_for_dhparams()
|
|||
#
|
||||
check_for_version()
|
||||
{
|
||||
y1=${1#*.}
|
||||
y1="${1#*.}"
|
||||
[ "$y1" = "$1" ] && y1=""
|
||||
z1=${y1#*.}
|
||||
[ "$z1" = "$y1" ] && z1=""
|
||||
x1=${1%%.*}
|
||||
y1=${y1%%.*}
|
||||
z1=${z1%%.*}
|
||||
x1="${1%%.*}"
|
||||
y1="${y1%%.*}"
|
||||
z1="${z1%%.*}"
|
||||
[ -z "$y1" ] && y1=0
|
||||
[ -z "$z1" ] && z1=0
|
||||
y2=${2#*.}
|
||||
y2="${2#*.}"
|
||||
[ "$y2" = "$2" ] && y2=""
|
||||
z2=${y2#*.}
|
||||
z2="${y2#*.}"
|
||||
[ "$z2" = "$y2" ] && z2=""
|
||||
x2=${2%%.*}
|
||||
y2=${y2%%.*}
|
||||
z2=${z2%%.*}
|
||||
x2="${2%%.*}"
|
||||
y2="${y2%%.*}"
|
||||
z2="${z2%%.*}"
|
||||
[ -z "$y2" ] && y2=0
|
||||
[ -z "$z2" ] && z2=0
|
||||
[ $x1 -lt $x2 ] && return 1
|
||||
|
@ -1021,3 +1152,127 @@ check_for_version()
|
|||
[ $z1 -lt $z2 ] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
trim_string()
|
||||
{
|
||||
if [ -n "$BASH_VERSION" ]; then
|
||||
local pattern="[![:space:]${2:-}]"
|
||||
local x="${1#*$pattern}"
|
||||
local z=${#1}
|
||||
x=${#x}
|
||||
if [ $x -ne $z ]; then
|
||||
local y="${1%$pattern*}"
|
||||
y=${#y}
|
||||
x=$(( z-x-1 ))
|
||||
y=$(( y-x+1 ))
|
||||
printf '%s' "${1:$x:$y}"
|
||||
else
|
||||
printf ''
|
||||
fi
|
||||
else
|
||||
local pattern="[[:space:]${2:-}]"
|
||||
echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Check whether process is still running.
|
||||
# The first parameter contains the name of the PID file.
|
||||
# The second parameter is the flag of the need to delete
|
||||
# the PID file.
|
||||
# If the second parameter is not zero and not empty,
|
||||
# then if the process terminates, the corresponding
|
||||
# PID file will be deleted.
|
||||
# This function also sets the CHECK_PID variable to zero
|
||||
# if the process has already exited, or writes the PID
|
||||
# of the process there if it is still running.
|
||||
#
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
local remove=${2:-0}
|
||||
if [ -r "$pid_file" ]; then
|
||||
local pid=$(cat "$pid_file" 2>/dev/null)
|
||||
if [ -n "$pid" ]; then
|
||||
if [ $pid -ne 0 ]; then
|
||||
if ps -p "$pid" >/dev/null 2>&1; then
|
||||
CHECK_PID=$pid
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ $remove -eq 1 ]; then
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
fi
|
||||
CHECK_PID=0
|
||||
return 1
|
||||
}
|
||||
|
||||
#
|
||||
# Checking that the process with the specified PID is still
|
||||
# running and killing it in this case by sending SIGTERM
|
||||
# (using the "kill" operation).
|
||||
# The first parameter contains PID of the process.
|
||||
# The second and third parameters (both optional) are the names
|
||||
# of the PID and the configuration files, which should be removed
|
||||
# after the process ends.
|
||||
# If the first parameter (PID of the process) is zero, then
|
||||
# the function immediately deletes the PID and the configuration
|
||||
# files (if specified), without any additional checks.
|
||||
#
|
||||
cleanup_pid()
|
||||
{
|
||||
local pid="$1"
|
||||
local pid_file="${2:-}"
|
||||
local config="${3:-}"
|
||||
|
||||
if [ $pid -ne 0 ]; then
|
||||
if ps -p $pid >/dev/null 2>&1; then
|
||||
if kill $pid >/dev/null 2>&1; then
|
||||
sleep 0.5
|
||||
local round=0
|
||||
local force=0
|
||||
while ps -p $pid >/dev/null 2>&1; do
|
||||
sleep 1
|
||||
round=$(( round+1 ))
|
||||
if [ $round -eq 16 ]; then
|
||||
if [ $force -eq 0 ]; then
|
||||
round=8
|
||||
force=1
|
||||
kill -9 $pid >/dev/null 2>&1
|
||||
else
|
||||
return 1;
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif ps -p $pid >/dev/null 2>&1; then
|
||||
wsrep_log_warning "Unable to kill PID=$pid ($pid_file)"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -n "$pid_file" ] && [ -f "$pid_file" ] && rm -f "$pid_file"
|
||||
[ -n "$config" ] && [ -f "$config" ] && rm -f "$config"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
nproc=""
|
||||
|
||||
get_proc()
|
||||
{
|
||||
if [ -z "$nproc" ]; then
|
||||
set +e
|
||||
if [ "$OS" = 'Linux' ]; then
|
||||
nproc=$(grep -c processor /proc/cpuinfo 2>/dev/null)
|
||||
elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then
|
||||
nproc=$(sysctl -n hw.ncpu)
|
||||
fi
|
||||
if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then
|
||||
nproc=1
|
||||
fi
|
||||
set -e
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -29,13 +29,10 @@ eformat=""
|
|||
ekey=""
|
||||
ekeyfile=""
|
||||
encrypt=0
|
||||
nproc=1
|
||||
ecode=0
|
||||
ssyslog=""
|
||||
ssystag=""
|
||||
MARIABACKUP_PID=""
|
||||
SST_PORT=""
|
||||
REMOTEIP=""
|
||||
BACKUP_PID=""
|
||||
tcert=""
|
||||
tpem=""
|
||||
tkey=""
|
||||
|
@ -55,7 +52,7 @@ ib_home_dir=""
|
|||
ib_log_dir=""
|
||||
ib_undo_dir=""
|
||||
|
||||
sfmt="tar"
|
||||
sfmt=""
|
||||
strmcmd=""
|
||||
tfmt=""
|
||||
tcmd=""
|
||||
|
@ -79,6 +76,11 @@ compress='none'
|
|||
compress_chunk=""
|
||||
compress_threads=""
|
||||
|
||||
backup_threads=""
|
||||
|
||||
encrypt_threads=""
|
||||
encrypt_chunk=""
|
||||
|
||||
readonly SECRET_TAG="secret"
|
||||
|
||||
# Required for backup locks
|
||||
|
@ -92,12 +94,11 @@ fi
|
|||
pcmd="pv $pvopts"
|
||||
declare -a RC
|
||||
|
||||
MARIABACKUP_BIN="$(command -v mariabackup)"
|
||||
if [ ! -x "$MARIABACKUP_BIN" ]; then
|
||||
wsrep_log_error 'mariabackup binary not found in $PATH'
|
||||
BACKUP_BIN="$(command -v mariabackup)"
|
||||
if [ ! -x "$BACKUP_BIN" ]; then
|
||||
wsrep_log_error 'mariabackup binary not found in path'
|
||||
exit 42
|
||||
fi
|
||||
MBSTREAM_BIN=mbstream
|
||||
|
||||
DATA="$WSREP_SST_OPT_DATA"
|
||||
INFO_FILE="xtrabackup_galera_info"
|
||||
|
@ -111,7 +112,8 @@ INNOBACKUPLOG="$DATA/mariabackup.backup.log"
|
|||
# Setting the path for ss and ip
|
||||
export PATH="/usr/sbin:/sbin:$PATH"
|
||||
|
||||
timeit(){
|
||||
timeit()
|
||||
{
|
||||
local stage="$1"
|
||||
shift
|
||||
local cmd="$@"
|
||||
|
@ -201,6 +203,12 @@ get_keys()
|
|||
else
|
||||
ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'"
|
||||
fi
|
||||
if [ -n "$encrypt_threads" ]; then
|
||||
ecmd="$ecmd --encrypt-threads=$encrypt_threads"
|
||||
fi
|
||||
if [ -n "$encrypt_chunk" ]; then
|
||||
ecmd="$ecmd --encrypt-chunk-size=$encrypt_chunk"
|
||||
fi
|
||||
else
|
||||
wsrep_log_error "Unknown encryption format='$eformat'"
|
||||
exit 2
|
||||
|
@ -215,8 +223,6 @@ get_keys()
|
|||
|
||||
get_transfer()
|
||||
{
|
||||
TSST_PORT="$SST_PORT"
|
||||
|
||||
if [ $tfmt = 'nc' ]; then
|
||||
wsrep_log_info "Using netcat as streamer"
|
||||
wsrep_check_programs nc
|
||||
|
@ -238,7 +244,7 @@ get_transfer()
|
|||
wsrep_log_info "Using traditional netcat as streamer"
|
||||
tcmd="$tcmd -l -p"
|
||||
fi
|
||||
tcmd="$tcmd $TSST_PORT"
|
||||
tcmd="$tcmd $SST_PORT"
|
||||
else
|
||||
# Check to see if netcat supports the '-N' flag.
|
||||
# -N Shutdown the network socket after EOF on stdin
|
||||
|
@ -260,7 +266,7 @@ get_transfer()
|
|||
wsrep_log_info "Using traditional netcat as streamer"
|
||||
tcmd="$tcmd -q0"
|
||||
fi
|
||||
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
|
||||
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT"
|
||||
fi
|
||||
else
|
||||
tfmt='socat'
|
||||
|
@ -268,25 +274,68 @@ get_transfer()
|
|||
wsrep_log_info "Using socat as streamer"
|
||||
wsrep_check_programs socat
|
||||
|
||||
if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
|
||||
wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)"
|
||||
if [ -n "$sockopt" ]; then
|
||||
sockopt=$(trim_string "$sockopt" ',')
|
||||
if [ -n "$sockopt" ]; then
|
||||
sockopt=",$sockopt"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add an option for ipv6 if needed:
|
||||
if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
|
||||
# If sockopt contains 'pf=ip6' somewhere in the middle,
|
||||
# this will not interfere with socat, but exclude the trivial
|
||||
# cases when sockopt contains 'pf=ip6' as prefix or suffix:
|
||||
if [ "$sockopt" = "${sockopt#,pf=ip6}" -a \
|
||||
"$sockopt" = "${sockopt%,pf=ip6}" ]
|
||||
then
|
||||
sockopt=",pf=ip6$sockopt"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $encrypt -lt 2 ]; then
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
tcmd="socat -u TCP-LISTEN:$SST_PORT,reuseaddr$sockopt stdio"
|
||||
else
|
||||
tcmd="socat -u stdio TCP:$REMOTEIP:$SST_PORT$sockopt"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
|
||||
wsrep_log_error "******** FATAL ERROR ************************************************ "
|
||||
wsrep_log_error "* Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt) *"
|
||||
wsrep_log_error "********************************************************************* "
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Determine the socat version
|
||||
SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
|
||||
if [ -z "$SOCAT_VERSION" ]; then
|
||||
wsrep_log_error "******** FATAL ERROR ******************"
|
||||
wsrep_log_error "* Cannot determine the socat version. *"
|
||||
wsrep_log_error "***************************************"
|
||||
exit 2
|
||||
local action='Decrypting'
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
|
||||
else
|
||||
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$SST_PORT"
|
||||
action='Encrypting'
|
||||
fi
|
||||
|
||||
if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then
|
||||
# socat versions < 1.7.3 will have 512-bit dhparams (too small)
|
||||
# so create 2048-bit dhparams and send that as a parameter:
|
||||
check_for_dhparams
|
||||
sockopt=",dhparam='$ssl_dhparams'$sockopt"
|
||||
if [ "${sockopt#*,dhparam=}" != "$sockopt" ]; then
|
||||
if [ -z "$ssl_dhparams" ]; then
|
||||
# Determine the socat version
|
||||
SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
|
||||
if [ -z "$SOCAT_VERSION" ]; then
|
||||
wsrep_log_error "******** FATAL ERROR ******************"
|
||||
wsrep_log_error "* Cannot determine the socat version. *"
|
||||
wsrep_log_error "***************************************"
|
||||
exit 2
|
||||
fi
|
||||
if ! check_for_version "$SOCAT_VERSION" '1.7.3'; then
|
||||
# socat versions < 1.7.3 will have 512-bit dhparams (too small)
|
||||
# so create 2048-bit dhparams and send that as a parameter:
|
||||
check_for_dhparams
|
||||
fi
|
||||
fi
|
||||
if [ -n "$ssl_dhparams" ]; then
|
||||
tcmd="$tcmd,dhparam='$ssl_dhparams'"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $encrypt -eq 2 ]; then
|
||||
|
@ -295,52 +344,60 @@ get_transfer()
|
|||
wsrep_log_error "Both PEM and CRT files required"
|
||||
exit 22
|
||||
fi
|
||||
stagemsg="$stagemsg-OpenSSL-Encrypted-2"
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}"
|
||||
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}"
|
||||
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',cafile='$tcert'$sockopt"
|
||||
if [ ! -r "$tpem" -o ! -r "$tcert" ]; then
|
||||
wsrep_log_error "Both PEM and CRT files must be readable"
|
||||
exit 22
|
||||
fi
|
||||
elif [ $encrypt -eq 3 ]; then
|
||||
verify_ca_matches_cert "$tcert" "$tpem"
|
||||
tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt"
|
||||
stagemsg="$stagemsg-OpenSSL-Encrypted-2"
|
||||
wsrep_log_info "$action with cert=$tpem, cafile=$tcert"
|
||||
elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then
|
||||
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
|
||||
if [ -z "$tpem" -o -z "$tkey" ]; then
|
||||
wsrep_log_error "Both certificate and key files required"
|
||||
exit 22
|
||||
fi
|
||||
if [ ! -r "$tpem" -o ! -r "$tkey" ]; then
|
||||
wsrep_log_error "Both certificate and key files must be readable"
|
||||
exit 22
|
||||
fi
|
||||
verify_cert_matches_key "$tpem" "$tkey"
|
||||
stagemsg="$stagemsg-OpenSSL-Encrypted-3"
|
||||
if [ -z "$tcert" ]; then
|
||||
# no verification
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0"
|
||||
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',verify=0$sockopt stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0"
|
||||
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',verify=0$sockopt"
|
||||
if [ $encrypt -eq 4 ]; then
|
||||
wsrep_log_error "Peer certificate required if encrypt=4"
|
||||
exit 22
|
||||
fi
|
||||
# no verification
|
||||
tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt"
|
||||
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
|
||||
else
|
||||
# CA verification
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
|
||||
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',cafile='$tcert'$sockopt stdio"
|
||||
else
|
||||
CN_option=""
|
||||
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
|
||||
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
|
||||
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
|
||||
CN_option=',commonname=localhost'
|
||||
fi
|
||||
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
|
||||
tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
|
||||
if [ ! -r "$tcert" ]; then
|
||||
wsrep_log_error "Certificate file must be readable"
|
||||
exit 22
|
||||
fi
|
||||
verify_ca_matches_cert "$tcert" "$tpem"
|
||||
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
|
||||
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
|
||||
elif [ $encrypt -eq 4 ]; then
|
||||
CN_option=",commonname=''"
|
||||
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
|
||||
CN_option=',commonname=localhost'
|
||||
else
|
||||
CN_option=",commonname='$WSREP_SST_OPT_HOST_UNSECAPED'"
|
||||
fi
|
||||
tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
|
||||
wsrep_log_info "$action with cert=$tpem, key=$tkey, cafile=$tcert"
|
||||
fi
|
||||
else
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
tcmd="socat -u TCP-LISTEN:$TSST_PORT,reuseaddr$sockopt stdio"
|
||||
else
|
||||
tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt"
|
||||
fi
|
||||
wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
tcmd="$tcmd stdio"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
@ -348,7 +405,7 @@ get_transfer()
|
|||
get_footprint()
|
||||
{
|
||||
pushd "$WSREP_SST_OPT_DATA" 1>/dev/null
|
||||
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }')
|
||||
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
|
||||
if [ "$compress" != 'none' ]; then
|
||||
# QuickLZ has around 50% compression ratio
|
||||
# When compression/compaction used, the progress is only an approximate.
|
||||
|
@ -412,10 +469,10 @@ read_cnf()
|
|||
tpem=$(parse_cnf 'sst' 'tcert')
|
||||
tkey=$(parse_cnf 'sst' 'tkey')
|
||||
fi
|
||||
if [ "$tmode" != 'DISABLED' ]
|
||||
then # backward-incompatible behavior
|
||||
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
|
||||
then # no old-style SSL config in [sst]
|
||||
if [ "$tmode" != 'DISABLED' ]; then
|
||||
# backward-incompatible behavior
|
||||
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]; then
|
||||
# no old-style SSL config in [sst]
|
||||
check_server_ssl_config
|
||||
fi
|
||||
if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ]
|
||||
|
@ -441,7 +498,7 @@ read_cnf()
|
|||
sockopt=$(parse_cnf sst sockopt "")
|
||||
progress=$(parse_cnf sst progress "")
|
||||
ttime=$(parse_cnf sst time 0)
|
||||
cpat='.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
|
||||
cpat='.*\.pem$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
|
||||
[ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g')
|
||||
cpat=$(parse_cnf sst cpat "$cpat")
|
||||
scomp=$(parse_cnf sst compressor "")
|
||||
|
@ -476,34 +533,38 @@ read_cnf()
|
|||
compress_threads=$(parse_cnf "$encgroups" 'compress-threads')
|
||||
fi
|
||||
fi
|
||||
|
||||
backup_threads=$(parse_cnf "$encgroups" 'backup-threads')
|
||||
|
||||
if [ "$eformat" = 'xbcrypt' ]; then
|
||||
encrypt_threads=$(parse_cnf "$encgroups" 'encrypt-threads')
|
||||
encrypt_chunk=$(parse_cnf "$encgroups" 'encrypt-chunk-size')
|
||||
fi
|
||||
}
|
||||
|
||||
get_stream()
|
||||
{
|
||||
if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then
|
||||
wsrep_log_info "Streaming with ${sfmt}"
|
||||
sfmt='mbstream'
|
||||
STREAM_BIN="$(command -v mbstream)"
|
||||
if [ -z "$STREAM_BIN" ]; then
|
||||
wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path"
|
||||
exit 42
|
||||
fi
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
strmcmd="$MBSTREAM_BIN -x"
|
||||
strmcmd="'$STREAM_BIN' -x"
|
||||
else
|
||||
strmcmd="$MBSTREAM_BIN -c '$INFO_FILE'"
|
||||
strmcmd="'$STREAM_BIN' -c '$INFO_FILE'"
|
||||
fi
|
||||
else
|
||||
sfmt="tar"
|
||||
wsrep_log_info "Streaming with tar"
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]]; then
|
||||
strmcmd="tar xfi -"
|
||||
sfmt='tar'
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
strmcmd='tar xfi -'
|
||||
else
|
||||
strmcmd="tar cf - '$INFO_FILE'"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
get_proc()
|
||||
{
|
||||
set +e
|
||||
nproc=$(grep -c processor /proc/cpuinfo)
|
||||
[ -z $nproc -o $nproc -eq 0 ] && nproc=1
|
||||
set -e
|
||||
wsrep_log_info "Streaming with $sfmt"
|
||||
}
|
||||
|
||||
sig_joiner_cleanup()
|
||||
|
@ -512,65 +573,27 @@ sig_joiner_cleanup()
|
|||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
}
|
||||
|
||||
cleanup_joiner()
|
||||
cleanup_at_exit()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
local estatus=$?
|
||||
if [ $estatus -ne 0 ]; then
|
||||
wsrep_log_error "Cleanup after exit with status:$estatus"
|
||||
elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
fi
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_log_info "Removing the sst_in_progress file"
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
if [ -n "$progress" -a -p "$progress" ]; then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm "$progress"
|
||||
fi
|
||||
|
||||
if [ -n "$STATDIR" ]; then
|
||||
[ -d "$STATDIR" ] && rm -rf "$STATDIR"
|
||||
fi
|
||||
|
||||
# Final cleanup
|
||||
pgid=$(ps -o pgid= $$ | grep -o '[0-9]*')
|
||||
|
||||
# This means no setsid done in mysqld.
|
||||
# We don't want to kill mysqld here otherwise.
|
||||
if [ $$ -eq $pgid ]; then
|
||||
# This means a signal was delivered to the process.
|
||||
# So, more cleanup.
|
||||
if [ $estatus -ge 128 ]; then
|
||||
kill -KILL -$$ || true
|
||||
else
|
||||
if [ -n "$BACKUP_PID" ]; then
|
||||
if check_pid "$BACKUP_PID" 1; then
|
||||
wsrep_log_error "mariabackup process is still running. Killing..."
|
||||
cleanup_pid $CHECK_PID "$BACKUP_PID"
|
||||
fi
|
||||
fi
|
||||
[ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
|
||||
fi
|
||||
|
||||
exit $estatus
|
||||
}
|
||||
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
|
||||
}
|
||||
|
||||
cleanup_donor()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
local estatus=$?
|
||||
if [ $estatus -ne 0 ]; then
|
||||
wsrep_log_error "Cleanup after exit with status:$estatus"
|
||||
fi
|
||||
|
||||
if [ -n "$MARIABACKUP_PID" ]; then
|
||||
if check_pid $MARIABACKUP_PID
|
||||
then
|
||||
wsrep_log_error "mariabackup process is still running. Killing..."
|
||||
kill_mariabackup
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
|
||||
|
||||
if [ -n "$progress" -a -p "$progress" ]; then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm -f "$progress" || true
|
||||
|
@ -578,8 +601,14 @@ cleanup_donor()
|
|||
|
||||
wsrep_log_info "Cleaning up temporary directories"
|
||||
|
||||
[ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true
|
||||
[ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
if [ -n "$STATDIR" ]; then
|
||||
[ -d "$STATDIR" ] && rm -rf "$STATDIR"
|
||||
fi
|
||||
else
|
||||
[ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true
|
||||
[ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true
|
||||
fi
|
||||
|
||||
# Final cleanup
|
||||
pgid=$(ps -o pgid= $$ | grep -o '[0-9]*')
|
||||
|
@ -590,21 +619,13 @@ cleanup_donor()
|
|||
# This means a signal was delivered to the process.
|
||||
# So, more cleanup.
|
||||
if [ $estatus -ge 128 ]; then
|
||||
kill -KILL -$$ || true
|
||||
kill -KILL -- -$$ || true
|
||||
fi
|
||||
fi
|
||||
|
||||
exit $estatus
|
||||
}
|
||||
|
||||
kill_mariabackup()
|
||||
{
|
||||
local PID=$(cat "$MARIABACKUP_PID")
|
||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
wsrep_log_info "Removing mariabackup pid file ($MARIABACKUP_PID)"
|
||||
rm -f "$MARIABACKUP_PID" || true
|
||||
}
|
||||
|
||||
setup_ports()
|
||||
{
|
||||
SST_PORT="$WSREP_SST_OPT_PORT"
|
||||
|
@ -615,51 +636,17 @@ setup_ports()
|
|||
fi
|
||||
}
|
||||
|
||||
check_port()
|
||||
{
|
||||
local PORT="$1"
|
||||
local UTILS="$2"
|
||||
|
||||
local port_info is_util
|
||||
|
||||
if [ $lsof_available -ne 0 ]; then
|
||||
port_info=$(lsof -i ":$PORT" -Pn 2>/dev/null | \
|
||||
grep -F '(LISTEN)')
|
||||
is_util=$(echo "$port_info" | \
|
||||
grep -E "^($UTILS)[^[:space:]]*[[:space:]]+[0-9]+[[:space:]]+")
|
||||
elif [ $sockstat_available -ne 0 ]; then
|
||||
port_info=$(sockstat -p "$PORT" 2>/dev/null | \
|
||||
grep -F 'LISTEN')
|
||||
is_util=$(echo "$port_info" | \
|
||||
grep -E "[[:space:]]+($UTILS)[^[:space:]]*[[:space:]]+[0-9]+[[:space:]]+")
|
||||
elif [ $ss_available -ne 0 ]; then
|
||||
port_info=$(ss -H -p -n -l "( sport = :$PORT )" 2>/dev/null)
|
||||
is_util=$(echo "$port_info" | \
|
||||
grep -E "users:\\(.*\\(\"($UTILS)[^[:space:]]*\".*\<pid=[0-9]+\>.*\\)")
|
||||
else
|
||||
wsrep_log_error "unknown sockets utility"
|
||||
exit 2 # ENOENT
|
||||
fi
|
||||
|
||||
if [ -z "$is_util" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
#
|
||||
# Waits ~30 seconds for socat or nc to open the port and
|
||||
# then reports ready, regardless of timeout.
|
||||
#
|
||||
wait_for_listen()
|
||||
{
|
||||
local PORT="$1"
|
||||
local ADDR="$2"
|
||||
local MODULE="$3"
|
||||
|
||||
for i in {1..50}
|
||||
do
|
||||
if check_port "$PORT" 'socat|nc'
|
||||
then
|
||||
for i in {1..150}; do
|
||||
if check_port "" "$PORT" 'socat|nc'; then
|
||||
break
|
||||
fi
|
||||
sleep 0.2
|
||||
|
@ -675,8 +662,8 @@ check_extra()
|
|||
if [ "$thread_handling" = 'pool-of-threads' ]; then
|
||||
local eport=$(parse_cnf '--mysqld' 'extra-port')
|
||||
if [ -n "$eport" ]; then
|
||||
# mariabackup works only locally, hence,
|
||||
# setting host to 127.0.0.1 unconditionally:
|
||||
# mariabackup works only locally.
|
||||
# Hence, setting host to 127.0.0.1 unconditionally:
|
||||
wsrep_log_info "SST through extra_port $eport"
|
||||
INNOEXTRA="$INNOEXTRA --host=127.0.0.1 --port=$eport"
|
||||
use_socket=0
|
||||
|
@ -792,30 +779,29 @@ monitor_process()
|
|||
local sst_stream_pid=$1
|
||||
|
||||
while true ; do
|
||||
if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null; then
|
||||
if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1; then
|
||||
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
|
||||
kill -- -"$WSREP_SST_OPT_PARENT"
|
||||
exit 32
|
||||
fi
|
||||
if ! ps -p "$sst_stream_pid" &>/dev/null; then
|
||||
if ! ps -p "$sst_stream_pid" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
|
||||
wsrep_check_programs "$MARIABACKUP_BIN"
|
||||
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then
|
||||
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
||||
wsrep_log_error "Invalid role '$WSREP_SST_OPT_ROLE'"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
read_cnf
|
||||
setup_ports
|
||||
|
||||
if "$MARIABACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then
|
||||
if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then
|
||||
disver='--no-version-check'
|
||||
fi
|
||||
|
||||
|
@ -838,7 +824,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P)
|
|||
cd "$OLD_PWD"
|
||||
|
||||
if [ $ssyslog -eq 1 ]; then
|
||||
|
||||
if [ -n "$(command -v logger)" ]; then
|
||||
wsrep_log_info "Logging all stderr of SST/mariabackup to syslog"
|
||||
|
||||
|
@ -856,70 +841,65 @@ if [ $ssyslog -eq 1 ]; then
|
|||
else
|
||||
wsrep_log_error "logger not in path: $PATH. Ignoring"
|
||||
fi
|
||||
|
||||
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply"
|
||||
INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move"
|
||||
INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
|
||||
|
||||
else
|
||||
|
||||
if [ $sstlogarchive -eq 1 ]
|
||||
then
|
||||
ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
|
||||
|
||||
if [ -n "$sstlogarchivedir" ]; then
|
||||
if [ ! -d "$sstlogarchivedir" ]; then
|
||||
mkdir -p "$sstlogarchivedir"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -e "$INNOAPPLYLOG" ]
|
||||
if [ $sstlogarchive -eq 1 ]
|
||||
then
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
then
|
||||
newfile=$(basename "$INNOAPPLYLOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
|
||||
mv "$INNOAPPLYLOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
|
||||
|
||||
if [ -e "$INNOMOVELOG" ]
|
||||
then
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
then
|
||||
newfile=$(basename "$INNOMOVELOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
|
||||
if [ -n "$sstlogarchivedir" ]; then
|
||||
if [ ! -d "$sstlogarchivedir" ]; then
|
||||
mkdir -p "$sstlogarchivedir"
|
||||
fi
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
|
||||
mv "$INNOMOVELOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
|
||||
if [ -e "$INNOBACKUPLOG" ]
|
||||
then
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
if [ -e "$INNOAPPLYLOG" ]
|
||||
then
|
||||
newfile=$(basename "$INNOBACKUPLOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
then
|
||||
newfile=$(basename "$INNOAPPLYLOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
|
||||
mv "$INNOAPPLYLOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
|
||||
mv "$INNOBACKUPLOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
fi
|
||||
|
||||
INNOAPPLY="&> '$INNOAPPLYLOG'"
|
||||
INNOMOVE="&> '$INNOMOVELOG'"
|
||||
if [ -e "$INNOMOVELOG" ]
|
||||
then
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
then
|
||||
newfile=$(basename "$INNOMOVELOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
|
||||
mv "$INNOMOVELOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
|
||||
if [ -e "$INNOBACKUPLOG" ]
|
||||
then
|
||||
if [ -n "$sstlogarchivedir" ]
|
||||
then
|
||||
newfile=$(basename "$INNOBACKUPLOG")
|
||||
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
|
||||
else
|
||||
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
|
||||
fi
|
||||
wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
|
||||
mv "$INNOBACKUPLOG" "$newfile"
|
||||
gzip "$newfile"
|
||||
fi
|
||||
fi
|
||||
INNOAPPLY="> '$INNOAPPLYLOG' 2>&1"
|
||||
INNOMOVE="> '$INNOMOVELOG' 2>&1"
|
||||
INNOBACKUP="2> '$INNOBACKUPLOG'"
|
||||
|
||||
fi
|
||||
|
||||
setup_commands()
|
||||
|
@ -928,9 +908,9 @@ setup_commands()
|
|||
if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then
|
||||
mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD"
|
||||
fi
|
||||
INNOAPPLY="$MARIABACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY"
|
||||
INNOMOVE="$MARIABACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE"
|
||||
INNOBACKUP="$MARIABACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream='$sfmt' --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP"
|
||||
INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY"
|
||||
INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE"
|
||||
INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP"
|
||||
}
|
||||
|
||||
get_stream
|
||||
|
@ -938,7 +918,7 @@ get_transfer
|
|||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
|
||||
then
|
||||
trap cleanup_donor EXIT
|
||||
trap cleanup_at_exit EXIT
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
then
|
||||
|
@ -951,12 +931,15 @@ then
|
|||
tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
|
||||
if [ -z "$tmpdir" ]; then
|
||||
xtmpdir="$(mktemp -d)"
|
||||
tmpopts="--tmpdir='$xtmpdir'"
|
||||
wsrep_log_info "Using $xtmpdir as mariabackup temporary directory"
|
||||
else
|
||||
xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
|
||||
fi
|
||||
|
||||
wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
|
||||
tmpopts="--tmpdir='$xtmpdir'"
|
||||
|
||||
itmpdir="$(mktemp -d)"
|
||||
wsrep_log_info "Using $itmpdir as mariabackup temporary directory"
|
||||
wsrep_log_info "Using '$itmpdir' as mariabackup working directory"
|
||||
|
||||
usrst=0
|
||||
if [ -n "$WSREP_SST_OPT_USER" ]; then
|
||||
|
@ -997,9 +980,9 @@ then
|
|||
|
||||
send_donor "$DATA" "$stagemsg-gtid"
|
||||
|
||||
# Restore the transport commmand to its original state
|
||||
tcmd="$ttcmd"
|
||||
|
||||
# Restore the transport commmand to its original state
|
||||
if [ -n "$progress" ]; then
|
||||
get_footprint
|
||||
tcmd="$pcmd | $tcmd"
|
||||
|
@ -1011,7 +994,7 @@ then
|
|||
wsrep_log_info "Sleeping before data transfer for SST"
|
||||
sleep 10
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP}:${SST_PORT}"
|
||||
wsrep_log_info "Streaming the backup to joiner at $REMOTEIP:$SST_PORT"
|
||||
|
||||
# Add compression to the head of the stream (if specified)
|
||||
if [ -n "$scomp" ]; then
|
||||
|
@ -1023,33 +1006,37 @@ then
|
|||
tcmd="$ecmd | $tcmd"
|
||||
fi
|
||||
|
||||
iopts="$iopts --databases-exclude='lost+found'"
|
||||
iopts="--databases-exclude='lost+found' $iopts"
|
||||
|
||||
if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
|
||||
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
|
||||
iopts="$iopts --no-backup-locks"
|
||||
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
|
||||
iopts="--no-backup-locks $iopts"
|
||||
fi
|
||||
|
||||
# if compression is enabled for backup files, then add the
|
||||
# appropriate options to the mariabackup command line:
|
||||
if [ "$compress" != 'none' ]; then
|
||||
iopts="$iopts --compress${compress:+=$compress}"
|
||||
iopts="--compress${compress:+=$compress} $iopts"
|
||||
if [ -n "$compress_threads" ]; then
|
||||
iopts="$iopts --compress-threads=$compress_threads"
|
||||
iopts="--compress-threads=$compress_threads $iopts"
|
||||
fi
|
||||
if [ -n "$compress_chunk" ]; then
|
||||
iopts="$iopts --compress-chunk-size=$compress_chunk"
|
||||
iopts="--compress-chunk-size=$compress_chunk $iopts"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$backup_threads" ]; then
|
||||
iopts="--parallel=$backup_threads $iopts"
|
||||
fi
|
||||
|
||||
setup_commands
|
||||
set +e
|
||||
timeit "$stagemsg-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
|
||||
if [ ${RC[0]} -ne 0 ]; then
|
||||
wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \
|
||||
"Check syslog or ${INNOBACKUPLOG} for details"
|
||||
wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \
|
||||
"Check syslog or '$INNOBACKUPLOG' for details"
|
||||
exit 22
|
||||
elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then
|
||||
wsrep_log_error "$tcmd finished with error: ${RC[1]}"
|
||||
|
@ -1057,7 +1044,7 @@ then
|
|||
fi
|
||||
|
||||
# mariabackup implicitly writes PID to fixed location in $xtmpdir
|
||||
MARIABACKUP_PID="$xtmpdir/xtrabackup_pid"
|
||||
BACKUP_PID="$xtmpdir/xtrabackup_pid"
|
||||
|
||||
else # BYPASS FOR IST
|
||||
|
||||
|
@ -1109,6 +1096,10 @@ then
|
|||
|
||||
ib_undo_dir="$INNODB_UNDO_DIR"
|
||||
|
||||
if [ -n "$backup_threads" ]; then
|
||||
impts="--parallel=$backup_threads $impts"
|
||||
fi
|
||||
|
||||
stagemsg='Joiner-Recv'
|
||||
|
||||
sencrypted=1
|
||||
|
@ -1148,7 +1139,7 @@ then
|
|||
fi
|
||||
|
||||
trap sig_joiner_cleanup HUP PIPE INT TERM
|
||||
trap cleanup_joiner EXIT
|
||||
trap cleanup_at_exit EXIT
|
||||
|
||||
if [ -n "$progress" ]; then
|
||||
adjust_progress
|
||||
|
@ -1171,7 +1162,7 @@ then
|
|||
|
||||
recv_joiner "$STATDIR" "$stagemsg-gtid" $stimeout 1 1
|
||||
|
||||
if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null
|
||||
if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
|
||||
exit 32
|
||||
|
@ -1181,7 +1172,7 @@ then
|
|||
then
|
||||
|
||||
if [ -d "$DATA/.sst" ]; then
|
||||
wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous state transfer. Removing"
|
||||
wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing"
|
||||
rm -rf "$DATA/.sst"
|
||||
fi
|
||||
mkdir -p "$DATA/.sst"
|
||||
|
@ -1291,37 +1282,37 @@ then
|
|||
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
wsrep_log_info "Preparing the backup at $DATA"
|
||||
setup_commands
|
||||
timeit "mariabackup prepare stage" "$INNOAPPLY"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details"
|
||||
wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
MAGIC_FILE="$TDATA/$INFO_FILE"
|
||||
wsrep_log_info "Moving the backup to ${TDATA}"
|
||||
timeit "mariabackup move stage" "$INNOMOVE"
|
||||
|
||||
wsrep_log_info "Moving the backup to $TDATA"
|
||||
timeit "mariabackup move stage" "$INNOMOVE"
|
||||
if [ $? -eq 0 ]; then
|
||||
wsrep_log_info "Move successful, removing ${DATA}"
|
||||
wsrep_log_info "Move successful, removing $DATA"
|
||||
rm -rf "$DATA"
|
||||
DATA="$TDATA"
|
||||
else
|
||||
wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis"
|
||||
wsrep_log_error "Check syslog or ${INNOMOVELOG} for details"
|
||||
wsrep_log_error "Move failed, keeping '$DATA' for further diagnosis"
|
||||
wsrep_log_error "Check syslog or '$INNOMOVELOG' for details"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
wsrep_log_info "${IST_FILE} received from donor: Running IST"
|
||||
wsrep_log_info "'$IST_FILE' received from donor: Running IST"
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -r "$MAGIC_FILE" ]; then
|
||||
wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
|
||||
wsrep_log_error "SST magic file '$MAGIC_FILE' not found/readable"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ then
|
|||
DROP PREPARE stmt;"
|
||||
fi
|
||||
|
||||
MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\
|
||||
MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\
|
||||
"$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\
|
||||
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
|
||||
|
||||
|
@ -140,7 +140,7 @@ then
|
|||
fi
|
||||
|
||||
# NOTE: we don't use --routines here because we're dumping mysql.proc table
|
||||
MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF $AUTH -S$WSREP_SST_OPT_SOCKET \
|
||||
MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \
|
||||
--add-drop-database --add-drop-table --skip-add-locks --create-options \
|
||||
--disable-keys --extended-insert --skip-lock-tables --quick --set-charset \
|
||||
--skip-comments --flush-privileges --all-databases --events"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash -ue
|
||||
|
||||
# Copyright (C) 2010-2014 Codership Oy
|
||||
# Copyright (C) 2017-2021 MariaDB
|
||||
# Copyright (C) 2010-2014 Codership Oy
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,9 +19,8 @@
|
|||
|
||||
# This is a reference script for rsync-based state snapshot tansfer
|
||||
|
||||
RSYNC_PID= # rsync pid file
|
||||
RSYNC_CONF= # rsync configuration file
|
||||
RSYNC_REAL_PID= # rsync process id
|
||||
RSYNC_REAL_PID=0 # rsync process id
|
||||
STUNNEL_REAL_PID=0 # stunnel process id
|
||||
|
||||
OS="$(uname)"
|
||||
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
|
||||
|
@ -36,95 +35,95 @@ wsrep_check_programs rsync
|
|||
|
||||
cleanup_joiner()
|
||||
{
|
||||
wsrep_log_info "Joiner cleanup. rsync PID: $RSYNC_REAL_PID"
|
||||
[ "0" != "$RSYNC_REAL_PID" ] && \
|
||||
kill $RSYNC_REAL_PID && \
|
||||
sleep 0.5 && \
|
||||
kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || :
|
||||
[ -f "$RSYNC_CONF" ] && rm -f "$RSYNC_CONF"
|
||||
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
|
||||
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
[ -f "$RSYNC_PID" ] && rm -f "$RSYNC_PID"
|
||||
local failure=0
|
||||
|
||||
wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID"
|
||||
|
||||
if [ -n "$STUNNEL" ]; then
|
||||
if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then
|
||||
if [ $RSYNC_REAL_PID -eq 0 ]; then
|
||||
if [ -r "$RSYNC_PID" ]; then
|
||||
RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null)
|
||||
if [ -z "$RSYNC_REAL_PID" ]; then
|
||||
RSYNC_REAL_PID=0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
wsrep_log_warning "stunnel cleanup failed."
|
||||
failure=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $failure -eq 0 ]; then
|
||||
if cleanup_pid $RSYNC_REAL_PID "$RSYNC_PID" "$RSYNC_CONF"; then
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
else
|
||||
wsrep_log_warning "rsync cleanup failed."
|
||||
fi
|
||||
fi
|
||||
|
||||
wsrep_log_info "Joiner cleanup done."
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
}
|
||||
|
||||
# Check whether rsync process is still running.
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
|
||||
}
|
||||
|
||||
check_pid_and_port()
|
||||
{
|
||||
local pid_file="$1"
|
||||
local rsync_pid=$2
|
||||
local rsync_addr="$3"
|
||||
local rsync_port="$4"
|
||||
local pid=$2
|
||||
local addr="$3"
|
||||
local port="$4"
|
||||
|
||||
if [ -z "$rsync_port" -o -z "$rsync_addr" -o -z "$rsync_pid" ]; then
|
||||
wsrep_log_error "check_pid_and_port(): bad arguments"
|
||||
exit 2 # ENOENT
|
||||
fi
|
||||
local utils='rsync|stunnel'
|
||||
|
||||
local port_info is_rsync
|
||||
if ! check_port "$pid" "$port" "$utils"; then
|
||||
local port_info
|
||||
local busy=0
|
||||
|
||||
if [ $lsof_available -ne 0 ]; then
|
||||
port_info=$(lsof -i ":$rsync_port" -Pn 2>/dev/null | \
|
||||
grep -F '(LISTEN)')
|
||||
is_rsync=$(echo "$port_info" | \
|
||||
grep -E "^(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+")
|
||||
elif [ $sockstat_available -ne 0 ]; then
|
||||
port_info=$(sockstat -p "$rsync_port" 2>/dev/null | \
|
||||
grep -F 'LISTEN')
|
||||
is_rsync=$(echo "$port_info" | \
|
||||
grep -E "[[:space:]]+(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+")
|
||||
elif [ $ss_available -ne 0 ]; then
|
||||
port_info=$(ss -H -p -n -l "( sport = :$rsync_port )" 2>/dev/null)
|
||||
is_rsync=$(echo "$port_info" | \
|
||||
grep -E "users:\\(.*\\(\"(rsync|stunnel)[^[:space:]]*\".*\<pid=$rsync_pid\>.*\\)")
|
||||
else
|
||||
wsrep_log_error "unknown sockets utility"
|
||||
exit 2 # ENOENT
|
||||
fi
|
||||
|
||||
if [ -z "$is_rsync" ]; then
|
||||
local is_listening_all
|
||||
if [ $lsof_available -ne 0 ]; then
|
||||
is_listening_all=$(echo "$port_info" | \
|
||||
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port[[:space:]]")
|
||||
port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \
|
||||
grep -F '(LISTEN)')
|
||||
echo "$port_info" | \
|
||||
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1
|
||||
else
|
||||
if [ $sockstat_available -eq 0 ]; then
|
||||
port_info=$(echo "$port_info" | grep -q -F 'users:(')
|
||||
local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+'
|
||||
if [ $sockstat_available -eq 1 ]; then
|
||||
port_info=$(sockstat -p "$port" 2>/dev/null | \
|
||||
grep -E '[[:space:]]LISTEN' | grep -o -E "$filter")
|
||||
else
|
||||
port_info=$(ss -nlpH "( sport = :$port )" 2>/dev/null | \
|
||||
grep -F 'users:(' | grep -o -E "$filter")
|
||||
fi
|
||||
port_info=$(echo "$port_info" | \
|
||||
grep -E "[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+" -o)
|
||||
is_listening_all=$(echo "$port_info" | \
|
||||
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port\$")
|
||||
echo "$port_info" | \
|
||||
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port\$" && busy=1
|
||||
fi
|
||||
local is_listening_addr=$(echo "$port_info" | \
|
||||
grep -w -F -- "$rsync_addr:$rsync_port")
|
||||
if [ -z "$is_listening_addr" ]; then
|
||||
is_listening_addr=$(echo "$port_info" | \
|
||||
grep -w -F "[$rsync_addr]:$rsync_port")
|
||||
|
||||
if [ $busy -eq 0 ]; then
|
||||
if echo "$port_info" | grep -qw -F "[$addr]:$port" || \
|
||||
echo "$port_info" | grep -qw -F -- "$addr:$port"
|
||||
then
|
||||
busy=1
|
||||
fi
|
||||
fi
|
||||
if [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then
|
||||
wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \
|
||||
|
||||
if [ $busy -eq 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! check_port "$pid" "$port" "$utils"; then
|
||||
wsrep_log_error "rsync or stunnel daemon port '$port' " \
|
||||
"has been taken by another program"
|
||||
exit 16 # EBUSY
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
check_pid "$pid_file" && [ $(cat "$pid_file") -eq $rsync_pid ]
|
||||
check_pid "$pid_file" && [ $CHECK_PID -eq $pid ]
|
||||
}
|
||||
|
||||
STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
|
||||
|
||||
STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
|
||||
|
||||
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
|
||||
|
@ -201,6 +200,8 @@ FILTER="-f '- /lost+found'
|
|||
-f '- /.zfs'
|
||||
-f '- /.fseventsd'
|
||||
-f '- /.Trashes'
|
||||
-f '- /.pid'
|
||||
-f '- /.conf'
|
||||
-f '+ /wsrep_sst_binlog.tar'
|
||||
-f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
|
||||
-f '- $INNODB_DATA_HOME_DIR/ibdata*'
|
||||
|
@ -250,19 +251,31 @@ else
|
|||
CAFILE_OPT=""
|
||||
fi
|
||||
|
||||
VERIFY_OPT=""
|
||||
CHECK_OPT=""
|
||||
CHECK_OPT_LOCAL=""
|
||||
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
|
||||
then
|
||||
case "$SSLMODE" in
|
||||
'VERIFY_IDENTITY')
|
||||
VERIFY_OPT='verifyPeer = yes'
|
||||
CHECK_OPT=""
|
||||
;;
|
||||
'VERIFY_CA')
|
||||
VERIFY_OPT='verifyChain = yes'
|
||||
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
|
||||
CHECK_OPT='checkHost = localhost'
|
||||
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
|
||||
CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
|
||||
else
|
||||
CHECK_OPT='checkHost = $WSREP_SST_OPT_HOST_UNESCAPED'
|
||||
# check if the address is an ip-address (v4 or v6):
|
||||
if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
|
||||
grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
|
||||
then
|
||||
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
|
||||
else
|
||||
CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST"
|
||||
fi
|
||||
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
|
||||
CHECK_OPT_LOCAL="checkHost = localhost"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
|
@ -273,9 +286,6 @@ then
|
|||
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file"
|
||||
exit 22 # EINVAL
|
||||
fi
|
||||
else
|
||||
VERIFY_OPT=""
|
||||
CHECK_OPT=""
|
||||
fi
|
||||
|
||||
STUNNEL=""
|
||||
|
@ -294,10 +304,10 @@ then
|
|||
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
|
||||
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
|
||||
|
||||
if [ -n "$STUNNEL" ]
|
||||
then
|
||||
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
|
||||
cat << EOF > "$STUNNEL_CONF"
|
||||
key = $SSTKEY
|
||||
cert = $SSTCERT
|
||||
|
@ -310,7 +320,10 @@ connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT
|
|||
TIMEOUTclose = 0
|
||||
${VERIFY_OPT}
|
||||
${CHECK_OPT}
|
||||
${CHECK_OPT_LOCAL}
|
||||
EOF
|
||||
else
|
||||
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
|
||||
fi
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
|
@ -319,13 +332,8 @@ EOF
|
|||
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
|
||||
ERROR="$WSREP_SST_OPT_DATA/sst_error"
|
||||
|
||||
rm -rf "$FLUSHED"
|
||||
rm -rf "$ERROR"
|
||||
|
||||
# Use deltaxfer only for WAN
|
||||
inv=$(basename "$0")
|
||||
[ "$inv" = "wsrep_sst_rsync_wan" ] && WHOLE_FILE_OPT="" \
|
||||
|| WHOLE_FILE_OPT="--whole-file"
|
||||
[ -f "$FLUSHED" ] && rm -f "$FLUSHED"
|
||||
[ -f "$ERROR" ] && rm -f "$ERROR"
|
||||
|
||||
echo "flush tables"
|
||||
|
||||
|
@ -340,15 +348,14 @@ EOF
|
|||
if [ -f "$ERROR" ]
|
||||
then
|
||||
# Flush tables operation failed.
|
||||
rm -rf "$ERROR"
|
||||
rm -f "$ERROR"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
STATE=$(cat "$FLUSHED")
|
||||
rm -rf "$FLUSHED"
|
||||
rm -f "$FLUSHED"
|
||||
|
||||
sync
|
||||
|
||||
|
@ -375,6 +382,13 @@ EOF
|
|||
cd "$OLD_PWD"
|
||||
fi
|
||||
|
||||
# Use deltaxfer only for WAN
|
||||
inv=$(basename "$0")
|
||||
WHOLE_FILE_OPT=""
|
||||
if [ "${inv%wsrep_sst_rsync_wan*}" != "$inv" ]; then
|
||||
WHOLE_FILE_OPT="--whole-file"
|
||||
fi
|
||||
|
||||
# first, the normal directories, so that we can detect incompatible protocol
|
||||
RC=0
|
||||
eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \
|
||||
|
@ -426,16 +440,18 @@ EOF
|
|||
fi
|
||||
|
||||
# then, we parallelize the transfer of database directories,
|
||||
# use . so that path concatenation works:
|
||||
# use '.' so that path concatenation works:
|
||||
|
||||
cd "$WSREP_SST_OPT_DATA"
|
||||
|
||||
count=1
|
||||
[ "$OS" = 'Linux' ] && count=$(grep -c processor /proc/cpuinfo)
|
||||
[ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ] && count=$(sysctl -n hw.ncpu)
|
||||
backup_threads=$(parse_cnf "--mysqld|sst" 'backup-threads')
|
||||
if [ -z "$backup_threads" ]; then
|
||||
get_proc
|
||||
backup_threads=$nproc
|
||||
fi
|
||||
|
||||
find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \
|
||||
-not -name '.zfs' -print0 | xargs -I{} -0 -P $count \
|
||||
-not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \
|
||||
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
||||
--owner --group --perms --links --specials \
|
||||
--ignore-times --inplace --recursive --delete --quiet \
|
||||
|
@ -474,35 +490,52 @@ EOF
|
|||
|
||||
echo "done $STATE"
|
||||
|
||||
if [ -n "$STUNNEL" ]; then
|
||||
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
|
||||
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
|
||||
fi
|
||||
|
||||
elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
|
||||
then
|
||||
check_sockets_utils
|
||||
|
||||
touch "$SST_PROGRESS_FILE"
|
||||
MYSQLD_PID="$WSREP_SST_OPT_PARENT"
|
||||
|
||||
MODULE="rsync_sst"
|
||||
|
||||
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
||||
# give some time for lingering rsync from previous SST to complete
|
||||
# give some time for lingering stunnel from previous SST to complete
|
||||
check_round=0
|
||||
while check_pid "$RSYNC_PID" && [ $check_round -lt 10 ]
|
||||
while check_pid "$STUNNEL_PID" 1
|
||||
do
|
||||
wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
|
||||
wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit"
|
||||
check_round=$(( check_round + 1 ))
|
||||
if [ $check_round -eq 10 ]; then
|
||||
wsrep_log_error "stunnel daemon already running."
|
||||
exit 114 # EALREADY
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if check_pid "$RSYNC_PID"
|
||||
then
|
||||
wsrep_log_error "rsync daemon already running."
|
||||
exit 114 # EALREADY
|
||||
fi
|
||||
MODULE="rsync_sst"
|
||||
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
||||
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
|
||||
|
||||
# give some time for lingering rsync from previous SST to complete
|
||||
check_round=0
|
||||
while check_pid "$RSYNC_PID" 1
|
||||
do
|
||||
wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
|
||||
check_round=$(( check_round + 1 ))
|
||||
if [ $check_round -eq 10 ]; then
|
||||
wsrep_log_error "rsync daemon already running."
|
||||
exit 114 # EALREADY
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
[ -f "$RSYNC_PID" ] && rm -f "$RSYNC_PID"
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
|
||||
|
||||
if [ -z "$STUNNEL" ]; then
|
||||
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
|
||||
fi
|
||||
|
||||
ADDR="$WSREP_SST_OPT_ADDR"
|
||||
RSYNC_PORT="$WSREP_SST_OPT_PORT"
|
||||
RSYNC_ADDR="$WSREP_SST_OPT_HOST"
|
||||
|
@ -512,7 +545,7 @@ then
|
|||
trap "exit 3" INT TERM ABRT
|
||||
trap cleanup_joiner EXIT
|
||||
|
||||
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
|
||||
touch "$SST_PROGRESS_FILE"
|
||||
|
||||
if [ -n "${MYSQL_TMP_DIR:-}" ]; then
|
||||
SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
|
||||
|
@ -535,18 +568,18 @@ $SILENT
|
|||
path = $INNODB_DATA_HOME_DIR
|
||||
EOF
|
||||
|
||||
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
|
||||
# rm -rf "$DATA/ib_logfile"* # we don't want old logs around
|
||||
|
||||
# If the IP is local listen only in it
|
||||
# If the IP is local, listen only on it:
|
||||
if is_local_ip "$RSYNC_ADDR_UNESCAPED"
|
||||
then
|
||||
RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED"
|
||||
STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT"
|
||||
else
|
||||
# Not local, possibly a NAT, listen on all interfaces
|
||||
# Not local, possibly a NAT, listen on all interfaces:
|
||||
RSYNC_EXTRA_ARGS=""
|
||||
STUNNEL_ACCEPT="$RSYNC_PORT"
|
||||
# Overwrite address with all
|
||||
# Overwrite address with all:
|
||||
RSYNC_ADDR="*"
|
||||
fi
|
||||
|
||||
|
@ -554,8 +587,9 @@ EOF
|
|||
then
|
||||
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
|
||||
RSYNC_REAL_PID=$!
|
||||
TRANSFER_REAL_PID="$RSYNC_REAL_PID"
|
||||
TRANSFER_PID=$RSYNC_PID
|
||||
else
|
||||
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
|
||||
# Let's check if the path to the config file contains a space?
|
||||
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
|
||||
cat << EOF > "$STUNNEL_CONF"
|
||||
|
@ -566,6 +600,9 @@ foreground = yes
|
|||
pid = $STUNNEL_PID
|
||||
debug = warning
|
||||
client = no
|
||||
${VERIFY_OPT}
|
||||
${CHECK_OPT}
|
||||
${CHECK_OPT_LOCAL}
|
||||
[rsync]
|
||||
accept = $STUNNEL_ACCEPT
|
||||
exec = $(command -v rsync)
|
||||
|
@ -583,6 +620,9 @@ foreground = yes
|
|||
pid = $STUNNEL_PID
|
||||
debug = warning
|
||||
client = no
|
||||
${VERIFY_OPT}
|
||||
${CHECK_OPT}
|
||||
${CHECK_OPT_LOCAL}
|
||||
[rsync]
|
||||
accept = $STUNNEL_ACCEPT
|
||||
exec = $SHELL
|
||||
|
@ -590,15 +630,11 @@ execargs = $SHELL -c \$RSYNC_CMD
|
|||
EOF
|
||||
fi
|
||||
stunnel "$STUNNEL_CONF" &
|
||||
RSYNC_REAL_PID=$!
|
||||
RSYNC_PID="$STUNNEL_PID"
|
||||
STUNNEL_REAL_PID=$!
|
||||
TRANSFER_REAL_PID="$STUNNEL_REAL_PID"
|
||||
TRANSFER_PID=$STUNNEL_PID
|
||||
fi
|
||||
|
||||
until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
|
||||
do
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
|
||||
then # backward-incompatible behavior
|
||||
CN=""
|
||||
|
@ -619,19 +655,26 @@ EOF
|
|||
ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST"
|
||||
else
|
||||
MY_SECRET="" # for check down in recv_joiner()
|
||||
ADDR=$WSREP_SST_OPT_HOST
|
||||
ADDR="$WSREP_SST_OPT_HOST"
|
||||
fi
|
||||
|
||||
until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
|
||||
do
|
||||
sleep 0.2
|
||||
done
|
||||
|
||||
echo "ready $ADDR:$RSYNC_PORT/$MODULE"
|
||||
|
||||
MYSQLD_PID="$WSREP_SST_OPT_PARENT"
|
||||
|
||||
# wait for SST to complete by monitoring magic file
|
||||
while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \
|
||||
ps -p $MYSQLD_PID >/dev/null
|
||||
while [ ! -r "$MAGIC_FILE" ] && check_pid "$TRANSFER_PID" && \
|
||||
ps -p $MYSQLD_PID >/dev/null 2>&1
|
||||
do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ! ps -p $MYSQLD_PID >/dev/null
|
||||
if ! ps -p $MYSQLD_PID >/dev/null 2>&1
|
||||
then
|
||||
wsrep_log_error \
|
||||
"Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly."
|
||||
|
@ -682,7 +725,7 @@ EOF
|
|||
echo "rsync process ended without creating '$MAGIC_FILE'"
|
||||
fi
|
||||
|
||||
wsrep_cleanup_progress_file
|
||||
# wsrep_cleanup_progress_file
|
||||
# cleanup_joiner
|
||||
else
|
||||
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (c) 2005, 2019, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2020, MariaDB
|
||||
Copyright (c) 2009, 2021, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -2305,25 +2305,6 @@ void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Change comments specific to handler
|
||||
|
||||
SYNOPSIS
|
||||
update_table_comment()
|
||||
comment Original comment
|
||||
|
||||
RETURN VALUE
|
||||
new comment
|
||||
|
||||
DESCRIPTION
|
||||
No comment changes so far
|
||||
*/
|
||||
|
||||
char *ha_partition::update_table_comment(const char *comment)
|
||||
{
|
||||
return (char*) comment; /* Nothing to change */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Handle delete and rename table
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/*
|
||||
Copyright (c) 2005, 2012, Oracle and/or its affiliates.
|
||||
Copyright (c) 2009, 2013, Monty Program Ab & SkySQL Ab.
|
||||
Copyright (c) 2009, 2021, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -519,10 +519,6 @@ public:
|
|||
Meta data routines to CREATE, DROP, RENAME table and often used at
|
||||
ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..).
|
||||
|
||||
update_table_comment is used in SHOW TABLE commands to provide a
|
||||
chance for the handler to add any interesting comments to the table
|
||||
comments not provided by the users comment.
|
||||
|
||||
create_partitioning_metadata is called before opening a new handler object
|
||||
with openfrm to call create. It is used to create any local handler
|
||||
object needed in opening the object in openfrm
|
||||
|
@ -535,7 +531,6 @@ public:
|
|||
virtual int create_partitioning_metadata(const char *name,
|
||||
const char *old_name, int action_flag);
|
||||
virtual void update_create_info(HA_CREATE_INFO *create_info);
|
||||
virtual char *update_table_comment(const char *comment);
|
||||
virtual int change_partitions(HA_CREATE_INFO *create_info,
|
||||
const char *path,
|
||||
ulonglong * const copied,
|
||||
|
|
|
@ -3729,8 +3729,6 @@ public:
|
|||
/* end of the list of admin commands */
|
||||
|
||||
virtual int indexes_are_disabled(void) {return 0;}
|
||||
virtual char *update_table_comment(const char * comment)
|
||||
{ return (char*) comment;}
|
||||
virtual void append_create_info(String *packet) {}
|
||||
/**
|
||||
If index == MAX_KEY then a check for table is made and if index <
|
||||
|
|
|
@ -520,8 +520,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
|
||||
DEBUG_SYNC(thd, "admin_command_kill_before_modify");
|
||||
|
||||
if (thd->is_killed())
|
||||
break;
|
||||
strxmov(table_name, db, ".", table->table_name.str, NullS);
|
||||
thd->open_options|= extra_open_options;
|
||||
table->lock_type= lock_type;
|
||||
|
@ -536,6 +534,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
: lock_type >= TL_WRITE_ALLOW_WRITE
|
||||
? MDL_SHARED_WRITE : MDL_SHARED_READ);
|
||||
|
||||
if (thd->check_killed())
|
||||
{
|
||||
fatal_error= true;
|
||||
result_code= HA_ADMIN_FAILED;
|
||||
goto send_result;
|
||||
}
|
||||
|
||||
/* open only one table from local list of command */
|
||||
while (1)
|
||||
{
|
||||
|
|
|
@ -9129,6 +9129,23 @@ int dynamic_column_error_message(enum_dyncol_func_result rc)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Turn on the SELECT_DESCRIBE flag for the primary SELECT_LEX of the statement
|
||||
being processed in case the statement is EXPLAIN UPDATE/DELETE.
|
||||
|
||||
@param lex current LEX
|
||||
*/
|
||||
|
||||
void promote_select_describe_flag_if_needed(LEX *lex)
|
||||
{
|
||||
if (lex->describe)
|
||||
{
|
||||
lex->select_lex.options |= SELECT_DESCRIBE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@} (end of group Data_Dictionary)
|
||||
*/
|
||||
|
|
|
@ -512,6 +512,8 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables,
|
|||
Prelocking_strategy *prelocking_strategy,
|
||||
bool has_prelocking_list);
|
||||
|
||||
void promote_select_describe_flag_if_needed(LEX *lex);
|
||||
|
||||
/**
|
||||
A context of open_tables() function, used to recover
|
||||
from a failed open_table() or open_routine() attempt.
|
||||
|
|
|
@ -328,6 +328,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||
query_plan.table= table;
|
||||
query_plan.updating_a_view= MY_TEST(table_list->view);
|
||||
|
||||
promote_select_describe_flag_if_needed(thd->lex);
|
||||
|
||||
if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
|
||||
select_lex->item_list, &conds,
|
||||
&delete_while_scanning))
|
||||
|
|
|
@ -399,6 +399,8 @@ int mysql_update(THD *thd,
|
|||
want_privilege= (table_list->view ? UPDATE_ACL :
|
||||
table_list->grant.want_privilege);
|
||||
#endif
|
||||
promote_select_describe_flag_if_needed(thd->lex);
|
||||
|
||||
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
|
|
|
@ -60,12 +60,12 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
|
|||
|
||||
if (Uri) {
|
||||
if (*Uri == '/' || Http[strlen(Http) - 1] == '/')
|
||||
sprintf(buf, "%s%s", Http, Uri);
|
||||
my_snprintf(buf, sizeof(buf)-1, "%s%s", Http, Uri);
|
||||
else
|
||||
sprintf(buf, "%s/%s", Http, Uri);
|
||||
my_snprintf(buf, sizeof(buf)-1, "%s/%s", Http, Uri);
|
||||
|
||||
} else
|
||||
strcpy(buf, Http);
|
||||
my_snprintf(buf, sizeof(buf)-1, "%s", Http);
|
||||
|
||||
#if defined(__WIN__)
|
||||
char cmd[1024];
|
||||
|
|
|
@ -14974,70 +14974,6 @@ ha_innobase::check(
|
|||
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Adds information about free space in the InnoDB tablespace to a table comment
|
||||
which is printed out when a user calls SHOW TABLE STATUS. Adds also info on
|
||||
foreign keys.
|
||||
@return table comment + InnoDB free space + info on foreign keys */
|
||||
UNIV_INTERN
|
||||
char*
|
||||
ha_innobase::update_table_comment(
|
||||
/*==============================*/
|
||||
const char* comment)/*!< in: table comment defined by user */
|
||||
{
|
||||
uint length = (uint) strlen(comment);
|
||||
char* str=0;
|
||||
size_t flen;
|
||||
std::string fk_str;
|
||||
|
||||
/* We do not know if MySQL can call this function before calling
|
||||
external_lock(). To be safe, update the thd of the current table
|
||||
handle. */
|
||||
|
||||
if (length > 64000 - 3) {
|
||||
return((char*) comment); /* string too long */
|
||||
}
|
||||
|
||||
update_thd(ha_thd());
|
||||
|
||||
m_prebuilt->trx->op_info = "returning table comment";
|
||||
|
||||
#define SSTR( x ) reinterpret_cast< std::ostringstream & >( \
|
||||
( std::ostringstream() << std::dec << x ) ).str()
|
||||
|
||||
if (m_prebuilt->table->space) {
|
||||
fk_str.append("InnoDB free: ");
|
||||
fk_str.append(SSTR(fsp_get_available_space_in_free_extents(
|
||||
*m_prebuilt->table->space)));
|
||||
}
|
||||
|
||||
fk_str.append(dict_print_info_on_foreign_keys(
|
||||
FALSE, m_prebuilt->trx,
|
||||
m_prebuilt->table));
|
||||
|
||||
flen = fk_str.length();
|
||||
|
||||
if (length + flen + 3 > 64000) {
|
||||
flen = 64000 - 3 - length;
|
||||
}
|
||||
/* allocate buffer for the full string */
|
||||
str = (char*) my_malloc(length + flen + 3, MYF(0));
|
||||
if (str) {
|
||||
char* pos = str + length;
|
||||
if (length) {
|
||||
memcpy(str, comment, length);
|
||||
*pos++ = ';';
|
||||
*pos++ = ' ';
|
||||
}
|
||||
memcpy(pos, fk_str.c_str(), flen);
|
||||
pos[flen] = 0;
|
||||
}
|
||||
|
||||
m_prebuilt->trx->op_info = (char*)"";
|
||||
|
||||
return(str ? str : (char*) comment);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Gets the foreign key create info for a table stored in InnoDB.
|
||||
@return own: character string in the form which can be inserted to the
|
||||
|
|
|
@ -219,7 +219,6 @@ public:
|
|||
int rename_table(const char* from, const char* to);
|
||||
inline int defragment_table(const char* name);
|
||||
int check(THD* thd, HA_CHECK_OPT* check_opt);
|
||||
char* update_table_comment(const char* comment);
|
||||
|
||||
char* get_foreign_key_create_info();
|
||||
|
||||
|
|
|
@ -149,6 +149,76 @@ row_sel_sec_rec_is_for_blob(
|
|||
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
|
||||
}
|
||||
|
||||
/** Function to read the secondary spatial index, calculate
|
||||
the minimum bounding rectangle for clustered index record
|
||||
and secondary index record and compare it.
|
||||
@param sec_rec secondary index record
|
||||
@param sec_index spatial secondary index
|
||||
@param clust_rec clustered index record
|
||||
@param clust_index clustered index
|
||||
@retval DB_SUCCESS_LOCKED_REC if the secondary record is equal to the
|
||||
corresponding fields in the clustered record, when compared with
|
||||
collation;
|
||||
@retval DB_SUCCESS if not equal */
|
||||
static
|
||||
dberr_t
|
||||
row_sel_spatial_sec_rec_is_for_clust_rec(
|
||||
const rec_t *sec_rec, const dict_index_t *sec_index,
|
||||
const rec_t *clust_rec, dict_index_t *clust_index)
|
||||
{
|
||||
mem_heap_t *heap= mem_heap_create(256);
|
||||
rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
rec_offs *clust_offs= clust_offsets_;
|
||||
ulint clust_len;
|
||||
|
||||
rec_offs_init(clust_offsets_);
|
||||
ulint clust_pos= dict_col_get_clust_pos(
|
||||
dict_index_get_nth_col(sec_index, 0), clust_index);
|
||||
clust_offs= rec_get_offsets(clust_rec, clust_index, clust_offs,
|
||||
clust_index->n_core_fields, clust_pos + 1,
|
||||
&heap);
|
||||
ut_ad(sec_index->n_user_defined_cols == 1);
|
||||
const byte *clust_field= rec_get_nth_field(clust_rec, clust_offs,
|
||||
clust_pos, &clust_len);
|
||||
if (clust_len == UNIV_SQL_NULL || clust_len < GEO_DATA_HEADER_SIZE)
|
||||
{
|
||||
ut_ad("corrupted geometry column" == 0);
|
||||
err_exit:
|
||||
mem_heap_free(heap);
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
/* For externally stored field, we need to get full
|
||||
geo data to generate the MBR for comparing. */
|
||||
if (rec_offs_nth_extern(clust_offs, clust_pos))
|
||||
{
|
||||
clust_field= btr_copy_externally_stored_field(
|
||||
&clust_len, clust_field, dict_table_page_size(sec_index->table),
|
||||
clust_len, heap);
|
||||
if (clust_field == NULL)
|
||||
{
|
||||
ut_ad("corrupted geometry blob" == 0);
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
ut_ad(clust_len >= GEO_DATA_HEADER_SIZE);
|
||||
rtr_mbr_t tmp_mbr;
|
||||
rtr_mbr_t sec_mbr;
|
||||
|
||||
rtree_mbr_from_wkb(
|
||||
clust_field + GEO_DATA_HEADER_SIZE,
|
||||
static_cast<uint>(clust_len - GEO_DATA_HEADER_SIZE),
|
||||
SPDIMS, reinterpret_cast<double*>(&tmp_mbr));
|
||||
|
||||
rtr_read_mbr(sec_rec, &sec_mbr);
|
||||
|
||||
mem_heap_free(heap);
|
||||
return MBR_EQUAL_CMP(&sec_mbr, &tmp_mbr)
|
||||
? DB_SUCCESS_LOCKED_REC
|
||||
: DB_SUCCESS;
|
||||
}
|
||||
|
||||
/** Returns TRUE if the user-defined column values in a secondary index record
|
||||
are alphabetically the same as the corresponding columns in the clustered
|
||||
index record.
|
||||
|
@ -176,20 +246,6 @@ row_sel_sec_rec_is_for_clust_rec(
|
|||
dict_index_t* clust_index,
|
||||
que_thr_t* thr)
|
||||
{
|
||||
const byte* sec_field;
|
||||
ulint sec_len;
|
||||
const byte* clust_field;
|
||||
ulint n;
|
||||
ulint i;
|
||||
mem_heap_t* heap = NULL;
|
||||
rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
rec_offs sec_offsets_[REC_OFFS_SMALL_SIZE];
|
||||
rec_offs* clust_offs = clust_offsets_;
|
||||
rec_offs* sec_offs = sec_offsets_;
|
||||
|
||||
rec_offs_init(clust_offsets_);
|
||||
rec_offs_init(sec_offsets_);
|
||||
|
||||
if (rec_get_deleted_flag(clust_rec,
|
||||
dict_table_is_comp(clust_index->table))) {
|
||||
/* In delete-marked records, DB_TRX_ID must
|
||||
|
@ -203,7 +259,27 @@ row_sel_sec_rec_is_for_clust_rec(
|
|||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
heap = mem_heap_create(256);
|
||||
if (dict_index_is_spatial(sec_index)) {
|
||||
return row_sel_spatial_sec_rec_is_for_clust_rec(
|
||||
sec_rec, sec_index, clust_rec,
|
||||
clust_index);
|
||||
}
|
||||
|
||||
const byte* sec_field;
|
||||
ulint sec_len;
|
||||
const byte* clust_field;
|
||||
ulint n;
|
||||
ulint i;
|
||||
mem_heap_t* heap = mem_heap_create(256);
|
||||
rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
rec_offs sec_offsets_[REC_OFFS_SMALL_SIZE];
|
||||
rec_offs* clust_offs = clust_offsets_;
|
||||
rec_offs* sec_offs = sec_offsets_;
|
||||
|
||||
rec_offs_init(clust_offsets_);
|
||||
rec_offs_init(sec_offsets_);
|
||||
|
||||
|
||||
ib_vcol_row vc(heap);
|
||||
|
||||
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
|
||||
|
@ -311,44 +387,10 @@ check_for_blob:
|
|||
}
|
||||
}
|
||||
|
||||
/* For spatial index, the first field is MBR, we check
|
||||
if the MBR is equal or not. */
|
||||
if (dict_index_is_spatial(sec_index) && i == 0) {
|
||||
rtr_mbr_t tmp_mbr;
|
||||
rtr_mbr_t sec_mbr;
|
||||
byte* dptr =
|
||||
const_cast<byte*>(clust_field);
|
||||
|
||||
ut_ad(clust_len != UNIV_SQL_NULL);
|
||||
|
||||
/* For externally stored field, we need to get full
|
||||
geo data to generate the MBR for comparing. */
|
||||
if (rec_offs_nth_extern(clust_offs, clust_pos)) {
|
||||
dptr = btr_copy_externally_stored_field(
|
||||
&clust_len, dptr,
|
||||
page_size_t(clust_index->table->space
|
||||
->flags),
|
||||
len, heap);
|
||||
}
|
||||
|
||||
rtree_mbr_from_wkb(dptr + GEO_DATA_HEADER_SIZE,
|
||||
static_cast<uint>(clust_len
|
||||
- GEO_DATA_HEADER_SIZE),
|
||||
SPDIMS,
|
||||
reinterpret_cast<double*>(
|
||||
&tmp_mbr));
|
||||
rtr_read_mbr(sec_field, &sec_mbr);
|
||||
|
||||
if (!MBR_EQUAL_CMP(&sec_mbr, &tmp_mbr)) {
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (0 != cmp_data_data(col->mtype, col->prtype,
|
||||
clust_field, len,
|
||||
sec_field, sec_len)) {
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
if (0 != cmp_data_data(col->mtype, col->prtype,
|
||||
clust_field, len,
|
||||
sec_field, sec_len)) {
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue