Commit fb14761d authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.2 into bb-10.2-ext

parents a82ed92a 2425f2ae
...@@ -139,6 +139,7 @@ char xtrabackup_real_incremental_basedir[FN_REFLEN]; ...@@ -139,6 +139,7 @@ char xtrabackup_real_incremental_basedir[FN_REFLEN];
char xtrabackup_real_extra_lsndir[FN_REFLEN]; char xtrabackup_real_extra_lsndir[FN_REFLEN];
char xtrabackup_real_incremental_dir[FN_REFLEN]; char xtrabackup_real_incremental_dir[FN_REFLEN];
char *xtrabackup_tmpdir; char *xtrabackup_tmpdir;
char *xtrabackup_tables; char *xtrabackup_tables;
...@@ -332,6 +333,9 @@ const char *opt_history = NULL; ...@@ -332,6 +333,9 @@ const char *opt_history = NULL;
my_bool opt_ssl_verify_server_cert = FALSE; my_bool opt_ssl_verify_server_cert = FALSE;
#endif #endif
char mariabackup_exe[FN_REFLEN];
char orig_argv1[FN_REFLEN];
/* Whether xtrabackup_binlog_info should be created on recovery */ /* Whether xtrabackup_binlog_info should be created on recovery */
static bool recover_binlog_info; static bool recover_binlog_info;
...@@ -348,6 +352,11 @@ xtrabackup_add_datasink(ds_ctxt_t *ds) ...@@ -348,6 +352,11 @@ xtrabackup_add_datasink(ds_ctxt_t *ds)
datasinks[actual_datasinks] = ds; actual_datasinks++; 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 ======== */ /* ======== Datafiles iterator ======== */
struct datafiles_iter_t { struct datafiles_iter_t {
fil_system_t *system; fil_system_t *system;
...@@ -1123,6 +1132,108 @@ debug_sync_point(const char *name) ...@@ -1123,6 +1132,108 @@ debug_sync_point(const char *name)
#endif #endif
} }
static std::vector<std::string> 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[]= static const char *xb_client_default_groups[]=
{ "xtrabackup", "client", 0, 0, 0 }; { "xtrabackup", "client", 0, 0, 0 };
...@@ -2520,6 +2631,7 @@ xb_new_datafile(const char *name, bool is_remote) ...@@ -2520,6 +2631,7 @@ xb_new_datafile(const char *name, bool is_remote)
} }
} }
static static
void void
xb_load_single_table_tablespace( xb_load_single_table_tablespace(
...@@ -2581,7 +2693,7 @@ xb_load_single_table_tablespace( ...@@ -2581,7 +2693,7 @@ xb_load_single_table_tablespace(
ut_a(space != NULL); 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)) { false, false)) {
ut_error; ut_error;
} }
...@@ -2610,9 +2722,8 @@ xb_load_single_table_tablespace( ...@@ -2610,9 +2722,8 @@ xb_load_single_table_tablespace(
/** Scan the database directories under the MySQL datadir, looking for /** Scan the database directories under the MySQL datadir, looking for
.ibd files and determining the space id in each of them. .ibd files and determining the space id in each of them.
@return DB_SUCCESS or error number */ @return DB_SUCCESS or error number */
static
dberr_t static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback)
xb_load_single_table_tablespaces()
{ {
int ret; int ret;
char* dbpath = NULL; char* dbpath = NULL;
...@@ -2650,8 +2761,7 @@ xb_load_single_table_tablespaces() ...@@ -2650,8 +2761,7 @@ xb_load_single_table_tablespaces()
&& !strcmp(dbinfo.name + len - 4, ".ibd"); && !strcmp(dbinfo.name + len - 4, ".ibd");
if (is_isl || is_ibd) { if (is_isl || is_ibd) {
xb_load_single_table_tablespace( (*callback)(NULL, dbinfo.name, is_isl);
NULL, dbinfo.name, is_isl);
} }
} }
...@@ -2710,9 +2820,7 @@ xb_load_single_table_tablespaces() ...@@ -2710,9 +2820,7 @@ xb_load_single_table_tablespaces()
if (len > 4 if (len > 4
&& !strcmp(fileinfo.name + len - 4, && !strcmp(fileinfo.name + len - 4,
".ibd")) { ".ibd")) {
xb_load_single_table_tablespace( (*callback)(dbinfo.name, fileinfo.name, false);
dbinfo.name, fileinfo.name,
false);
} }
} }
...@@ -2807,7 +2915,7 @@ xb_load_tablespaces() ...@@ -2807,7 +2915,7 @@ xb_load_tablespaces()
msg("xtrabackup: Generating a list of tablespaces\n"); 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) { if (err != DB_SUCCESS) {
return(err); return(err);
} }
...@@ -3232,7 +3340,7 @@ open_or_create_log_file( ...@@ -3232,7 +3340,7 @@ open_or_create_log_file(
ut_a(fil_validate()); 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)); space, false, false));
return(DB_SUCCESS); return(DB_SUCCESS);
...@@ -4505,349 +4613,6 @@ xtrabackup_apply_deltas() ...@@ -4505,349 +4613,6 @@ xtrabackup_apply_deltas()
xtrabackup_apply_delta); 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 static
void void
...@@ -4884,7 +4649,6 @@ store_binlog_info(const char* filename, const char* name, ulonglong pos) ...@@ -4884,7 +4649,6 @@ store_binlog_info(const char* filename, const char* name, ulonglong pos)
static bool static bool
xtrabackup_prepare_func(char** argv) xtrabackup_prepare_func(char** argv)
{ {
datafiles_iter_t *it;
char metadata_path[FN_REFLEN]; char metadata_path[FN_REFLEN];
/* cd to target-dir */ /* cd to target-dir */
...@@ -4903,6 +4667,8 @@ xtrabackup_prepare_func(char** argv) ...@@ -4903,6 +4667,8 @@ xtrabackup_prepare_func(char** argv)
xtrabackup_target_dir= mysql_data_home_buff; xtrabackup_target_dir= mysql_data_home_buff;
xtrabackup_target_dir[0]=FN_CURLIB; // all paths are relative from here xtrabackup_target_dir[0]=FN_CURLIB; // all paths are relative from here
xtrabackup_target_dir[1]=0; xtrabackup_target_dir[1]=0;
const lsn_t target_lsn = xtrabackup_incremental
? incremental_to_lsn : metadata_to_lsn;
/* /*
read metadata of target read metadata of target
...@@ -4953,9 +4719,7 @@ xtrabackup_prepare_func(char** argv) ...@@ -4953,9 +4719,7 @@ xtrabackup_prepare_func(char** argv)
srv_operation = SRV_OPERATION_RESTORE_DELTA; srv_operation = SRV_OPERATION_RESTORE_DELTA;
if (innodb_init_param()) { if (innodb_init_param()) {
error_cleanup: goto error_cleanup;
xb_filters_free();
return(false);
} }
xb_normalize_init_values(); xb_normalize_init_values();
...@@ -5028,169 +4792,6 @@ xtrabackup_prepare_func(char** argv) ...@@ -5028,169 +4792,6 @@ xtrabackup_prepare_func(char** argv)
goto 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<byte *>(malloc(UNIV_PAGE_SIZE * 2));
page = static_cast<byte *>(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) { if (ok) {
mtr_t mtr; mtr_t mtr;
...@@ -5227,8 +4828,6 @@ xtrabackup_prepare_func(char** argv) ...@@ -5227,8 +4828,6 @@ xtrabackup_prepare_func(char** argv)
} }
/* Check whether the log is applied enough or not. */ /* 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)) if ((srv_start_lsn || fil_space_get(SRV_LOG_SPACE_FIRST_ID))
&& srv_start_lsn < target_lsn) { && srv_start_lsn < target_lsn) {
msg("xtrabackup: error: " msg("xtrabackup: error: "
...@@ -5275,6 +4874,10 @@ xtrabackup_prepare_func(char** argv) ...@@ -5275,6 +4874,10 @@ xtrabackup_prepare_func(char** argv)
if (ok) ok = apply_log_finish(); if (ok) ok = apply_log_finish();
if (ok && xtrabackup_export)
ok= (prepare_export() == 0);
error_cleanup:
xb_filters_free(); xb_filters_free();
return ok; return ok;
} }
...@@ -5424,7 +5027,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) ...@@ -5424,7 +5027,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
my_sigset(SIGINT, SIG_DFL); my_sigset(SIGINT, SIG_DFL);
#endif #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 i;
int ho_error; int ho_error;
...@@ -5594,17 +5197,41 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server) ...@@ -5594,17 +5197,41 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
} }
static int main_low(char** argv); static int main_low(char** argv);
static int get_exepath(char *buf, size_t size, const char *argv0);
/* ================= main =================== */ /* ================= main =================== */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char **client_defaults, **server_defaults; 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 )
{
/* 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++; argv++;
argc--; argc--;
innobackupex_mode = true; innobackupex_mode = true;
} }
}
if (argc > 1)
strncpy(orig_argv1,argv[1],sizeof(orig_argv1) -1);
init_signals(); init_signals();
MY_INIT(argv[0]); MY_INIT(argv[0]);
...@@ -5860,3 +5487,20 @@ static int main_low(char** argv) ...@@ -5860,3 +5487,20 @@ static int main_low(char** argv)
return(EXIT_SUCCESS); 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);
}
...@@ -5057,13 +5057,6 @@ sub mysqld_start ($$) { ...@@ -5057,13 +5057,6 @@ sub mysqld_start ($$) {
$path_vardir_trace, $mysqld->name()); $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. # "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 # Use it to restart the server at testing a failing server start (e.g
...@@ -5526,14 +5519,6 @@ sub start_mysqltest ($) { ...@@ -5526,14 +5519,6 @@ sub start_mysqltest ($) {
my $extra_opts= get_extra_opts($mysqld, $tinfo); my $extra_opts= get_extra_opts($mysqld, $tinfo);
mysqld_arguments($mysqld_args, $mysqld, $extra_opts); mysqld_arguments($mysqld_args, $mysqld, $extra_opts);
mtr_add_arg($args, "--server-arg=%s", $_) for @$mysqld_args; 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");
}
}
} }
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
......
...@@ -50,7 +50,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); ...@@ -50,7 +50,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip');
# ib_logfile0 expecting NOT FOUND # ib_logfile0 expecting NOT FOUND
NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0 NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0
# ib_logfile0 expecting FOUND # ib_logfile0 expecting FOUND
FOUND 3 /public|gossip/ in ib_logfile0 FOUND 1 /(public|gossip).*/ in ib_logfile0
# ibdata1 expecting NOT FOUND # ibdata1 expecting NOT FOUND
NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in ibdata1 NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in ibdata1
# t0.ibd expecting NOT FOUND # t0.ibd expecting NOT FOUND
......
...@@ -75,7 +75,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); ...@@ -75,7 +75,7 @@ INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip');
--echo # ib_logfile0 expecting NOT FOUND --echo # ib_logfile0 expecting NOT FOUND
-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 -- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0
-- source include/search_pattern_in_file.inc -- source include/search_pattern_in_file.inc
--let SEARCH_PATTERN=public|gossip --let SEARCH_PATTERN=(public|gossip).*
--echo # ib_logfile0 expecting FOUND --echo # ib_logfile0 expecting FOUND
-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 -- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0
-- source include/search_pattern_in_file.inc -- source include/search_pattern_in_file.inc
......
#
# 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;
# 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;
partial : xtrabackup --export does not work
xb_page_compress : xtrabackup --export does not work
CREATE TABLE t1(i INT) ENGINE INNODB; CREATE TABLE t1(i INT) ENGINE INNODB;
INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1);
CREATE TABLE t21(i INT) ENGINE INNODB;
INSERT INTO t21 VALUES(1);
CREATE TABLE t2(i int) ENGINE INNODB; CREATE TABLE t2(i int) ENGINE INNODB;
# xtrabackup backup # xtrabackup backup
t1.ibd t1.ibd
t21.ibd
# xtrabackup prepare # xtrabackup prepare
t1.cfg
t21.cfg
ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 DISCARD TABLESPACE;
ALTER TABLE t1 IMPORT TABLESPACE; ALTER TABLE t1 IMPORT TABLESPACE;
SELECT * FROM t1; SELECT * FROM t1;
...@@ -11,3 +16,4 @@ i ...@@ -11,3 +16,4 @@ i
1 1
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t21;
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
CREATE TABLE t1(i INT) ENGINE INNODB; CREATE TABLE t1(i INT) ENGINE INNODB;
INSERT INTO t1 VALUES(1); INSERT INTO t1 VALUES(1);
CREATE TABLE t21(i INT) ENGINE INNODB;
INSERT INTO t21 VALUES(1);
CREATE TABLE t2(i int) ENGINE INNODB; CREATE TABLE t2(i int) ENGINE INNODB;
echo # xtrabackup backup; echo # xtrabackup backup;
...@@ -15,13 +18,23 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=te ...@@ -15,13 +18,23 @@ exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=te
--enable_result_log --enable_result_log
list_files $targetdir/test *.ibd; 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; echo # xtrabackup prepare;
--disable_result_log --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 --enable_result_log
ALTER TABLE t1 DISCARD TABLESPACE; list_files $targetdir/test *.cfg;
let $MYSQLD_DATADIR= `select @@datadir`; 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.ibd $MYSQLD_DATADIR/test/t1.ibd;
copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg; copy_file $targetdir/test/t1.cfg $MYSQLD_DATADIR/test/t1.cfg;
ALTER TABLE t1 IMPORT TABLESPACE; ALTER TABLE t1 IMPORT TABLESPACE;
...@@ -29,4 +42,5 @@ ALTER TABLE t1 IMPORT TABLESPACE; ...@@ -29,4 +42,5 @@ ALTER TABLE t1 IMPORT TABLESPACE;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t21;
rmdir $targetdir; rmdir $targetdir;
...@@ -29,7 +29,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; ...@@ -29,7 +29,7 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
--disable_result_log --disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir;
echo # xtrabackup prepare; 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 --enable_result_log
ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 DISCARD TABLESPACE;
......
...@@ -4991,6 +4991,11 @@ static int init_server_components() ...@@ -4991,6 +4991,11 @@ static int init_server_components()
help information. Since the implementation of plugin server help information. Since the implementation of plugin server
variables the help output is now written much later. 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 (opt_error_log && !opt_abort)
{ {
if (!log_error_file_ptr[0]) if (!log_error_file_ptr[0])
......
...@@ -589,6 +589,7 @@ row_quiesce_table_complete( ...@@ -589,6 +589,7 @@ row_quiesce_table_complete(
++count; ++count;
} }
if (!opt_bootstrap) {
/* Remove the .cfg file now that the user has resumed /* Remove the .cfg file now that the user has resumed
normal operations. Otherwise it will cause problems when normal operations. Otherwise it will cause problems when
the user tries to drop the database (remove directory). */ the user tries to drop the database (remove directory). */
...@@ -599,6 +600,7 @@ row_quiesce_table_complete( ...@@ -599,6 +600,7 @@ row_quiesce_table_complete(
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) { if (trx_purge_state() != PURGE_STATE_DISABLED) {
trx_purge_run(); trx_purge_run();
......
...@@ -1687,6 +1687,12 @@ trx_undo_assign_undo( ...@@ -1687,6 +1687,12 @@ trx_undo_assign_undo(
mutex_enter(&rseg->mutex); 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, type, trx->id, trx->xid, *undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, trx->xid,
&mtr); &mtr);
if (*undo == NULL) { if (*undo == NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment