diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 4c98c80cb52..586c4fdf2d9 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -140,6 +140,7 @@ char xtrabackup_real_incremental_basedir[FN_REFLEN]; char xtrabackup_real_extra_lsndir[FN_REFLEN]; char xtrabackup_real_incremental_dir[FN_REFLEN]; + char *xtrabackup_tmpdir; char *xtrabackup_tables; @@ -333,6 +334,9 @@ const char *opt_history = NULL; my_bool opt_ssl_verify_server_cert = FALSE; #endif +char mariabackup_exe[FN_REFLEN]; +char orig_argv1[FN_REFLEN]; + /* Whether xtrabackup_binlog_info should be created on recovery */ static bool recover_binlog_info; @@ -349,6 +353,11 @@ xtrabackup_add_datasink(ds_ctxt_t *ds) datasinks[actual_datasinks] = ds; actual_datasinks++; } + +typedef void (*process_single_tablespace_func_t)(const char *dirname, const char *filname, bool is_remote); +static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback); + + /* ======== Datafiles iterator ======== */ struct datafiles_iter_t { fil_system_t *system; @@ -1124,6 +1133,108 @@ debug_sync_point(const char *name) #endif } + +static std::vector tables_for_export; + +static void append_export_table(const char *dbname, const char *tablename, bool is_remote) +{ + if(dbname && tablename && !is_remote) + { + char buf[3*FN_REFLEN]; + char db_utf8[FN_REFLEN]; + char table_utf8[FN_REFLEN]; + + snprintf(buf,sizeof(buf),"%s/%s",dbname, tablename); + // trim .ibd + char *p=strrchr(buf, '.'); + if (p) *p=0; + + dict_fs2utf8(buf, db_utf8, sizeof(db_utf8),table_utf8,sizeof(table_utf8)); + snprintf(buf,sizeof(buf),"`%s`.`%s`",db_utf8,table_utf8); + tables_for_export.push_back(buf); + } +} + + +#define BOOTSTRAP_FILENAME "mariabackup_prepare_for_export.sql" + +static int create_bootstrap_file() +{ + FILE *f= fopen(BOOTSTRAP_FILENAME,"wb"); + if(!f) + return -1; + + fputs("SET NAMES UTF8;\n",f); + enumerate_ibd_files(append_export_table); + for (size_t i= 0; i < tables_for_export.size(); i++) + { + const char *tab = tables_for_export[i].c_str(); + fprintf(f, + "BEGIN NOT ATOMIC " + "DECLARE CONTINUE HANDLER FOR NOT FOUND,SQLEXCEPTION BEGIN END;" + "FLUSH TABLES %s FOR EXPORT;" + "END;\n" + "UNLOCK TABLES;\n", + tab); + } + fclose(f); + return 0; +} + +static int prepare_export() +{ + int err= -1; + + char cmdline[2*FN_REFLEN]; + FILE *outf; + + if (create_bootstrap_file()) + return -1; + + // Process defaults-file , it can have some --lc-language stuff, + // which is* unfortunately* still necessary to get mysqld up + if (strncmp(orig_argv1,"--defaults-file=",16) == 0) + { + sprintf(cmdline, + IF_WIN("\"","") "\"%s\" --mysqld \"%s\" --defaults-group-suffix=%s" + " --defaults-extra-file=./backup-my.cnf --datadir=." + " --innodb --innodb-fast-shutdown=0" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + mariabackup_exe, + orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""), + xtrabackup_use_memory); + } + else + { + sprintf(cmdline, + IF_WIN("\"","") "\"%s\" --mysqld" + " --defaults-file=./backup-my.cnf --datadir=." + " --innodb --innodb-fast-shutdown=0" + " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" + " --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + mariabackup_exe, + xtrabackup_use_memory); + } + + msg("Prepare export : executing %s\n", cmdline); + fflush(stderr); + + outf= popen(cmdline,"r"); + if (!outf) + goto end; + + char outline[FN_REFLEN]; + while(fgets(outline, sizeof(outline)-1, outf)) + fprintf(stderr,"%s",outline); + + err = pclose(outf); +end: + unlink(BOOTSTRAP_FILENAME); + return err; +} + + static const char *xb_client_default_groups[]= { "xtrabackup", "client", 0, 0, 0 }; @@ -2518,6 +2629,7 @@ xb_new_datafile(const char *name, bool is_remote) } } + static void xb_load_single_table_tablespace( @@ -2579,7 +2691,7 @@ xb_load_single_table_tablespace( ut_a(space != NULL); - if (!fil_node_create(file->filepath(), n_pages, space, + if (!fil_node_create(file->filepath(), ulint(n_pages), space, false, false)) { ut_error; } @@ -2608,9 +2720,8 @@ xb_load_single_table_tablespace( /** Scan the database directories under the MySQL datadir, looking for .ibd files and determining the space id in each of them. @return DB_SUCCESS or error number */ -static -dberr_t -xb_load_single_table_tablespaces() + +static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback) { int ret; char* dbpath = NULL; @@ -2648,8 +2759,7 @@ xb_load_single_table_tablespaces() && !strcmp(dbinfo.name + len - 4, ".ibd"); if (is_isl || is_ibd) { - xb_load_single_table_tablespace( - NULL, dbinfo.name, is_isl); + (*callback)(NULL, dbinfo.name, is_isl); } } @@ -2708,9 +2818,7 @@ xb_load_single_table_tablespaces() if (len > 4 && !strcmp(fileinfo.name + len - 4, ".ibd")) { - xb_load_single_table_tablespace( - dbinfo.name, fileinfo.name, - false); + (*callback)(dbinfo.name, fileinfo.name, false); } } @@ -2805,7 +2913,7 @@ xb_load_tablespaces() msg("xtrabackup: Generating a list of tablespaces\n"); - err = xb_load_single_table_tablespaces(); + err = enumerate_ibd_files(xb_load_single_table_tablespace); if (err != DB_SUCCESS) { return(err); } @@ -3230,7 +3338,7 @@ open_or_create_log_file( ut_a(fil_validate()); - ut_a(fil_node_create(name, srv_log_file_size >> srv_page_size_shift, + ut_a(fil_node_create(name, ulint(srv_log_file_size >> srv_page_size_shift), space, false, false)); return(DB_SUCCESS); @@ -4503,349 +4611,6 @@ xtrabackup_apply_deltas() xtrabackup_apply_delta); } -/*********************************************************************//** -Write the meta data (index user fields) config file. -@return true in case of success otherwise false. */ -static -bool -xb_export_cfg_write_index_fields( -/*===========================*/ - const dict_index_t* index, /*!< in: write the meta data for - this index */ - FILE* file) /*!< in: file to write to */ -{ - byte row[sizeof(ib_uint32_t) * 2]; - - for (ulint i = 0; i < index->n_fields; ++i) { - byte* ptr = row; - const dict_field_t* field = &index->fields[i]; - - mach_write_to_4(ptr, field->prefix_len); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, field->fixed_len); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - - msg("xtrabackup: Error: writing index fields."); - - return(false); - } - - /* Include the NUL byte in the length. */ - ib_uint32_t len = (ib_uint32_t)strlen(field->name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(field->name, 1, len, file) != len) { - - msg("xtrabackup: Error: writing index column."); - - return(false); - } - } - - return(true); -} - -/*********************************************************************//** -Write the meta data config file index information. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_indexes( -/*======================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - { - byte row[sizeof(ib_uint32_t)]; - - /* Write the number of indexes in the table. */ - mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes)); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("xtrabackup: Error: writing index count."); - - return(false); - } - } - - bool ret = true; - - /* Write the index meta data. */ - for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); - index != 0 && ret; - index = UT_LIST_GET_NEXT(indexes, index)) { - - byte* ptr; - byte row[sizeof(ib_uint64_t) - + sizeof(ib_uint32_t) * 8]; - - ptr = row; - - ut_ad(sizeof(ib_uint64_t) == 8); - mach_write_to_8(ptr, index->id); - ptr += sizeof(ib_uint64_t); - - mach_write_to_4(ptr, index->space); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->page); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->type); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->trx_id_offset); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_user_defined_cols); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_uniq); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_nullable); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, index->n_fields); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - - msg("xtrabackup: Error: writing index meta-data."); - - return(false); - } - - /* Write the length of the index name. - NUL byte is included in the length. */ - ib_uint32_t len = (ib_uint32_t)strlen(index->name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(index->name, 1, len, file) != len) { - - msg("xtrabackup: Error: writing index name."); - - return(false); - } - - ret = xb_export_cfg_write_index_fields(index, file); - } - - return(ret); -} - -/*********************************************************************//** -Write the meta data (table columns) config file. Serialise the contents of -dict_col_t structure, along with the column name. All fields are serialized -as ib_uint32_t. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_table( -/*====================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - dict_col_t* col; - byte row[sizeof(ib_uint32_t) * 7]; - - col = table->cols; - - for (ulint i = 0; i < table->n_cols; ++i, ++col) { - byte* ptr = row; - - mach_write_to_4(ptr, col->prtype); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->mtype); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->len); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->mbminmaxlen); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->ind); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->ord_part); - ptr += sizeof(ib_uint32_t); - - mach_write_to_4(ptr, col->max_prefix); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("xtrabackup: Error: writing table column data."); - - return(false); - } - - /* Write out the column name as [len, byte array]. The len - includes the NUL byte. */ - ib_uint32_t len; - const char* col_name; - - col_name = dict_table_get_col_name(table, dict_col_get_no(col)); - - /* Include the NUL byte in the length. */ - len = (ib_uint32_t)strlen(col_name) + 1; - ut_a(len > 1); - - mach_write_to_4(row, len); - - if (fwrite(row, 1, sizeof(len), file) != sizeof(len) - || fwrite(col_name, 1, len, file) != len) { - - msg("xtrabackup: Error: writing column name."); - - return(false); - } - } - - return(true); -} - -/*********************************************************************//** -Write the meta data config file header. -@return true in case of success otherwise false. */ -static __attribute__((nonnull, warn_unused_result)) -bool -xb_export_cfg_write_header( -/*=====================*/ - const dict_table_t* table, /*!< in: write the meta data for - this table */ - FILE* file) /*!< in: file to write to */ -{ - byte value[sizeof(ib_uint32_t)]; - - /* Write the meta-data version number. */ - mach_write_to_4(value, IB_EXPORT_CFG_VERSION_V1); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)) { - msg("xtrabackup: Error: writing meta-data version number."); - - return(false); - } - - /* Write the server hostname. */ - ib_uint32_t len; - const char* hostname = "Hostname unknown"; - - /* The server hostname includes the NUL byte. */ - len = (ib_uint32_t)strlen(hostname) + 1; - mach_write_to_4(value, len); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value) - || fwrite(hostname, 1, len, file) != len) { - - msg("xtrabackup: Error: writing hostname."); - - return(false); - } - - /* The table name includes the NUL byte. */ - const char* table_name = table->name.m_name; - ut_a(table_name != 0); - len = (ib_uint32_t)strlen(table_name) + 1; - - /* Write the table name. */ - mach_write_to_4(value, len); - - if (fwrite(&value, 1, sizeof(value), file) != sizeof(value) - || fwrite(table_name, 1, len, file) != len) { - - msg("xtrabackup: Error: writing table name."); - - return(false); - } - - byte row[sizeof(ib_uint32_t) * 3]; - - /* Write the next autoinc value. */ - mach_write_to_8(row, table->autoinc); - - if (fwrite(row, 1, sizeof(ib_uint64_t), file) != sizeof(ib_uint64_t)) { - msg("xtrabackup: Error: writing table autoinc value."); - - return(false); - } - - byte* ptr = row; - - /* Write the system page size. */ - mach_write_to_4(ptr, UNIV_PAGE_SIZE); - ptr += sizeof(ib_uint32_t); - - /* Write the table->flags. */ - mach_write_to_4(ptr, table->flags); - ptr += sizeof(ib_uint32_t); - - /* Write the number of columns in the table. */ - mach_write_to_4(ptr, table->n_cols); - - if (fwrite(row, 1, sizeof(row), file) != sizeof(row)) { - msg("xtrabackup: Error: writing table meta-data."); - - return(false); - } - - return(true); -} - -/*********************************************************************//** -Write MySQL 5.6-style meta data config file. -@return true in case of success otherwise false. */ -static -bool -xb_export_cfg_write( - const fil_node_t* node, - const dict_table_t* table) /*!< in: write the meta data for - this table */ -{ - char file_path[FN_REFLEN]; - FILE* file; - bool success; - - strcpy(file_path, node->name); - strcpy(file_path + strlen(file_path) - 4, ".cfg"); - - file = fopen(file_path, "w+b"); - - if (file == NULL) { - msg("xtrabackup: Error: cannot open %s\n", node->name); - - success = false; - } else { - - success = xb_export_cfg_write_header(table, file); - - if (success) { - success = xb_export_cfg_write_table(table, file); - } - - if (success) { - success = xb_export_cfg_write_indexes(table, file); - } - - if (fclose(file) != 0) { - msg("xtrabackup: Error: cannot close %s\n", node->name); - success = false; - } - - } - - return(success); - -} static void @@ -4882,7 +4647,6 @@ store_binlog_info(const char* filename, const char* name, ulonglong pos) static bool xtrabackup_prepare_func(char** argv) { - datafiles_iter_t *it; char metadata_path[FN_REFLEN]; /* cd to target-dir */ @@ -4901,6 +4665,8 @@ xtrabackup_prepare_func(char** argv) xtrabackup_target_dir= mysql_data_home_buff; xtrabackup_target_dir[0]=FN_CURLIB; // all paths are relative from here xtrabackup_target_dir[1]=0; + const lsn_t target_lsn = xtrabackup_incremental + ? incremental_to_lsn : metadata_to_lsn; /* read metadata of target @@ -4951,9 +4717,7 @@ xtrabackup_prepare_func(char** argv) srv_operation = SRV_OPERATION_RESTORE_DELTA; if (innodb_init_param()) { -error_cleanup: - xb_filters_free(); - return(false); + goto error_cleanup; } xb_normalize_init_values(); @@ -5026,169 +4790,6 @@ error_cleanup: goto error_cleanup; } - if (xtrabackup_export) { -#if 1 // FIXME: remove the option or fix the logic - /* In MariaDB 10.2, undo log processing would need the - ability to evaluate indexed virtual columns, and we - have not initialized the necessary infrastructure. */ - msg("xtrabackup: --export does not work!\n"); - ok = false; - } else if (xtrabackup_export) { -#endif - msg("xtrabackup: export option is specified.\n"); - - /* To allow subsequent MariaDB server startup independent - of the value of --innodb-log-checksums, - unconditionally enable redo log checksums. */ - log_checksum_algorithm_ptr = log_block_calc_checksum_crc32; - - pfs_os_file_t info_file; - char info_file_path[FN_REFLEN]; - bool success; - char table_name[FN_REFLEN]; - - byte* page; - byte* buf = NULL; - - buf = static_cast(malloc(UNIV_PAGE_SIZE * 2)); - page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); - - it = datafiles_iter_new(fil_system); - if (it == NULL) { - msg("xtrabackup: Error: datafiles_iter_new() " - "failed.\n"); - ok = false; - } else - while (fil_node_t *node = datafiles_iter_next(it)) { - int len; - char *next, *prev, *p; - dict_table_t* table; - dict_index_t* index; - ulint n_index; - - const fil_space_t* space = node->space; - - /* treat file_per_table only */ - if (!fil_is_user_tablespace_id(space->id)) { - continue; - } - - /* node exist == file exist, here */ - strcpy(info_file_path, node->name); -#ifdef _WIN32 - for (int i = 0; info_file_path[i]; i++) - if (info_file_path[i] == '\\') - info_file_path[i]= '/'; -#endif - strcpy(info_file_path + - strlen(info_file_path) - - 4, ".exp"); - - len =(ib_uint32_t)strlen(info_file_path); - - p = info_file_path; - prev = NULL; - while ((next = strchr(p, '/')) != NULL) - { - prev = p; - p = next + 1; - } - info_file_path[len - 4] = 0; - strncpy(table_name, prev, FN_REFLEN); - - info_file_path[len - 4] = '.'; - - mutex_enter(&(dict_sys->mutex)); - - table = dict_table_get_low(table_name); - if (!table) { - msg("xtrabackup: error: " - "cannot find dictionary " - "record of table %s\n", - table_name); - goto next_node; - } - - /* Write MySQL 5.6 .cfg file */ - if (!xb_export_cfg_write(node, table)) { - goto next_node; - } - - index = dict_table_get_first_index(table); - n_index = UT_LIST_GET_LEN(table->indexes); - if (n_index > 31) { - msg("xtrabackup: warning: table '%s' has more " - "than 31 indexes, .exp file was not " - "generated. Table will fail to import " - "on server version prior to 5.6.\n", - table->name.m_name); - goto next_node; - } - - /* init exp file */ - memcpy(page, "xportinf", 8); - mach_write_to_4(page + 8, n_index); - memset(page + 12, 0, UNIV_PAGE_SIZE - 12); - strncpy((char *) page + 12, - table_name, 500); - - msg("xtrabackup: export metadata of " - "table '%s' to file `%s` " - "(%lu indexes)\n", - table_name, info_file_path, - n_index); - - n_index = 1; - while (index) { - mach_write_to_8(page + n_index * 512, index->id); - mach_write_to_4(page + n_index * 512 + 8, - index->page); - strncpy((char *) page + n_index * 512 + - 12, index->name, 500); - - msg("xtrabackup: name=%s, " - "id.low=%lu, page=%lu\n", - index->name(), - (ulint)(index->id & - 0xFFFFFFFFUL), - (ulint) index->page); - index = dict_table_get_next_index(index); - n_index++; - } - - os_normalize_path(info_file_path); - info_file = os_file_create( - 0, - info_file_path, - OS_FILE_OVERWRITE, - OS_FILE_NORMAL, OS_DATA_FILE, - false, &success); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } - success = os_file_write(IORequestWrite, info_file_path, - info_file, page, - 0, UNIV_PAGE_SIZE); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } - success = os_file_flush(info_file); - if (!success) { - os_file_get_last_error(TRUE); - goto next_node; - } -next_node: - if (info_file != OS_FILE_CLOSED) { - os_file_close(info_file); - info_file = OS_FILE_CLOSED; - } - mutex_exit(&(dict_sys->mutex)); - } - - free(buf); - } if (ok) { mtr_t mtr; @@ -5225,8 +4826,6 @@ next_node: } /* Check whether the log is applied enough or not. */ - const lsn_t target_lsn = xtrabackup_incremental - ? incremental_to_lsn : metadata_to_lsn; if ((srv_start_lsn || fil_space_get(SRV_LOG_SPACE_FIRST_ID)) && srv_start_lsn < target_lsn) { msg("xtrabackup: error: " @@ -5273,6 +4872,10 @@ next_node: if (ok) ok = apply_log_finish(); + if (ok && xtrabackup_export) + ok= (prepare_export() == 0); + +error_cleanup: xb_filters_free(); return ok; } @@ -5422,7 +5025,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) my_sigset(SIGINT, SIG_DFL); #endif - sf_leaking_memory = 0; /* don't report memory leaks on early exist */ + sf_leaking_memory = 1; /* don't report memory leaks on early exist */ int i; int ho_error; @@ -5592,17 +5195,41 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) } static int main_low(char** argv); +static int get_exepath(char *buf, size_t size, const char *argv0); /* ================= main =================== */ int main(int argc, char **argv) { char **client_defaults, **server_defaults; - if (argc > 1 && (strcmp(argv[1], "--innobackupex") == 0)) + + if (get_exepath(mariabackup_exe,FN_REFLEN, argv[0])) + strncpy(mariabackup_exe,argv[0], FN_REFLEN-1); + + + if (argc > 1 ) { - argv++; - argc--; - innobackupex_mode = true; + /* In "prepare export", we need to start mysqld + Since it is not always be installed on the machine, + we start "mariabackup --mysqld", which acts as mysqld + */ + if (strcmp(argv[1], "--mysqld") == 0) + { + extern int mysqld_main(int argc, char **argv); + argc--; + argv++; + argv[0]+=2; + return mysqld_main(argc, argv); + } + if(strcmp(argv[1], "--innobackupex") == 0) + { + argv++; + argc--; + innobackupex_mode = true; + } } + + if (argc > 1) + strncpy(orig_argv1,argv[1],sizeof(orig_argv1) -1); init_signals(); MY_INIT(argv[0]); @@ -5858,3 +5485,20 @@ static int main_low(char** argv) return(EXIT_SUCCESS); } + + +static int get_exepath(char *buf, size_t size, const char *argv0) +{ +#ifdef _WIN32 + DWORD ret = GetModuleFileNameA(NULL, buf, size); + if (ret > 0) + return 0; +#elif defined(__linux__) + ssize_t ret = readlink("/proc/self/exe", buf, size-1); + if(ret > 0) + return 0; +#endif + + return my_realpath(buf, argv0, 0); +} + diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a931381d9cc..1bbcfde9aa3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5044,13 +5044,6 @@ sub mysqld_start ($$) { $path_vardir_trace, $mysqld->name()); } - if (IS_WINDOWS) - { - # Trick the server to send output to stderr, with --console - if (!(grep(/^--log-error/, @$args))) { - mtr_add_arg($args, "--console"); - } - } # "Dynamic" version of MYSQLD_CMD is reevaluated with each mysqld_start. # Use it to restart the server at testing a failing server start (e.g @@ -5514,14 +5507,6 @@ sub start_mysqltest ($) { my $extra_opts= get_extra_opts($mysqld, $tinfo); mysqld_arguments($mysqld_args, $mysqld, $extra_opts); mtr_add_arg($args, "--server-arg=%s", $_) for @$mysqld_args; - - if (IS_WINDOWS) - { - # Trick the server to send output to stderr, with --console - if (!(grep(/^--server-arg=--log-error/, @$args))) { - mtr_add_arg($args, "--server-arg=--console"); - } - } } # ---------------------------------------------------------------------- diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log.result b/mysql-test/suite/encryption/r/innodb_encrypt_log.result index 2ed3e50a590..0663890c685 100644 --- a/mysql-test/suite/encryption/r/innodb_encrypt_log.result +++ b/mysql-test/suite/encryption/r/innodb_encrypt_log.result @@ -50,7 +50,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); # ib_logfile0 expecting NOT FOUND NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0 # ib_logfile0 expecting FOUND -FOUND 3 /public|gossip/ in ib_logfile0 +FOUND 1 /(public|gossip).*/ in ib_logfile0 # ibdata1 expecting NOT FOUND NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in ibdata1 # t0.ibd expecting NOT FOUND diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log.test b/mysql-test/suite/encryption/t/innodb_encrypt_log.test index 4bc556ee1d2..4b3d92e876c 100644 --- a/mysql-test/suite/encryption/t/innodb_encrypt_log.test +++ b/mysql-test/suite/encryption/t/innodb_encrypt_log.test @@ -75,7 +75,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); --echo # ib_logfile0 expecting NOT FOUND -- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 -- source include/search_pattern_in_file.inc ---let SEARCH_PATTERN=public|gossip +--let SEARCH_PATTERN=(public|gossip).* --echo # ib_logfile0 expecting FOUND -- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 -- source include/search_pattern_in_file.inc diff --git a/mysql-test/suite/innodb/r/alter_crash.result b/mysql-test/suite/innodb/r/alter_crash.result new file mode 100644 index 00000000000..8de02cc5fbd --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_crash.result @@ -0,0 +1,149 @@ +# +# Bug#20015132 ALTER TABLE FAILS TO CHECK IF TABLE IS CORRUPTED +# +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB; +SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx'; +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); +ERROR HY000: Too many active concurrent transactions +SET DEBUG_DBUG=@saved_debug_dbug; +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); +SET DEBUG_DBUG='+d,dict_set_index_corrupted'; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Warning InnoDB: Index c2 is marked as corrupted +test.t1 check Warning InnoDB: Index c3 is marked as corrupted +test.t1 check error Corrupt +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Warning InnoDB: Index c2 is marked as corrupted +test.t1 check Warning InnoDB: Index c3 is marked as corrupted +test.t1 check error Corrupt +ALTER TABLE t1 DROP INDEX c2; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Warning InnoDB: Index c3 is marked as corrupted +test.t1 check error Corrupt +ALTER TABLE t1 ADD INDEX (c2,c3); +ERROR HY000: Index c3 is corrupted +ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +ALTER TABLE t1 ADD INDEX (c2,c3); +DROP TABLE t1; +# +# Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE +# +# -- Scenario 1: +# Crash the server in ha_innobase::commit_inplace_alter_table() +# just after committing the dictionary changes. +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; +INSERT INTO t1 VALUES (1,2),(3,4); +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit'; +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +ERROR HY000: Lost connection to MySQL server during query +# Restart mysqld after the crash and reconnect. +# Manual *.frm recovery begin. +# Manual recovery end +FLUSH TABLES; +# Drop the orphaned original table. +# Files in datadir after manual recovery. +t1.frm +t1.ibd +SHOW TABLES; +Tables_in_test +t1 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + PRIMARY KEY (`f2`,`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES (5,6),(7,8); +SELECT * FROM t1; +f1 f2 +1 2 +3 4 +5 6 +7 8 +DROP TABLE t1; +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +DROP TABLE t1; +# -- Scenario 2: +# Crash the server in ha_innobase::commit_inplace_alter_table() +# just before committing the dictionary changes, but after +# writing the MLOG_FILE_RENAME records. As the mini-transaction +# is not committed, the renames will not be replayed. +CREATE TABLE t2 (f1 int not null, f2 int not null) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,2),(3,4); +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit'; +ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); +ERROR HY000: Lost connection to MySQL server during query +# Startup the server after the crash +# Read and remember the temporary table name +# Manual *.frm recovery begin. The dictionary was not updated +# and the files were not renamed. The rebuilt table +# was left behind on purpose, to faciliate data recovery. +# Manual recovery end +# Drop the orphaned rebuilt table. +SHOW TABLES; +Tables_in_test +t2 +INSERT INTO t2 VALUES (5,6),(7,8); +SELECT * from t2; +f1 f2 +1 2 +3 4 +5 6 +7 8 +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t2; +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; +ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); +DROP TABLE t2; +# ------------------------- +# End of Testing Scenario 2 +# ------------------------- +# +# Bug#19330255 WL#7142 - CRASH DURING ALTER TABLE LEADS TO +# DATA DICTIONARY INCONSISTENCY +# +CREATE TABLE t1(a int PRIMARY KEY, b varchar(255), c int NOT NULL) +ENGINE=InnoDB; +INSERT INTO t1 SET a=1,c=2; +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit'; +ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE; +ERROR HY000: Lost connection to MySQL server during query +# Restart mysqld after the crash and reconnect. +# Manual *.frm recovery begin. +# Manual recovery end +FLUSH TABLES; +# Drop the orphaned original table. +# Files in datadir after manual recovery. +t1.frm +t1.ibd +SHOW TABLES; +Tables_in_test +t1 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(255) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +UPDATE t1 SET d=NULL; +SELECT * FROM t1; +a b d +1 NULL NULL +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/alter_crash.opt b/mysql-test/suite/innodb/t/alter_crash.opt new file mode 100644 index 00000000000..39b93371503 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_crash.opt @@ -0,0 +1 @@ +--loose-innodb-sys-tables diff --git a/mysql-test/suite/innodb/t/alter_crash.test b/mysql-test/suite/innodb/t/alter_crash.test new file mode 100644 index 00000000000..54cc51aecf4 --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_crash.test @@ -0,0 +1,228 @@ +# Crash-safe InnoDB ALTER operations + +--source include/not_valgrind.inc +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/not_crashrep.inc + +--disable_query_log +call mtr.add_suppression('InnoDB: cannot find a free slot for an undo log'); +call mtr.add_suppression('InnoDB: row_merge_rename_index_to_add failed with error 47'); +call mtr.add_suppression('InnoDB: Flagged corruption of `c[23]`'); +call mtr.add_suppression('InnoDB: Index `c[23]` .*is corrupted'); +--enable_query_log + +--echo # +--echo # Bug#20015132 ALTER TABLE FAILS TO CHECK IF TABLE IS CORRUPTED +--echo # + +CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB; +SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx'; +--error ER_TOO_MANY_CONCURRENT_TRXS +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); + +SET DEBUG_DBUG=@saved_debug_dbug; +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); +# Flag the secondary indexes corrupted. +SET DEBUG_DBUG='+d,dict_set_index_corrupted'; +CHECK TABLE t1; + +# Ensure that the corruption is permanent. +--source include/restart_mysqld.inc +CHECK TABLE t1; +ALTER TABLE t1 DROP INDEX c2; +CHECK TABLE t1; +# We refuse an ALTER TABLE that would modify the InnoDB data dictionary +# while leaving some of the table corrupted. +--error ER_INDEX_CORRUPT +ALTER TABLE t1 ADD INDEX (c2,c3); +# This will rebuild the table, uncorrupting all secondary indexes. +ALTER TABLE t1 CHANGE c3 c3 INT NOT NULL; +CHECK TABLE t1; +ALTER TABLE t1 ADD INDEX (c2,c3); +DROP TABLE t1; + +let $MYSQLD_DATADIR= `select @@datadir`; +let datadir= `select @@datadir`; + +# These are from include/shutdown_mysqld.inc and allow to call start_mysqld.inc +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +--echo # +--echo # Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE +--echo # +--echo # -- Scenario 1: +--echo # Crash the server in ha_innobase::commit_inplace_alter_table() +--echo # just after committing the dictionary changes. + +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; +INSERT INTO t1 VALUES (1,2),(3,4); +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit'; + +let $orig_table_id = `SELECT table_id + FROM information_schema.innodb_sys_tables + WHERE name = 'test/t1'`; + +# Write file to make mysql-test-run.pl expect crash +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--error 2013 +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); + +--echo # Restart mysqld after the crash and reconnect. +--source include/start_mysqld.inc + +let $temp_table_name = `SELECT SUBSTR(name, 6) + FROM information_schema.innodb_sys_tables + WHERE table_id = $orig_table_id`; + +--echo # Manual *.frm recovery begin. + +--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm + +perl; +my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm"; +my $t1_frm = "$ENV{'datadir'}/test/t1.frm"; +rename($frm_file[0], $t1_frm); +EOF + +--echo # Manual recovery end + +FLUSH TABLES; + +--echo # Drop the orphaned original table. +--disable_query_log +eval DROP TABLE `#mysql50#$temp_table_name`; +--enable_query_log + +--echo # Files in datadir after manual recovery. +--list_files $MYSQLD_DATADIR/test + +SHOW TABLES; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (5,6),(7,8); +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; +ALTER TABLE t1 ADD PRIMARY KEY (f2, f1); +DROP TABLE t1; + +--echo # -- Scenario 2: +--echo # Crash the server in ha_innobase::commit_inplace_alter_table() +--echo # just before committing the dictionary changes, but after +--echo # writing the MLOG_FILE_RENAME records. As the mini-transaction +--echo # is not committed, the renames will not be replayed. + +CREATE TABLE t2 (f1 int not null, f2 int not null) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,2),(3,4); +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_before_commit'; + +let $orig_table_id = `SELECT table_id + FROM information_schema.innodb_sys_tables + WHERE name = 'test/t2'`; + +# Write file to make mysql-test-run.pl expect crash +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--error 2013 +ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); + +--echo # Startup the server after the crash +--source include/start_mysqld.inc + +--echo # Read and remember the temporary table name +let $temp_table_name = `SELECT SUBSTRING(name,6) + FROM information_schema.innodb_sys_tables + WHERE name LIKE "test/#sql-ib$orig_table_id%"`; +# This second copy is an environment variable for the perl script below. +let temp_table_name = $temp_table_name; + +--echo # Manual *.frm recovery begin. The dictionary was not updated +--echo # and the files were not renamed. The rebuilt table +--echo # was left behind on purpose, to faciliate data recovery. + +perl; +my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm"; +my $target_frm = "$ENV{'datadir'}/test/$ENV{'temp_table_name'}.frm"; +rename($frm_file[0], $target_frm); +EOF + +--echo # Manual recovery end + +--echo # Drop the orphaned rebuilt table. +--disable_query_log +eval DROP TABLE `#mysql50#$temp_table_name`; +--enable_query_log + +SHOW TABLES; +INSERT INTO t2 VALUES (5,6),(7,8); +SELECT * from t2; +SHOW CREATE TABLE t2; +DROP TABLE t2; + +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=InnoDB; +ALTER TABLE t2 ADD PRIMARY KEY (f2, f1); +DROP TABLE t2; +--list_files $MYSQLD_DATADIR/test + +--echo # ------------------------- +--echo # End of Testing Scenario 2 +--echo # ------------------------- + +--echo # +--echo # Bug#19330255 WL#7142 - CRASH DURING ALTER TABLE LEADS TO +--echo # DATA DICTIONARY INCONSISTENCY +--echo # + +CREATE TABLE t1(a int PRIMARY KEY, b varchar(255), c int NOT NULL) +ENGINE=InnoDB; +INSERT INTO t1 SET a=1,c=2; +SET DEBUG_DBUG='+d,innodb_alter_commit_crash_after_commit'; + +let $orig_table_id = `select table_id from + information_schema.innodb_sys_tables where name = 'test/t1'`; + +# FIXME: MDEV-9469 'Incorrect key file' on ALTER TABLE +# Write file to make mysql-test-run.pl expect crash +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# +--error 2013 +ALTER TABLE t1 ADD INDEX (b), CHANGE c d int, ALGORITHM=INPLACE; + +--echo # Restart mysqld after the crash and reconnect. +--source include/start_mysqld.inc + +let $temp_table_name = `SELECT SUBSTR(name, 6) + FROM information_schema.innodb_sys_tables + WHERE table_id = $orig_table_id`; + +--echo # Manual *.frm recovery begin. +--move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/$temp_table_name.frm + +perl; +my @frm_file = glob "$ENV{'datadir'}/test/#sql-*.frm"; +my $t1_frm = "$ENV{'datadir'}/test/t1.frm"; +rename($frm_file[0], $t1_frm); +EOF + +--echo # Manual recovery end + +FLUSH TABLES; + +--echo # Drop the orphaned original table. +--disable_query_log +eval DROP TABLE `#mysql50#$temp_table_name`; +--enable_query_log + +--echo # Files in datadir after manual recovery. +--list_files $MYSQLD_DATADIR/test + +SHOW TABLES; +SHOW CREATE TABLE t1; +UPDATE t1 SET d=NULL; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/mariabackup/disabled.def b/mysql-test/suite/mariabackup/disabled.def index d3c11872f0a..8b137891791 100644 --- a/mysql-test/suite/mariabackup/disabled.def +++ b/mysql-test/suite/mariabackup/disabled.def @@ -1,2 +1 @@ -partial : xtrabackup --export does not work -xb_page_compress : xtrabackup --export does not work + diff --git a/mysql-test/suite/mariabackup/partial.result b/mysql-test/suite/mariabackup/partial.result index 98c59be91bb..8ccc8f6a6c7 100644 --- a/mysql-test/suite/mariabackup/partial.result +++ b/mysql-test/suite/mariabackup/partial.result @@ -1,9 +1,14 @@ CREATE TABLE t1(i INT) ENGINE INNODB; INSERT INTO t1 VALUES(1); +CREATE TABLE t21(i INT) ENGINE INNODB; +INSERT INTO t21 VALUES(1); CREATE TABLE t2(i int) ENGINE INNODB; # xtrabackup backup t1.ibd +t21.ibd # xtrabackup prepare +t1.cfg +t21.cfg ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 IMPORT TABLESPACE; SELECT * FROM t1; @@ -11,3 +16,4 @@ i 1 DROP TABLE t1; DROP TABLE t2; +DROP TABLE t21; diff --git a/mysql-test/suite/mariabackup/partial.test b/mysql-test/suite/mariabackup/partial.test index 9c774b2df03..559ba155972 100644 --- a/mysql-test/suite/mariabackup/partial.test +++ b/mysql-test/suite/mariabackup/partial.test @@ -5,6 +5,9 @@ CREATE TABLE t1(i INT) ENGINE INNODB; INSERT INTO t1 VALUES(1); +CREATE TABLE t21(i INT) ENGINE INNODB; +INSERT INTO t21 VALUES(1); + CREATE TABLE t2(i int) ENGINE INNODB; echo # xtrabackup backup; @@ -15,13 +18,23 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=te --enable_result_log list_files $targetdir/test *.ibd; +# Inject a junk .ibd file into backup dir to +# see if prepare does not choke on it. +write_file $targetdir/test/junk.ibd; +EOF +write_file $targetdir/test/junk.frm; +EOF + + echo # xtrabackup prepare; --disable_result_log -exec $XTRABACKUP --prepare --export --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; --enable_result_log -ALTER TABLE t1 DISCARD TABLESPACE; +list_files $targetdir/test *.cfg; + let $MYSQLD_DATADIR= `select @@datadir`; +ALTER TABLE t1 DISCARD TABLESPACE; copy_file $targetdir/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd; copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg; ALTER TABLE t1 IMPORT TABLESPACE; @@ -29,4 +42,5 @@ ALTER TABLE t1 IMPORT TABLESPACE; SELECT * FROM t1; DROP TABLE t1; DROP TABLE t2; +DROP TABLE t21; rmdir $targetdir; diff --git a/mysql-test/suite/mariabackup/xb_page_compress.test b/mysql-test/suite/mariabackup/xb_page_compress.test index 0e9a7d6987c..7e806e6de22 100644 --- a/mysql-test/suite/mariabackup/xb_page_compress.test +++ b/mysql-test/suite/mariabackup/xb_page_compress.test @@ -29,7 +29,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir; echo # xtrabackup prepare; -exec $XTRABACKUP --prepare --export --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; --enable_result_log ALTER TABLE t1 DISCARD TABLESPACE; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3bad009a8bc..2fc5e3c27a5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5044,6 +5044,11 @@ static int init_server_components() help information. Since the implementation of plugin server variables the help output is now written much later. */ +#ifdef _WIN32 + if (opt_console) + opt_error_log= false; +#endif + if (opt_error_log && !opt_abort) { if (!log_error_file_ptr[0]) diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 8bd1f5730a2..54583956107 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -589,16 +589,18 @@ row_quiesce_table_complete( ++count; } - /* Remove the .cfg file now that the user has resumed - normal operations. Otherwise it will cause problems when - the user tries to drop the database (remove directory). */ - char cfg_name[OS_FILE_MAX_PATH]; + if (!opt_bootstrap) { + /* Remove the .cfg file now that the user has resumed + normal operations. Otherwise it will cause problems when + the user tries to drop the database (remove directory). */ + char cfg_name[OS_FILE_MAX_PATH]; - srv_get_meta_data_filename(table, cfg_name, sizeof(cfg_name)); + srv_get_meta_data_filename(table, cfg_name, sizeof(cfg_name)); - os_file_delete_if_exists(innodb_data_file_key, cfg_name, NULL); + os_file_delete_if_exists(innodb_data_file_key, cfg_name, NULL); - ib::info() << "Deleting the meta-data file '" << cfg_name << "'"; + ib::info() << "Deleting the meta-data file '" << cfg_name << "'"; + } if (trx_purge_state() != PURGE_STATE_DISABLED) { trx_purge_run(); diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index c4041340fce..e193697139a 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -1507,6 +1507,12 @@ trx_undo_assign_undo(trx_t* trx, trx_rseg_t* rseg, trx_undo_t** undo) mutex_enter(&rseg->mutex); + DBUG_EXECUTE_IF( + "ib_create_table_fail_too_many_trx", + err = DB_TOO_MANY_CONCURRENT_TRXS; + goto func_exit; + ); + *undo = trx_undo_reuse_cached(trx, rseg, trx->id, trx->xid, &mtr); if (*undo == NULL) { err = trx_undo_create(trx, rseg, trx->id, trx->xid,