Merge 10.2 into 10.3

This commit is contained in:
Marko Mäkelä 2021-06-01 08:40:59 +03:00
commit 950a220060
37 changed files with 986 additions and 778 deletions

View file

@ -214,7 +214,7 @@ ibx_mode_t ibx_mode = IBX_MODE_BACKUP;
static struct my_option ibx_long_options[] = 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, (uchar *) &opt_ibx_version, (uchar *) &opt_ibx_version, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 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, (uchar *) &opt_ibx_slave_info, (uchar *) &opt_ibx_slave_info, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"incremental", OPT_INCREMENTAL, "This option tells xtrabackup to " {"incremental", OPT_INCREMENTAL,
"create an incremental backup, rather than a full one. It is passed " "Create an incremental backup, rather than a full one. When this option is specified, "
"to the xtrabackup child process. When this option is specified, "
"either --incremental-lsn or --incremental-basedir can also be given. " "either --incremental-lsn or --incremental-basedir can also be given. "
"If neither option is given, option --incremental-basedir is passed " "If neither option is given, option --incremental-basedir is used "
"to xtrabackup by default, set to the first timestamped backup " "by default, set to the first timestamped backup "
"directory in the backup base directory.", "directory in the backup base directory.",
(uchar *) &opt_ibx_incremental, (uchar *) &opt_ibx_incremental, 0, (uchar *) &opt_ibx_incremental, (uchar *) &opt_ibx_incremental, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 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, {"incremental-history-name", OPT_INCREMENTAL_HISTORY_NAME,
"This option specifies the name of the backup series stored in the " "This option specifies the name of the backup series stored in the "
"PERCONA_SCHEMA.xtrabackup_history history record to base an " "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 " "looking for the most recent (highest innodb_to_lsn), successful "
"backup in the series and take the to_lsn value to use as the " "backup in the series and take the to_lsn value to use as the "
"starting lsn for the incremental backup. This will be mutually " "starting lsn for the incremental backup. This will be mutually "
"exclusive with --incremental-history-uuid, --incremental-basedir " "exclusive with --incremental-history-uuid, --incremental-basedir "
"and --incremental-lsn. If no valid lsn can be found (no series by " "and --incremental-lsn. If no valid lsn can be found (no series by "
"that name, no successful backups by that name) xtrabackup will " "that name, no successful backups by that name), "
"return with an error. It is used with the --incremental option.", "an error will be returned. It is used with the --incremental option.",
(uchar*) &opt_ibx_incremental_history_name, (uchar*) &opt_ibx_incremental_history_name,
(uchar*) &opt_ibx_incremental_history_name, 0, GET_STR, (uchar*) &opt_ibx_incremental_history_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 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 " "stored in the PERCONA_SCHEMA.xtrabackup_history to base an "
"incremental backup on. --incremental-history-name, " "incremental backup on. --incremental-history-name, "
"--incremental-basedir and --incremental-lsn. If no valid lsn can be " "--incremental-basedir and --incremental-lsn. If no valid lsn can be "
"found (no success record with that uuid) xtrabackup will return " "found (no success record with that uuid), an error will be returned."
"with an error. It is used with the --incremental option.", " It is used with the --incremental option.",
(uchar*) &opt_ibx_incremental_history_uuid, (uchar*) &opt_ibx_incremental_history_uuid,
(uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR, (uchar*) &opt_ibx_incremental_history_uuid, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@ -424,7 +423,7 @@ static struct my_option ibx_long_options[] =
{"include", OPT_INCLUDE, {"include", OPT_INCLUDE,
"This option is a regular expression to be matched against table " "This option is a regular expression to be matched against table "
"names in databasename.tablename format. It is passed directly to " "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.", "details.",
(uchar*) &opt_ibx_include, (uchar*) &opt_ibx_include,
(uchar*) &opt_ibx_include, 0, GET_STR, (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, (uchar*) &opt_ibx_lock_wait_threshold, 0, GET_UINT,
REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, 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, {"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT,
"How many seconds --safe-slave-backup should wait for " "How many seconds --safe-slave-backup should wait for "
"Slave_open_temp_tables to become zero. (default 300)", "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 We put them here with only purpose for them to showup in
innobackupex --help output */ innobackupex --help output */
{"close_files", OPT_CLOSE_FILES, "Do not keep files opened. This " {"close_files", OPT_CLOSE_FILES, "Do not keep files opened."
"option is passed directly to xtrabackup. Use at your own risk.", " Use at your own risk.",
(uchar*) &ibx_xb_close_files, (uchar*) &ibx_xb_close_files, 0, (uchar*) &ibx_xb_close_files, (uchar*) &ibx_xb_close_files, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"compress", OPT_COMPRESS, "This option instructs xtrabackup to " {"compress", OPT_COMPRESS, "This option instructs backup to "
"compress backup copies of InnoDB data files. It is passed directly " "compress backup copies of InnoDB data files."
"to the xtrabackup child process. Try 'xtrabackup --help' for more " , (uchar*) &ibx_xtrabackup_compress_alg,
"details.", (uchar*) &ibx_xtrabackup_compress_alg,
(uchar*) &ibx_xtrabackup_compress_alg, 0, (uchar*) &ibx_xtrabackup_compress_alg, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"compress-threads", OPT_COMPRESS_THREADS, {"compress-threads", OPT_COMPRESS_THREADS,
"This option specifies the number of worker threads that will be used " "This option specifies the number of worker threads that will be used "
"for parallel compression. It is passed directly to the xtrabackup " "for parallel compression.",
"child process. Try 'xtrabackup --help' for more details.",
(uchar*) &ibx_xtrabackup_compress_threads, (uchar*) &ibx_xtrabackup_compress_threads,
(uchar*) &ibx_xtrabackup_compress_threads, (uchar*) &ibx_xtrabackup_compress_threads,
0, GET_UINT, REQUIRED_ARG, 1, 1, UINT_MAX, 0, 0, 0}, 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, (uchar*) &ibx_xtrabackup_compress_chunk_size,
0, GET_ULL, REQUIRED_ARG, (1 << 16), 1024, ULONGLONG_MAX, 0, 0, 0}, 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", OPT_EXPORT, " enables exporting individual tables for import "
"--export option. It enables exporting individual tables for import " "into another server.",
"into another server. See the xtrabackup documentation for details.",
(uchar*) &ibx_xtrabackup_export, (uchar*) &ibx_xtrabackup_export, (uchar*) &ibx_xtrabackup_export, (uchar*) &ibx_xtrabackup_export,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"extra-lsndir", OPT_EXTRA_LSNDIR, "This option specifies the " {"extra-lsndir", OPT_EXTRA_LSNDIR, "This option specifies the "
"directory in which to save an extra copy of the " "directory in which to save an extra copy of the "
"\"xtrabackup_checkpoints\" file. The option accepts a string " "\"xtrabackup_checkpoints\" file. The option accepts a string "
"argument. It is passed directly to xtrabackup's --extra-lsndir " "argument.",
"option. See the xtrabackup documentation for details.",
(uchar*) &ibx_xtrabackup_extra_lsndir, (uchar*) &ibx_xtrabackup_extra_lsndir,
(uchar*) &ibx_xtrabackup_extra_lsndir, (uchar*) &ibx_xtrabackup_extra_lsndir,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 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}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"incremental-force-scan", OPT_INCREMENTAL_FORCE_SCAN, {"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 " "for taking an incremental backup even if full changed page bitmap "
"data is available to enable the backup without the full scan.", "data is available to enable the backup without the full scan.",
(uchar*)&ibx_xtrabackup_incremental_force_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}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"parallel", OPT_PARALLEL, "On backup, this option specifies the " {"parallel", OPT_PARALLEL, "On backup, this option specifies the "
"number of threads the xtrabackup child process should use to back " "number of threads to use to back "
"up files concurrently. The option accepts an integer argument. It " "up files concurrently. The option accepts an integer argument.",
"is passed directly to xtrabackup's --parallel option. See the "
"xtrabackup documentation for details.",
(uchar*) &ibx_xtrabackup_parallel, (uchar*) &ibx_xtrabackup_parallel, (uchar*) &ibx_xtrabackup_parallel, (uchar*) &ibx_xtrabackup_parallel,
0, GET_INT, REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0}, 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 " {"stream", OPT_STREAM, "This option specifies the format in which to "
"do the streamed backup. The option accepts a string argument. The " "do the streamed backup. The option accepts a string argument. The "
"backup will be done to STDOUT in the specified format. Currently, " "backup will be done to STDOUT in the specified format. Currently, "
"the only supported formats are tar and mbstream/xbstream. This " "the only supported formats are tar and mbstream/xbstream.",
"option is passed directly to xtrabackup's --stream option.",
(uchar*) &ibx_xtrabackup_stream_str, (uchar*) &ibx_xtrabackup_stream_str,
(uchar*) &ibx_xtrabackup_stream_str, 0, GET_STR, (uchar*) &ibx_xtrabackup_stream_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"tables-file", OPT_TABLES_FILE, "This option specifies the file in " {"tables-file", OPT_TABLES_FILE, "This option specifies the file in "
"which there are a list of names of the form database. The option " "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 " "accepts a string argument.table, one per line.",
"directly to xtrabackup's --tables-file option.",
(uchar*) &ibx_xtrabackup_tables_file, (uchar*) &ibx_xtrabackup_tables_file,
(uchar*) &ibx_xtrabackup_tables_file, (uchar*) &ibx_xtrabackup_tables_file,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"throttle", OPT_THROTTLE, "This option specifies a number of I/O " {"throttle", OPT_THROTTLE, "This option specifies a number of I/O "
"operations (pairs of read+write) per second. It accepts an integer " "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, (uchar*) &ibx_xtrabackup_throttle, (uchar*) &ibx_xtrabackup_throttle,
0, GET_LONG, REQUIRED_ARG, 0, 0, LONG_MAX, 0, 1, 0}, 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}, 0, 0, 0, 0, 0, 0},
{"use-memory", OPT_USE_MEMORY, "This option accepts a string argument " {"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 " "for crash recovery while preparing a backup. Multiples are supported "
"providing the unit (e.g. 1MB, 1GB). It is used only with the option " "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 " "--apply-log.",
"option. See the xtrabackup documentation for details.",
(uchar*) &ibx_xtrabackup_use_memory, (uchar*) &ibx_xtrabackup_use_memory,
(uchar*) &ibx_xtrabackup_use_memory, (uchar*) &ibx_xtrabackup_use_memory,
0, GET_LL, REQUIRED_ARG, 100*1024*1024L, 1024*1024L, LONGLONG_MAX, 0, 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) static void usage(void)
{ {
puts("Open source backup tool for InnoDB and XtraDB\n\ puts("Open source backup tool\n\
\n\ \n\
Copyright (C) 2009-2015 Percona LLC and/or its affiliates.\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\ Portions Copyright (C) 2000, 2011, MySQL AB & Innobase Oy. All Rights Reserved.\n\
@ -692,7 +676,7 @@ innobackupex [--decompress]\n\
\n\ \n\
DESCRIPTION\n\ DESCRIPTION\n\
\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\ 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\ 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\ 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\ --databases option. The created backup contains .frm, .MRG, .MYD,\n\
.MYI, .MAD, .MAI, .TRG, .TRN, .ARM, .ARZ, .CSM, CSV, .opt, .par, and\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\ 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\ location of the database.\n\
using the mysql client program, and runs xtrabackup as a child\n\
process.\n\
\n\ \n\
The --apply-log command prepares a backup for starting a MySQL\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\ 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\ 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\ 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\ The BACKUP-DIR should be the path to a backup directory\n\
xtrabackup. This command runs xtrabackup as a child process, but it does not \n\
connect to the database server.\n\
\n\ \n\
The --copy-back command copies data, index, and log files\n\ The --copy-back command copies data, index, and log files\n\
from the backup directory back to their original locations.\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 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\ \n\
The --move-back command is similar to --copy-back with the only difference that\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\ it moves files to their original locations rather than copies them. As this\n\

View file

@ -261,9 +261,6 @@ it every INNOBASE_WAKE_INTERVAL'th step. */
#define INNOBASE_WAKE_INTERVAL 32 #define INNOBASE_WAKE_INTERVAL 32
ulong innobase_active_counter = 0; ulong innobase_active_counter = 0;
#ifndef _WIN32
static char *xtrabackup_debug_sync = NULL;
#endif
my_bool xtrabackup_incremental_force_scan = FALSE; my_bool xtrabackup_incremental_force_scan = FALSE;
@ -1056,7 +1053,7 @@ enum options_xtrabackup
struct my_option xb_client_options[]= { struct my_option xb_client_options[]= {
{"verbose", 'V', "display verbose output", (G_PTR *) &verbose, {"verbose", 'V', "display verbose output", (G_PTR *) &verbose,
(G_PTR *) &verbose, 0, GET_BOOL, NO_ARG, FALSE, 0, 0, 0, 0, 0}, (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, (G_PTR *) &xtrabackup_version, (G_PTR *) &xtrabackup_version, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
{"target-dir", OPT_XTRA_TARGET_DIR, "destination directory", {"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 " "starting lsn for the incremental backup. This will be mutually "
"exclusive with --incremental-history-uuid, --incremental-basedir " "exclusive with --incremental-history-uuid, --incremental-basedir "
"and --incremental-lsn. If no valid lsn can be found (no series by " "and --incremental-lsn. If no valid lsn can be found (no series by "
"that name, no successful backups by that name) xtrabackup will " "that name, no successful backups by that name), an error will be returned."
"return with an error. It is used with the --incremental option.", " It is used with the --incremental option.",
(uchar *) &opt_incremental_history_name, (uchar *) &opt_incremental_history_name,
(uchar *) &opt_incremental_history_name, 0, GET_STR, REQUIRED_ARG, 0, 0, (uchar *) &opt_incremental_history_name, 0, GET_STR, REQUIRED_ARG, 0, 0,
0, 0, 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 " "stored in the PERCONA_SCHEMA.xtrabackup_history to base an "
"incremental backup on. --incremental-history-name, " "incremental backup on. --incremental-history-name, "
"--incremental-basedir and --incremental-lsn. If no valid lsn can be " "--incremental-basedir and --incremental-lsn. If no valid lsn can be "
"found (no success record with that uuid) xtrabackup will return " "found (no success record with that uuid), an error will be returned."
"with an error. It is used with the --incremental option.", " It is used with the --incremental option.",
(uchar *) &opt_incremental_history_uuid, (uchar *) &opt_incremental_history_uuid,
(uchar *) &opt_incremental_history_uuid, 0, GET_STR, REQUIRED_ARG, 0, 0, (uchar *) &opt_incremental_history_uuid, 0, GET_STR, REQUIRED_ARG, 0, 0,
0, 0, 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, (uchar *) &opt_lock_wait_threshold, (uchar *) &opt_lock_wait_threshold, 0,
GET_UINT, REQUIRED_ARG, 60, 0, 0, 0, 0, 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, {"safe-slave-backup-timeout", OPT_SAFE_SLAVE_BACKUP_TIMEOUT,
"How many seconds --safe-slave-backup should wait for " "How many seconds --safe-slave-backup should wait for "
@ -1436,9 +1428,9 @@ struct my_option xb_client_options[]= {
0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{"binlog-info", OPT_BINLOG_INFO, {"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, " "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_binlog_info, &opt_binlog_info, &binlog_info_typelib, GET_ENUM,
OPT_ARG, BINLOG_INFO_AUTO, 0, 0, 0, 0, 0}, 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, &dbug_option, &dbug_option, 0, GET_STR, OPT_ARG,
0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, 0},
#endif #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, {"innodb_checksum_algorithm", OPT_INNODB_CHECKSUM_ALGORITHM,
"The algorithm InnoDB uses for page checksumming. [CRC32, STRICT_CRC32, " "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}, REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
{"lock-ddl-per-table", OPT_LOCK_DDL_PER_TABLE, "Lock DDL for each table " {"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, (uchar*) &opt_lock_ddl_per_table, (uchar*) &opt_lock_ddl_per_table, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 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); 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; 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; log_copy_scanned_lsn = start_lsn;
pthread_cond_broadcast(&scanned_lsn_cond); pthread_cond_broadcast(&scanned_lsn_cond);
pthread_mutex_unlock(&backup_mutex); pthread_mutex_unlock(&backup_mutex);
debug_sync_point("xtrabackup_copy_logfile_pause");
return(false); return(false);
} }
@ -3239,8 +3168,6 @@ DECLARE_THREAD(data_copy_thread_func)(
*/ */
my_thread_init(); my_thread_init();
debug_sync_point("data_copy_thread_func");
while ((node = datafiles_iter_next(ctxt->it)) != NULL) { while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name); DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
DBUG_EXECUTE_FOR_KEY("wait_innodb_redo_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) { if (err != DB_SUCCESS) {
return(err); return(err);
} }
debug_sync_point("xtrabackup_load_tablespaces_pause");
DBUG_MARIABACKUP_EVENT("after_load_tablespaces", 0); DBUG_MARIABACKUP_EVENT("after_load_tablespaces", 0);
return(DB_SUCCESS); return(DB_SUCCESS);
} }
@ -4607,8 +4532,6 @@ fail_before_log_copying_thread_start:
if (!flush_changed_page_bitmaps()) { if (!flush_changed_page_bitmaps()) {
goto fail; goto fail;
} }
debug_sync_point("xtrabackup_suspend_at_start");
ut_a(xtrabackup_parallel > 0); 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 */ /* --backup */
if (xtrabackup_backup && !xtrabackup_backup_func()) { if (xtrabackup_backup && !xtrabackup_backup_func()) {
return(EXIT_FAILURE); return(EXIT_FAILURE);

View file

@ -628,7 +628,7 @@ sub self2str {
sub _verbose { sub _verbose {
return unless $_verbose; return unless $_verbose;
print STDERR " ## ". @_. "\n"; print STDERR " ## @_\n";
} }

View file

@ -5533,5 +5533,23 @@ Note 1003 /* select#1 */ select (/* select#2 */ select 1 from `test`.`t2` where
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2; 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 # End of 10.2 tests
# #

View file

@ -4983,6 +4983,20 @@ SHOW WARNINGS;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2; DROP TABLE t1, t2;
--echo # --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 # End of 10.2 tests
--echo # --echo #

View file

@ -9,4 +9,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'

View file

@ -11,4 +11,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'

View file

@ -8,5 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'

View file

@ -13,4 +13,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
[sst] [sst]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=mbstream

View file

@ -10,3 +10,4 @@ transferfmt=@ENV.MTR_GALERA_TFMT
compress=quicklz compress=quicklz
compress-threads=2 compress-threads=2
compress-chunk-size=32768 compress-chunk-size=32768
backup-threads=2

View file

@ -15,4 +15,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
[sst] [sst]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=mbstream

View file

@ -8,4 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
[mysqld.2] [mysqld.2]
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'

View file

@ -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' 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=@ENV.MYSQLTEST_VARDIR/server2_binlog
log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index

View file

@ -9,3 +9,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
[mysqld.2] [mysqld.2]
innodb_data_home_dir=@ENV.MYSQL_TMP_DIR/rsync_test_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' wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
[sst]
backup_threads=2

View file

@ -34,4 +34,3 @@ bind-address=::
[SST] [SST]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=xbstream
sockopt=",pf=ip6"

View file

@ -38,4 +38,5 @@ bind-address=::
[SST] [SST]
transferfmt=@ENV.MTR_GALERA_TFMT transferfmt=@ENV.MTR_GALERA_TFMT
streamfmt=xbstream streamfmt=xbstream
# Not needed, but left here for debugging:
sockopt=",pf=ip6" sockopt=",pf=ip6"

View file

@ -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_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"

View file

@ -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_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"

View file

@ -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_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port' wsrep_node_incoming_address='[::1]:@mysqld.3.port'
bind-address=:: bind-address=::
[SST]
sockopt=",pf=ip6"

View file

@ -1480,9 +1480,20 @@ FROM buildings, bridges
WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1; WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
count(*) count(*)
1 1
DROP DATABASE gis_ogs;
# #
# Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE # Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE
# #
SELECT ST_Union('', ''), md5(1); SELECT ST_Union('', ''), md5(1);
ERROR HY000: Illegal parameter data type varchar for operation 'st_union' 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;

View file

@ -2,6 +2,7 @@
--source include/have_innodb.inc --source include/have_innodb.inc
-- source include/have_geometry.inc -- source include/have_geometry.inc
--source include/have_sequence.inc
SET default_storage_engine=InnoDB; SET default_storage_engine=InnoDB;
@ -1424,11 +1425,21 @@ WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
#FROM lakes #FROM lakes
#WHERE lakes.name = 'Blue Lake'; #WHERE lakes.name = 'Blue Lake';
DROP DATABASE gis_ogs;
--echo # --echo #
--echo # Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE --echo # Bug#13362660 ASSERTION `FIELD_POS < FIELD_COUNT' FAILED. IN PROTOCOL_TEXT::STORE
--echo # --echo #
--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION --error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION
SELECT ST_Union('', ''), md5(1); 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;

View file

@ -29,7 +29,9 @@ WSREP_SST_OPT_USER="${WSREP_SST_OPT_USER:-}"
WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_PSWD:-}" WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_PSWD:-}"
WSREP_SST_OPT_REMOTE_AUTH="${WSREP_SST_OPT_REMOTE_AUTH:-}" WSREP_SST_OPT_REMOTE_AUTH="${WSREP_SST_OPT_REMOTE_AUTH:-}"
WSREP_SST_OPT_DEFAULT="" WSREP_SST_OPT_DEFAULT=""
WSREP_SST_OPT_DEFAULTS=""
WSREP_SST_OPT_EXTRA_DEFAULT="" WSREP_SST_OPT_EXTRA_DEFAULT=""
WSREP_SST_OPT_EXTRA_DEFAULTS=""
WSREP_SST_OPT_SUFFIX_DEFAULT="" WSREP_SST_OPT_SUFFIX_DEFAULT=""
WSREP_SST_OPT_SUFFIX_VALUE="" WSREP_SST_OPT_SUFFIX_VALUE=""
WSREP_SST_OPT_MYSQLD="" WSREP_SST_OPT_MYSQLD=""
@ -152,10 +154,12 @@ case "$1" in
;; ;;
'--defaults-file') '--defaults-file')
readonly WSREP_SST_OPT_DEFAULT="$1=$2" readonly WSREP_SST_OPT_DEFAULT="$1=$2"
readonly WSREP_SST_OPT_DEFAULTS="$1='$2'"
shift shift
;; ;;
'--defaults-extra-file') '--defaults-extra-file')
readonly WSREP_SST_OPT_EXTRA_DEFAULT="$1=$2" readonly WSREP_SST_OPT_EXTRA_DEFAULT="$1=$2"
readonly WSREP_SST_OPT_EXTRA_DEFAULTS="$1='$2'"
shift shift
;; ;;
'--defaults-group-suffix') '--defaults-group-suffix')
@ -295,7 +299,7 @@ case "$1" in
value="$1" value="$1"
fi fi
fi fi
if [ $option == 'h' ]; then if [ $option = 'h' ]; then
if [ -z "$WSREP_SST_OPT_DATA" ]; then if [ -z "$WSREP_SST_OPT_DATA" ]; then
MYSQLD_OPT_DATADIR="${value%/}" MYSQLD_OPT_DATADIR="${value%/}"
fi fi
@ -611,24 +615,54 @@ else
MYSQLDUMP="$(command -v mysqldump)" MYSQLDUMP="$(command -v mysqldump)"
fi 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 if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults" MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
else else
MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" 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 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" wsrep_defaults="$WSREP_SST_OPT_DEFAULT"
if [ -n "$wsrep_defaults" ]; then wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT"
wsrep_defaults="$wsrep_defaults " wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
fi
wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT" readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults"
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"
# #
# User can specify mariabackup specific settings that will be used during sst # 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, # If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix: # then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then 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 if [ -n "$reval" ]; then
break break
fi fi
fi fi
# Let's try to use the group name as it is: # 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 if [ -n "$reval" ]; then
break break
fi fi
@ -710,13 +752,21 @@ in_config()
# If the group name is the same as the "mysqld" without "--" prefix, # If the group name is the same as the "mysqld" without "--" prefix,
# then try to use it together with the group suffix: # then try to use it together with the group suffix:
if [ "$group" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then 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 if [ $found -ne 0 ]; then
break break
fi fi
fi fi
# Let's try to use the group name as it is: # 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 if [ $found -ne 0 ]; then
break break
fi fi
@ -797,29 +847,6 @@ else
SST_PROGRESS_FILE="" SST_PROGRESS_FILE=""
fi 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() wsrep_cleanup_progress_file()
{ {
[ -n "$SST_PROGRESS_FILE" -a \ [ -n "$SST_PROGRESS_FILE" -a \
@ -959,6 +986,43 @@ check_sockets_utils()
fi 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 # If the ssl_dhparams variable is already set, uses that as a source
# of dh parameters for OpenSSL. Otherwise, looks for dhparams.pem in # of dh parameters for OpenSSL. Otherwise, looks for dhparams.pem in
@ -966,28 +1030,95 @@ check_sockets_utils()
# #
check_for_dhparams() check_for_dhparams()
{ {
if [ -z "$ssl_dhparams" ]; then ssl_dhparams="$DATA/dhparams.pem"
ssl_dhparams="$DATA/dhparams.pem" if [ ! -r "$ssl_dhparams" ]; then
if [ ! -r "$ssl_dhparams" ]; then get_openssl
get_openssl if [ -n "$OPENSSL_BINARY" ]; then
if [ -n "$OPENSSL_BINARY" ]; then wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams"
wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams" if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1
if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1 then
then wsrep_log_error "******** ERROR *****************************************"
wsrep_log_error "******** ERROR *****************************************" wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *"
wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *" wsrep_log_error "********************************************************"
wsrep_log_error "********************************************************"
ssl_dhparams=""
fi
else
# Rollback: if openssl is not installed, then use
# the default parameters:
ssl_dhparams="" ssl_dhparams=""
fi fi
else
# Rollback: if openssl is not installed, then use
# the default parameters:
ssl_dhparams=""
fi fi
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. # Compares two version strings.
# The first parameter is the version to be checked; # The first parameter is the version to be checked;
@ -996,22 +1127,22 @@ check_for_dhparams()
# #
check_for_version() check_for_version()
{ {
y1=${1#*.} y1="${1#*.}"
[ "$y1" = "$1" ] && y1="" [ "$y1" = "$1" ] && y1=""
z1=${y1#*.} z1=${y1#*.}
[ "$z1" = "$y1" ] && z1="" [ "$z1" = "$y1" ] && z1=""
x1=${1%%.*} x1="${1%%.*}"
y1=${y1%%.*} y1="${y1%%.*}"
z1=${z1%%.*} z1="${z1%%.*}"
[ -z "$y1" ] && y1=0 [ -z "$y1" ] && y1=0
[ -z "$z1" ] && z1=0 [ -z "$z1" ] && z1=0
y2=${2#*.} y2="${2#*.}"
[ "$y2" = "$2" ] && y2="" [ "$y2" = "$2" ] && y2=""
z2=${y2#*.} z2="${y2#*.}"
[ "$z2" = "$y2" ] && z2="" [ "$z2" = "$y2" ] && z2=""
x2=${2%%.*} x2="${2%%.*}"
y2=${y2%%.*} y2="${y2%%.*}"
z2=${z2%%.*} z2="${z2%%.*}"
[ -z "$y2" ] && y2=0 [ -z "$y2" ] && y2=0
[ -z "$z2" ] && z2=0 [ -z "$z2" ] && z2=0
[ $x1 -lt $x2 ] && return 1 [ $x1 -lt $x2 ] && return 1
@ -1021,3 +1152,127 @@ check_for_version()
[ $z1 -lt $z2 ] && return 1 [ $z1 -lt $z2 ] && return 1
return 0 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
}

View file

@ -29,13 +29,10 @@ eformat=""
ekey="" ekey=""
ekeyfile="" ekeyfile=""
encrypt=0 encrypt=0
nproc=1
ecode=0 ecode=0
ssyslog="" ssyslog=""
ssystag="" ssystag=""
MARIABACKUP_PID="" BACKUP_PID=""
SST_PORT=""
REMOTEIP=""
tcert="" tcert=""
tpem="" tpem=""
tkey="" tkey=""
@ -55,7 +52,7 @@ ib_home_dir=""
ib_log_dir="" ib_log_dir=""
ib_undo_dir="" ib_undo_dir=""
sfmt="tar" sfmt=""
strmcmd="" strmcmd=""
tfmt="" tfmt=""
tcmd="" tcmd=""
@ -79,6 +76,11 @@ compress='none'
compress_chunk="" compress_chunk=""
compress_threads="" compress_threads=""
backup_threads=""
encrypt_threads=""
encrypt_chunk=""
readonly SECRET_TAG="secret" readonly SECRET_TAG="secret"
# Required for backup locks # Required for backup locks
@ -92,12 +94,11 @@ fi
pcmd="pv $pvopts" pcmd="pv $pvopts"
declare -a RC declare -a RC
MARIABACKUP_BIN="$(command -v mariabackup)" BACKUP_BIN="$(command -v mariabackup)"
if [ ! -x "$MARIABACKUP_BIN" ]; then if [ ! -x "$BACKUP_BIN" ]; then
wsrep_log_error 'mariabackup binary not found in $PATH' wsrep_log_error 'mariabackup binary not found in path'
exit 42 exit 42
fi fi
MBSTREAM_BIN=mbstream
DATA="$WSREP_SST_OPT_DATA" DATA="$WSREP_SST_OPT_DATA"
INFO_FILE="xtrabackup_galera_info" INFO_FILE="xtrabackup_galera_info"
@ -111,7 +112,8 @@ INNOBACKUPLOG="$DATA/mariabackup.backup.log"
# Setting the path for ss and ip # Setting the path for ss and ip
export PATH="/usr/sbin:/sbin:$PATH" export PATH="/usr/sbin:/sbin:$PATH"
timeit(){ timeit()
{
local stage="$1" local stage="$1"
shift shift
local cmd="$@" local cmd="$@"
@ -201,6 +203,12 @@ get_keys()
else else
ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'" ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'"
fi 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 else
wsrep_log_error "Unknown encryption format='$eformat'" wsrep_log_error "Unknown encryption format='$eformat'"
exit 2 exit 2
@ -215,8 +223,6 @@ get_keys()
get_transfer() get_transfer()
{ {
TSST_PORT="$SST_PORT"
if [ $tfmt = 'nc' ]; then if [ $tfmt = 'nc' ]; then
wsrep_log_info "Using netcat as streamer" wsrep_log_info "Using netcat as streamer"
wsrep_check_programs nc wsrep_check_programs nc
@ -238,7 +244,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -l -p" tcmd="$tcmd -l -p"
fi fi
tcmd="$tcmd $TSST_PORT" tcmd="$tcmd $SST_PORT"
else else
# Check to see if netcat supports the '-N' flag. # Check to see if netcat supports the '-N' flag.
# -N Shutdown the network socket after EOF on stdin # -N Shutdown the network socket after EOF on stdin
@ -260,7 +266,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -q0" tcmd="$tcmd -q0"
fi fi
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT"
fi fi
else else
tfmt='socat' tfmt='socat'
@ -268,25 +274,68 @@ get_transfer()
wsrep_log_info "Using socat as streamer" wsrep_log_info "Using socat as streamer"
wsrep_check_programs socat wsrep_check_programs socat
if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then if [ -n "$sockopt" ]; then
wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)" 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 exit 2
fi fi
# Determine the socat version local action='Decrypting'
SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*') if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
if [ -z "$SOCAT_VERSION" ]; then tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
wsrep_log_error "******** FATAL ERROR ******************" else
wsrep_log_error "* Cannot determine the socat version. *" tcmd="socat -u stdio openssl-connect:$REMOTEIP:$SST_PORT"
wsrep_log_error "***************************************" action='Encrypting'
exit 2
fi fi
if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then if [ "${sockopt#*,dhparam=}" != "$sockopt" ]; then
# socat versions < 1.7.3 will have 512-bit dhparams (too small) if [ -z "$ssl_dhparams" ]; then
# so create 2048-bit dhparams and send that as a parameter: # Determine the socat version
check_for_dhparams SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
sockopt=",dhparam='$ssl_dhparams'$sockopt" 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 fi
if [ $encrypt -eq 2 ]; then if [ $encrypt -eq 2 ]; then
@ -295,52 +344,60 @@ get_transfer()
wsrep_log_error "Both PEM and CRT files required" wsrep_log_error "Both PEM and CRT files required"
exit 22 exit 22
fi fi
stagemsg="$stagemsg-OpenSSL-Encrypted-2" if [ ! -r "$tpem" -o ! -r "$tcert" ]; then
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_error "Both PEM and CRT files must be readable"
wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}" exit 22
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"
fi 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" wsrep_log_info "Using openssl based encryption with socat: with key and crt"
if [ -z "$tpem" -o -z "$tkey" ]; then if [ -z "$tpem" -o -z "$tkey" ]; then
wsrep_log_error "Both certificate and key files required" wsrep_log_error "Both certificate and key files required"
exit 22 exit 22
fi 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" stagemsg="$stagemsg-OpenSSL-Encrypted-3"
if [ -z "$tcert" ]; then if [ -z "$tcert" ]; then
# no verification if [ $encrypt -eq 4 ]; then
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_error "Peer certificate required if encrypt=4"
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" exit 22
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"
fi fi
# no verification
tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt"
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
else else
# CA verification # CA verification
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ ! -r "$tcert" ]; then
wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" wsrep_log_error "Certificate file must be readable"
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',cafile='$tcert'$sockopt stdio" exit 22
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"
fi 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 fi
else else
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
tcmd="socat -u TCP-LISTEN:$TSST_PORT,reuseaddr$sockopt stdio" exit 22
else fi
tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt"
fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="$tcmd stdio"
fi fi
fi fi
} }
@ -348,7 +405,7 @@ get_transfer()
get_footprint() get_footprint()
{ {
pushd "$WSREP_SST_OPT_DATA" 1>/dev/null 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 if [ "$compress" != 'none' ]; then
# QuickLZ has around 50% compression ratio # QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate. # When compression/compaction used, the progress is only an approximate.
@ -412,10 +469,10 @@ read_cnf()
tpem=$(parse_cnf 'sst' 'tcert') tpem=$(parse_cnf 'sst' 'tcert')
tkey=$(parse_cnf 'sst' 'tkey') tkey=$(parse_cnf 'sst' 'tkey')
fi fi
if [ "$tmode" != 'DISABLED' ] if [ "$tmode" != 'DISABLED' ]; then
then # backward-incompatible behavior # backward-incompatible behavior
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]; then
then # no old-style SSL config in [sst] # no old-style SSL config in [sst]
check_server_ssl_config check_server_ssl_config
fi fi
if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ]
@ -441,7 +498,7 @@ read_cnf()
sockopt=$(parse_cnf sst sockopt "") sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "") progress=$(parse_cnf sst progress "")
ttime=$(parse_cnf sst time 0) 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') [ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g')
cpat=$(parse_cnf sst cpat "$cpat") cpat=$(parse_cnf sst cpat "$cpat")
scomp=$(parse_cnf sst compressor "") scomp=$(parse_cnf sst compressor "")
@ -476,34 +533,38 @@ read_cnf()
compress_threads=$(parse_cnf "$encgroups" 'compress-threads') compress_threads=$(parse_cnf "$encgroups" 'compress-threads')
fi fi
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() get_stream()
{ {
if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then 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 if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
strmcmd="$MBSTREAM_BIN -x" strmcmd="'$STREAM_BIN' -x"
else else
strmcmd="$MBSTREAM_BIN -c '$INFO_FILE'" strmcmd="'$STREAM_BIN' -c '$INFO_FILE'"
fi fi
else else
sfmt="tar" sfmt='tar'
wsrep_log_info "Streaming with tar" if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]]; then strmcmd='tar xfi -'
strmcmd="tar xfi -"
else else
strmcmd="tar cf - '$INFO_FILE'" strmcmd="tar cf - '$INFO_FILE'"
fi fi
fi fi
} wsrep_log_info "Streaming with $sfmt"
get_proc()
{
set +e
nproc=$(grep -c processor /proc/cpuinfo)
[ -z $nproc -o $nproc -eq 0 ] && nproc=1
set -e
} }
sig_joiner_cleanup() sig_joiner_cleanup()
@ -512,65 +573,27 @@ sig_joiner_cleanup()
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
} }
cleanup_joiner() cleanup_at_exit()
{ {
# Since this is invoked just after exit NNN # Since this is invoked just after exit NNN
local estatus=$? local estatus=$?
if [ $estatus -ne 0 ]; then if [ $estatus -ne 0 ]; then
wsrep_log_error "Cleanup after exit with status:$estatus" 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_log_info "Removing the sst_in_progress file"
wsrep_cleanup_progress_file wsrep_cleanup_progress_file
fi else
if [ -n "$progress" -a -p "$progress" ]; then if [ -n "$BACKUP_PID" ]; then
wsrep_log_info "Cleaning up fifo file $progress" if check_pid "$BACKUP_PID" 1; then
rm "$progress" wsrep_log_error "mariabackup process is still running. Killing..."
fi cleanup_pid $CHECK_PID "$BACKUP_PID"
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
fi fi
[ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
fi 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 if [ -n "$progress" -a -p "$progress" ]; then
wsrep_log_info "Cleaning up fifo file $progress" wsrep_log_info "Cleaning up fifo file $progress"
rm -f "$progress" || true rm -f "$progress" || true
@ -578,8 +601,14 @@ cleanup_donor()
wsrep_log_info "Cleaning up temporary directories" wsrep_log_info "Cleaning up temporary directories"
[ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
[ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true 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 # Final cleanup
pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') pgid=$(ps -o pgid= $$ | grep -o '[0-9]*')
@ -590,21 +619,13 @@ cleanup_donor()
# This means a signal was delivered to the process. # This means a signal was delivered to the process.
# So, more cleanup. # So, more cleanup.
if [ $estatus -ge 128 ]; then if [ $estatus -ge 128 ]; then
kill -KILL -$$ || true kill -KILL -- -$$ || true
fi fi
fi fi
exit $estatus 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() setup_ports()
{ {
SST_PORT="$WSREP_SST_OPT_PORT" SST_PORT="$WSREP_SST_OPT_PORT"
@ -615,51 +636,17 @@ setup_ports()
fi fi
} }
check_port() #
{ # Waits ~30 seconds for socat or nc to open the port and
local PORT="$1" # then reports ready, regardless of timeout.
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)
wait_for_listen() wait_for_listen()
{ {
local PORT="$1" local PORT="$1"
local ADDR="$2" local ADDR="$2"
local MODULE="$3" local MODULE="$3"
for i in {1..150}; do
for i in {1..50} if check_port "" "$PORT" 'socat|nc'; then
do
if check_port "$PORT" 'socat|nc'
then
break break
fi fi
sleep 0.2 sleep 0.2
@ -675,8 +662,8 @@ check_extra()
if [ "$thread_handling" = 'pool-of-threads' ]; then if [ "$thread_handling" = 'pool-of-threads' ]; then
local eport=$(parse_cnf '--mysqld' 'extra-port') local eport=$(parse_cnf '--mysqld' 'extra-port')
if [ -n "$eport" ]; then if [ -n "$eport" ]; then
# mariabackup works only locally, hence, # mariabackup works only locally.
# setting host to 127.0.0.1 unconditionally: # Hence, setting host to 127.0.0.1 unconditionally:
wsrep_log_info "SST through extra_port $eport" wsrep_log_info "SST through extra_port $eport"
INNOEXTRA="$INNOEXTRA --host=127.0.0.1 --port=$eport" INNOEXTRA="$INNOEXTRA --host=127.0.0.1 --port=$eport"
use_socket=0 use_socket=0
@ -792,30 +779,29 @@ monitor_process()
local sst_stream_pid=$1 local sst_stream_pid=$1
while true ; do 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." wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
kill -- -"$WSREP_SST_OPT_PARENT"
exit 32 exit 32
fi fi
if ! ps -p "$sst_stream_pid" &>/dev/null; then if ! ps -p "$sst_stream_pid" >/dev/null 2>&1; then
break break
fi fi
sleep 0.1 sleep 0.1
done done
} }
wsrep_check_programs "$MARIABACKUP_BIN"
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then 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 exit 22
fi fi
read_cnf read_cnf
setup_ports 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' disver='--no-version-check'
fi fi
@ -838,7 +824,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P)
cd "$OLD_PWD" cd "$OLD_PWD"
if [ $ssyslog -eq 1 ]; then if [ $ssyslog -eq 1 ]; then
if [ -n "$(command -v logger)" ]; then if [ -n "$(command -v logger)" ]; then
wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" wsrep_log_info "Logging all stderr of SST/mariabackup to syslog"
@ -856,70 +841,65 @@ if [ $ssyslog -eq 1 ]; then
else else
wsrep_log_error "logger not in path: $PATH. Ignoring" wsrep_log_error "logger not in path: $PATH. Ignoring"
fi fi
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply"
INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move"
INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
else else
if [ $sstlogarchive -eq 1 ]
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" ]
then then
if [ -n "$sstlogarchivedir" ] ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
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
if [ -e "$INNOMOVELOG" ] if [ -n "$sstlogarchivedir" ]; then
then if [ ! -d "$sstlogarchivedir" ]; then
if [ -n "$sstlogarchivedir" ] mkdir -p "$sstlogarchivedir"
then fi
newfile=$(basename "$INNOMOVELOG")
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
fi fi
wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
mv "$INNOMOVELOG" "$newfile"
gzip "$newfile"
fi
if [ -e "$INNOBACKUPLOG" ] if [ -e "$INNOAPPLYLOG" ]
then
if [ -n "$sstlogarchivedir" ]
then then
newfile=$(basename "$INNOBACKUPLOG") if [ -n "$sstlogarchivedir" ]
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" then
else newfile=$(basename "$INNOAPPLYLOG")
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
fi
wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
mv "$INNOAPPLYLOG" "$newfile"
gzip "$newfile"
fi fi
wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
mv "$INNOBACKUPLOG" "$newfile"
gzip "$newfile"
fi
fi
INNOAPPLY="&> '$INNOAPPLYLOG'" if [ -e "$INNOMOVELOG" ]
INNOMOVE="&> '$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'" INNOBACKUP="2> '$INNOBACKUPLOG'"
fi fi
setup_commands() setup_commands()
@ -928,9 +908,9 @@ setup_commands()
if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then
mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD"
fi fi
INNOAPPLY="$MARIABACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" INNOAPPLY="$BACKUP_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" INNOMOVE="$BACKUP_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" 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 get_stream
@ -938,7 +918,7 @@ get_transfer
if [ "$WSREP_SST_OPT_ROLE" = 'donor' ] if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
then then
trap cleanup_donor EXIT trap cleanup_at_exit EXIT
if [ $WSREP_SST_OPT_BYPASS -eq 0 ] if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then then
@ -951,12 +931,15 @@ then
tmpdir=$(parse_cnf "$encgroups" 'tmpdir') tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
if [ -z "$tmpdir" ]; then if [ -z "$tmpdir" ]; then
xtmpdir="$(mktemp -d)" xtmpdir="$(mktemp -d)"
tmpopts="--tmpdir='$xtmpdir'" else
wsrep_log_info "Using $xtmpdir as mariabackup temporary directory" xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
fi fi
wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
tmpopts="--tmpdir='$xtmpdir'"
itmpdir="$(mktemp -d)" itmpdir="$(mktemp -d)"
wsrep_log_info "Using $itmpdir as mariabackup temporary directory" wsrep_log_info "Using '$itmpdir' as mariabackup working directory"
usrst=0 usrst=0
if [ -n "$WSREP_SST_OPT_USER" ]; then if [ -n "$WSREP_SST_OPT_USER" ]; then
@ -997,9 +980,9 @@ then
send_donor "$DATA" "$stagemsg-gtid" send_donor "$DATA" "$stagemsg-gtid"
# Restore the transport commmand to its original state
tcmd="$ttcmd" tcmd="$ttcmd"
# Restore the transport commmand to its original state
if [ -n "$progress" ]; then if [ -n "$progress" ]; then
get_footprint get_footprint
tcmd="$pcmd | $tcmd" tcmd="$pcmd | $tcmd"
@ -1011,7 +994,7 @@ then
wsrep_log_info "Sleeping before data transfer for SST" wsrep_log_info "Sleeping before data transfer for SST"
sleep 10 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) # Add compression to the head of the stream (if specified)
if [ -n "$scomp" ]; then if [ -n "$scomp" ]; then
@ -1023,33 +1006,37 @@ then
tcmd="$ecmd | $tcmd" tcmd="$ecmd | $tcmd"
fi fi
iopts="$iopts --databases-exclude='lost+found'" iopts="--databases-exclude='lost+found' $iopts"
if [ ${FORCE_FTWRL:-0} -eq 1 ]; then if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
iopts="$iopts --no-backup-locks" iopts="--no-backup-locks $iopts"
fi fi
# if compression is enabled for backup files, then add the # if compression is enabled for backup files, then add the
# appropriate options to the mariabackup command line: # appropriate options to the mariabackup command line:
if [ "$compress" != 'none' ]; then if [ "$compress" != 'none' ]; then
iopts="$iopts --compress${compress:+=$compress}" iopts="--compress${compress:+=$compress} $iopts"
if [ -n "$compress_threads" ]; then if [ -n "$compress_threads" ]; then
iopts="$iopts --compress-threads=$compress_threads" iopts="--compress-threads=$compress_threads $iopts"
fi fi
if [ -n "$compress_chunk" ]; then if [ -n "$compress_chunk" ]; then
iopts="$iopts --compress-chunk-size=$compress_chunk" iopts="--compress-chunk-size=$compress_chunk $iopts"
fi fi
fi fi
if [ -n "$backup_threads" ]; then
iopts="--parallel=$backup_threads $iopts"
fi
setup_commands setup_commands
set +e set +e
timeit "$stagemsg-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )" timeit "$stagemsg-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
set -e set -e
if [ ${RC[0]} -ne 0 ]; then if [ ${RC[0]} -ne 0 ]; then
wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \ wsrep_log_error "mariabackup finished with error: ${RC[0]}. " \
"Check syslog or ${INNOBACKUPLOG} for details" "Check syslog or '$INNOBACKUPLOG' for details"
exit 22 exit 22
elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then
wsrep_log_error "$tcmd finished with error: ${RC[1]}" wsrep_log_error "$tcmd finished with error: ${RC[1]}"
@ -1057,7 +1044,7 @@ then
fi fi
# mariabackup implicitly writes PID to fixed location in $xtmpdir # mariabackup implicitly writes PID to fixed location in $xtmpdir
MARIABACKUP_PID="$xtmpdir/xtrabackup_pid" BACKUP_PID="$xtmpdir/xtrabackup_pid"
else # BYPASS FOR IST else # BYPASS FOR IST
@ -1109,6 +1096,10 @@ then
ib_undo_dir="$INNODB_UNDO_DIR" ib_undo_dir="$INNODB_UNDO_DIR"
if [ -n "$backup_threads" ]; then
impts="--parallel=$backup_threads $impts"
fi
stagemsg='Joiner-Recv' stagemsg='Joiner-Recv'
sencrypted=1 sencrypted=1
@ -1148,7 +1139,7 @@ then
fi fi
trap sig_joiner_cleanup HUP PIPE INT TERM trap sig_joiner_cleanup HUP PIPE INT TERM
trap cleanup_joiner EXIT trap cleanup_at_exit EXIT
if [ -n "$progress" ]; then if [ -n "$progress" ]; then
adjust_progress adjust_progress
@ -1171,7 +1162,7 @@ then
recv_joiner "$STATDIR" "$stagemsg-gtid" $stimeout 1 1 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 then
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly." wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
exit 32 exit 32
@ -1181,7 +1172,7 @@ then
then then
if [ -d "$DATA/.sst" ]; 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" rm -rf "$DATA/.sst"
fi fi
mkdir -p "$DATA/.sst" mkdir -p "$DATA/.sst"
@ -1291,37 +1282,37 @@ then
fi fi
wsrep_log_info "Preparing the backup at ${DATA}" wsrep_log_info "Preparing the backup at $DATA"
setup_commands setup_commands
timeit "mariabackup prepare stage" "$INNOAPPLY" timeit "mariabackup prepare stage" "$INNOAPPLY"
if [ $? -ne 0 ]; then 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 exit 22
fi fi
MAGIC_FILE="$TDATA/$INFO_FILE" 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 if [ $? -eq 0 ]; then
wsrep_log_info "Move successful, removing ${DATA}" wsrep_log_info "Move successful, removing $DATA"
rm -rf "$DATA" rm -rf "$DATA"
DATA="$TDATA" DATA="$TDATA"
else else
wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" wsrep_log_error "Move failed, keeping '$DATA' for further diagnosis"
wsrep_log_error "Check syslog or ${INNOMOVELOG} for details" wsrep_log_error "Check syslog or '$INNOMOVELOG' for details"
exit 22 exit 22
fi fi
else else
wsrep_log_info "${IST_FILE} received from donor: Running IST" wsrep_log_info "'$IST_FILE' received from donor: Running IST"
fi fi
if [ ! -r "$MAGIC_FILE" ]; then 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 exit 2
fi fi

View file

@ -103,7 +103,7 @@ then
DROP PREPARE stmt;" DROP PREPARE stmt;"
fi fi
MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\
"$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
@ -140,7 +140,7 @@ then
fi fi
# NOTE: we don't use --routines here because we're dumping mysql.proc table # 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 \ --add-drop-database --add-drop-table --skip-add-locks --create-options \
--disable-keys --extended-insert --skip-lock-tables --quick --set-charset \ --disable-keys --extended-insert --skip-lock-tables --quick --set-charset \
--skip-comments --flush-privileges --all-databases --events" --skip-comments --flush-privileges --all-databases --events"

View file

@ -1,7 +1,7 @@
#!/bin/bash -ue #!/bin/bash -ue
# Copyright (C) 2010-2014 Codership Oy
# Copyright (C) 2017-2021 MariaDB # Copyright (C) 2017-2021 MariaDB
# Copyright (C) 2010-2014 Codership Oy
# #
# This program is free software; you can redistribute it and/or modify # 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 # 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 # This is a reference script for rsync-based state snapshot tansfer
RSYNC_PID= # rsync pid file RSYNC_REAL_PID=0 # rsync process id
RSYNC_CONF= # rsync configuration file STUNNEL_REAL_PID=0 # stunnel process id
RSYNC_REAL_PID= # rsync process id
OS="$(uname)" OS="$(uname)"
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
@ -36,95 +35,95 @@ wsrep_check_programs rsync
cleanup_joiner() cleanup_joiner()
{ {
wsrep_log_info "Joiner cleanup. rsync PID: $RSYNC_REAL_PID" local failure=0
[ "0" != "$RSYNC_REAL_PID" ] && \
kill $RSYNC_REAL_PID && \ wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID"
sleep 0.5 && \
kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || : if [ -n "$STUNNEL" ]; then
[ -f "$RSYNC_CONF" ] && rm -f "$RSYNC_CONF" if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF" if [ $RSYNC_REAL_PID -eq 0 ]; then
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID" if [ -r "$RSYNC_PID" ]; then
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null)
[ -f "$RSYNC_PID" ] && rm -f "$RSYNC_PID" 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." wsrep_log_info "Joiner cleanup done."
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_cleanup_progress_file wsrep_cleanup_progress_file
fi 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() check_pid_and_port()
{ {
local pid_file="$1" local pid_file="$1"
local rsync_pid=$2 local pid=$2
local rsync_addr="$3" local addr="$3"
local rsync_port="$4" local port="$4"
if [ -z "$rsync_port" -o -z "$rsync_addr" -o -z "$rsync_pid" ]; then local utils='rsync|stunnel'
wsrep_log_error "check_pid_and_port(): bad arguments"
exit 2 # ENOENT
fi
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 if [ $lsof_available -ne 0 ]; then
is_listening_all=$(echo "$port_info" | \ port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port[[:space:]]") grep -F '(LISTEN)')
echo "$port_info" | \
grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1
else else
if [ $sockstat_available -eq 0 ]; then local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+'
port_info=$(echo "$port_info" | grep -q -F 'users:(') 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 fi
port_info=$(echo "$port_info" | \ echo "$port_info" | \
grep -E "[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+" -o) grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port\$" && busy=1
is_listening_all=$(echo "$port_info" | \
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port\$")
fi fi
local is_listening_addr=$(echo "$port_info" | \
grep -w -F -- "$rsync_addr:$rsync_port") if [ $busy -eq 0 ]; then
if [ -z "$is_listening_addr" ]; then if echo "$port_info" | grep -qw -F "[$addr]:$port" || \
is_listening_addr=$(echo "$port_info" | \ echo "$port_info" | grep -qw -F -- "$addr:$port"
grep -w -F "[$rsync_addr]:$rsync_port") then
busy=1
fi
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" "has been taken by another program"
exit 16 # EBUSY exit 16 # EBUSY
fi fi
return 1
fi 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_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid" STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete" MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
@ -201,6 +200,8 @@ FILTER="-f '- /lost+found'
-f '- /.zfs' -f '- /.zfs'
-f '- /.fseventsd' -f '- /.fseventsd'
-f '- /.Trashes' -f '- /.Trashes'
-f '- /.pid'
-f '- /.conf'
-f '+ /wsrep_sst_binlog.tar' -f '+ /wsrep_sst_binlog.tar'
-f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
-f '- $INNODB_DATA_HOME_DIR/ibdata*' -f '- $INNODB_DATA_HOME_DIR/ibdata*'
@ -250,19 +251,31 @@ else
CAFILE_OPT="" CAFILE_OPT=""
fi fi
VERIFY_OPT=""
CHECK_OPT=""
CHECK_OPT_LOCAL=""
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ] if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
then then
case "$SSLMODE" in case "$SSLMODE" in
'VERIFY_IDENTITY') 'VERIFY_IDENTITY')
VERIFY_OPT='verifyPeer = yes' VERIFY_OPT='verifyPeer = yes'
CHECK_OPT=""
;; ;;
'VERIFY_CA') 'VERIFY_CA')
VERIFY_OPT='verifyChain = yes' VERIFY_OPT='verifyChain = yes'
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CHECK_OPT='checkHost = localhost' CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
else 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 fi
;; ;;
*) *)
@ -273,9 +286,6 @@ then
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file" wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file"
exit 22 # EINVAL exit 22 # EINVAL
fi fi
else
VERIFY_OPT=""
CHECK_OPT=""
fi fi
STUNNEL="" STUNNEL=""
@ -294,10 +304,10 @@ then
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE" [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE" [ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
if [ -n "$STUNNEL" ] if [ -n "$STUNNEL" ]
then then
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
cat << EOF > "$STUNNEL_CONF" cat << EOF > "$STUNNEL_CONF"
key = $SSTKEY key = $SSTKEY
cert = $SSTCERT cert = $SSTCERT
@ -310,7 +320,10 @@ connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT
TIMEOUTclose = 0 TIMEOUTclose = 0
${VERIFY_OPT} ${VERIFY_OPT}
${CHECK_OPT} ${CHECK_OPT}
${CHECK_OPT_LOCAL}
EOF EOF
else
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
fi fi
if [ $WSREP_SST_OPT_BYPASS -eq 0 ] if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
@ -319,13 +332,8 @@ EOF
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed" FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
ERROR="$WSREP_SST_OPT_DATA/sst_error" ERROR="$WSREP_SST_OPT_DATA/sst_error"
rm -rf "$FLUSHED" [ -f "$FLUSHED" ] && rm -f "$FLUSHED"
rm -rf "$ERROR" [ -f "$ERROR" ] && rm -f "$ERROR"
# Use deltaxfer only for WAN
inv=$(basename "$0")
[ "$inv" = "wsrep_sst_rsync_wan" ] && WHOLE_FILE_OPT="" \
|| WHOLE_FILE_OPT="--whole-file"
echo "flush tables" echo "flush tables"
@ -340,15 +348,14 @@ EOF
if [ -f "$ERROR" ] if [ -f "$ERROR" ]
then then
# Flush tables operation failed. # Flush tables operation failed.
rm -rf "$ERROR" rm -f "$ERROR"
exit 255 exit 255
fi fi
sleep 0.2 sleep 0.2
done done
STATE=$(cat "$FLUSHED") STATE=$(cat "$FLUSHED")
rm -rf "$FLUSHED" rm -f "$FLUSHED"
sync sync
@ -375,6 +382,13 @@ EOF
cd "$OLD_PWD" cd "$OLD_PWD"
fi 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 # first, the normal directories, so that we can detect incompatible protocol
RC=0 RC=0
eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \ eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \
@ -426,16 +440,18 @@ EOF
fi fi
# then, we parallelize the transfer of database directories, # 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" cd "$WSREP_SST_OPT_DATA"
count=1 backup_threads=$(parse_cnf "--mysqld|sst" 'backup-threads')
[ "$OS" = 'Linux' ] && count=$(grep -c processor /proc/cpuinfo) if [ -z "$backup_threads" ]; then
[ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ] && count=$(sysctl -n hw.ncpu) get_proc
backup_threads=$nproc
fi
find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ 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"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \ --ignore-times --inplace --recursive --delete --quiet \
@ -474,35 +490,52 @@ EOF
echo "done $STATE" 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' ] elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then then
check_sockets_utils check_sockets_utils
touch "$SST_PROGRESS_FILE" # give some time for lingering stunnel from previous SST to complete
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
check_round=0 check_round=0
while check_pid "$RSYNC_PID" && [ $check_round -lt 10 ] while check_pid "$STUNNEL_PID" 1
do 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 )) check_round=$(( check_round + 1 ))
if [ $check_round -eq 10 ]; then
wsrep_log_error "stunnel daemon already running."
exit 114 # EALREADY
fi
sleep 1 sleep 1
done done
if check_pid "$RSYNC_PID" MODULE="rsync_sst"
then RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
wsrep_log_error "rsync daemon already running." RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
exit 114 # EALREADY
fi # 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 "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_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" ADDR="$WSREP_SST_OPT_ADDR"
RSYNC_PORT="$WSREP_SST_OPT_PORT" RSYNC_PORT="$WSREP_SST_OPT_PORT"
RSYNC_ADDR="$WSREP_SST_OPT_HOST" RSYNC_ADDR="$WSREP_SST_OPT_HOST"
@ -512,7 +545,7 @@ then
trap "exit 3" INT TERM ABRT trap "exit 3" INT TERM ABRT
trap cleanup_joiner EXIT trap cleanup_joiner EXIT
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf" touch "$SST_PROGRESS_FILE"
if [ -n "${MYSQL_TMP_DIR:-}" ]; then if [ -n "${MYSQL_TMP_DIR:-}" ]; then
SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log" SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
@ -535,18 +568,18 @@ $SILENT
path = $INNODB_DATA_HOME_DIR path = $INNODB_DATA_HOME_DIR
EOF 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" if is_local_ip "$RSYNC_ADDR_UNESCAPED"
then then
RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED" RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED"
STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT" STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT"
else else
# Not local, possibly a NAT, listen on all interfaces # Not local, possibly a NAT, listen on all interfaces:
RSYNC_EXTRA_ARGS="" RSYNC_EXTRA_ARGS=""
STUNNEL_ACCEPT="$RSYNC_PORT" STUNNEL_ACCEPT="$RSYNC_PORT"
# Overwrite address with all # Overwrite address with all:
RSYNC_ADDR="*" RSYNC_ADDR="*"
fi fi
@ -554,8 +587,9 @@ EOF
then then
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
RSYNC_REAL_PID=$! RSYNC_REAL_PID=$!
TRANSFER_REAL_PID="$RSYNC_REAL_PID"
TRANSFER_PID=$RSYNC_PID
else else
[ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
# Let's check if the path to the config file contains a space? # Let's check if the path to the config file contains a space?
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
cat << EOF > "$STUNNEL_CONF" cat << EOF > "$STUNNEL_CONF"
@ -566,6 +600,9 @@ foreground = yes
pid = $STUNNEL_PID pid = $STUNNEL_PID
debug = warning debug = warning
client = no client = no
${VERIFY_OPT}
${CHECK_OPT}
${CHECK_OPT_LOCAL}
[rsync] [rsync]
accept = $STUNNEL_ACCEPT accept = $STUNNEL_ACCEPT
exec = $(command -v rsync) exec = $(command -v rsync)
@ -583,6 +620,9 @@ foreground = yes
pid = $STUNNEL_PID pid = $STUNNEL_PID
debug = warning debug = warning
client = no client = no
${VERIFY_OPT}
${CHECK_OPT}
${CHECK_OPT_LOCAL}
[rsync] [rsync]
accept = $STUNNEL_ACCEPT accept = $STUNNEL_ACCEPT
exec = $SHELL exec = $SHELL
@ -590,15 +630,11 @@ execargs = $SHELL -c \$RSYNC_CMD
EOF EOF
fi fi
stunnel "$STUNNEL_CONF" & stunnel "$STUNNEL_CONF" &
RSYNC_REAL_PID=$! STUNNEL_REAL_PID=$!
RSYNC_PID="$STUNNEL_PID" TRANSFER_REAL_PID="$STUNNEL_REAL_PID"
TRANSFER_PID=$STUNNEL_PID
fi 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" ] if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
then # backward-incompatible behavior then # backward-incompatible behavior
CN="" CN=""
@ -619,19 +655,26 @@ EOF
ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST" ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST"
else else
MY_SECRET="" # for check down in recv_joiner() MY_SECRET="" # for check down in recv_joiner()
ADDR=$WSREP_SST_OPT_HOST ADDR="$WSREP_SST_OPT_HOST"
fi 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" echo "ready $ADDR:$RSYNC_PORT/$MODULE"
MYSQLD_PID="$WSREP_SST_OPT_PARENT"
# wait for SST to complete by monitoring magic file # wait for SST to complete by monitoring magic file
while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \ while [ ! -r "$MAGIC_FILE" ] && check_pid "$TRANSFER_PID" && \
ps -p $MYSQLD_PID >/dev/null ps -p $MYSQLD_PID >/dev/null 2>&1
do do
sleep 1 sleep 1
done done
if ! ps -p $MYSQLD_PID >/dev/null if ! ps -p $MYSQLD_PID >/dev/null 2>&1
then then
wsrep_log_error \ wsrep_log_error \
"Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly." "Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly."
@ -682,7 +725,7 @@ EOF
echo "rsync process ended without creating '$MAGIC_FILE'" echo "rsync process ended without creating '$MAGIC_FILE'"
fi fi
wsrep_cleanup_progress_file # wsrep_cleanup_progress_file
# cleanup_joiner # cleanup_joiner
else else
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'" wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"

View file

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2005, 2019, Oracle and/or its affiliates. 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 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 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 Handle delete and rename table

View file

@ -3,7 +3,7 @@
/* /*
Copyright (c) 2005, 2012, Oracle and/or its affiliates. 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 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 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 Meta data routines to CREATE, DROP, RENAME table and often used at
ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..). 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 create_partitioning_metadata is called before opening a new handler object
with openfrm to call create. It is used to create any local handler with openfrm to call create. It is used to create any local handler
object needed in opening the object in openfrm object needed in opening the object in openfrm
@ -535,7 +531,6 @@ public:
virtual int create_partitioning_metadata(const char *name, virtual int create_partitioning_metadata(const char *name,
const char *old_name, int action_flag); const char *old_name, int action_flag);
virtual void update_create_info(HA_CREATE_INFO *create_info); 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, virtual int change_partitions(HA_CREATE_INFO *create_info,
const char *path, const char *path,
ulonglong * const copied, ulonglong * const copied,

View file

@ -3729,8 +3729,6 @@ public:
/* end of the list of admin commands */ /* end of the list of admin commands */
virtual int indexes_are_disabled(void) {return 0;} 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) {} virtual void append_create_info(String *packet) {}
/** /**
If index == MAX_KEY then a check for table is made and if index < If index == MAX_KEY then a check for table is made and if index <

View file

@ -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)); DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
DEBUG_SYNC(thd, "admin_command_kill_before_modify"); DEBUG_SYNC(thd, "admin_command_kill_before_modify");
if (thd->is_killed())
break;
strxmov(table_name, db, ".", table->table_name.str, NullS); strxmov(table_name, db, ".", table->table_name.str, NullS);
thd->open_options|= extra_open_options; thd->open_options|= extra_open_options;
table->lock_type= lock_type; 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 : lock_type >= TL_WRITE_ALLOW_WRITE
? MDL_SHARED_WRITE : MDL_SHARED_READ); ? 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 */ /* open only one table from local list of command */
while (1) while (1)
{ {

View file

@ -9129,6 +9129,23 @@ int dynamic_column_error_message(enum_dyncol_func_result rc)
return 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) @} (end of group Data_Dictionary)
*/ */

View file

@ -512,6 +512,8 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables,
Prelocking_strategy *prelocking_strategy, Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list); bool has_prelocking_list);
void promote_select_describe_flag_if_needed(LEX *lex);
/** /**
A context of open_tables() function, used to recover A context of open_tables() function, used to recover
from a failed open_table() or open_routine() attempt. from a failed open_table() or open_routine() attempt.

View file

@ -328,6 +328,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
query_plan.table= table; query_plan.table= table;
query_plan.updating_a_view= MY_TEST(table_list->view); 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, if (mysql_prepare_delete(thd, table_list, select_lex->with_wild,
select_lex->item_list, &conds, select_lex->item_list, &conds,
&delete_while_scanning)) &delete_while_scanning))

View file

@ -399,6 +399,8 @@ int mysql_update(THD *thd,
want_privilege= (table_list->view ? UPDATE_ACL : want_privilege= (table_list->view ? UPDATE_ACL :
table_list->grant.want_privilege); table_list->grant.want_privilege);
#endif #endif
promote_select_describe_flag_if_needed(thd->lex);
if (mysql_prepare_update(thd, table_list, &conds, order_num, order)) if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
DBUG_RETURN(1); DBUG_RETURN(1);

View file

@ -60,12 +60,12 @@ int Xcurl(PGLOBAL g, PCSZ Http, PCSZ Uri, PCSZ filename)
if (Uri) { if (Uri) {
if (*Uri == '/' || Http[strlen(Http) - 1] == '/') if (*Uri == '/' || Http[strlen(Http) - 1] == '/')
sprintf(buf, "%s%s", Http, Uri); my_snprintf(buf, sizeof(buf)-1, "%s%s", Http, Uri);
else else
sprintf(buf, "%s/%s", Http, Uri); my_snprintf(buf, sizeof(buf)-1, "%s/%s", Http, Uri);
} else } else
strcpy(buf, Http); my_snprintf(buf, sizeof(buf)-1, "%s", Http);
#if defined(__WIN__) #if defined(__WIN__)
char cmd[1024]; char cmd[1024];

View file

@ -14974,70 +14974,6 @@ ha_innobase::check(
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT); 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. 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 @return own: character string in the form which can be inserted to the

View file

@ -219,7 +219,6 @@ public:
int rename_table(const char* from, const char* to); int rename_table(const char* from, const char* to);
inline int defragment_table(const char* name); inline int defragment_table(const char* name);
int check(THD* thd, HA_CHECK_OPT* check_opt); int check(THD* thd, HA_CHECK_OPT* check_opt);
char* update_table_comment(const char* comment);
char* get_foreign_key_create_info(); char* get_foreign_key_create_info();

View file

@ -149,6 +149,76 @@ row_sel_sec_rec_is_for_blob(
return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len)); 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 /** Returns TRUE if the user-defined column values in a secondary index record
are alphabetically the same as the corresponding columns in the clustered are alphabetically the same as the corresponding columns in the clustered
index record. index record.
@ -176,20 +246,6 @@ row_sel_sec_rec_is_for_clust_rec(
dict_index_t* clust_index, dict_index_t* clust_index,
que_thr_t* thr) 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, if (rec_get_deleted_flag(clust_rec,
dict_table_is_comp(clust_index->table))) { dict_table_is_comp(clust_index->table))) {
/* In delete-marked records, DB_TRX_ID must /* In delete-marked records, DB_TRX_ID must
@ -203,7 +259,27 @@ row_sel_sec_rec_is_for_clust_rec(
return DB_SUCCESS; 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); ib_vcol_row vc(heap);
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, 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 (0 != cmp_data_data(col->mtype, col->prtype,
if the MBR is equal or not. */ clust_field, len,
if (dict_index_is_spatial(sec_index) && i == 0) { sec_field, sec_len)) {
rtr_mbr_t tmp_mbr; return DB_SUCCESS;
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;
}
} }
} }