Skip to content

Commit b1829ff

Browse files
MDEV-22250 InnoDB: Failing assertion: opt_no_lock during mariabackup --backup
backup_file_op_fail(): Ignore the FTS internal table if it is being created in late phase of backup. mariabackup --prepare should be handle intermediate table and orphaned fts internal table. check_if_fts_table(): Modified the code to check for fts auxiliary table and fts common tables. Revised some error message during backup stage commands.
1 parent bd3ee3a commit b1829ff

File tree

1 file changed

+87
-26
lines changed

1 file changed

+87
-26
lines changed

extra/mariabackup/xtrabackup.cc

Lines changed: 87 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,29 +1151,63 @@ static void backup_file_op(uint32_t space_id, int type,
11511151
}
11521152
}
11531153

1154-
static bool check_if_fts_table(const char *file_name) {
1155-
const char *table_name_start = strrchr(file_name, '/');
1154+
/** Check whether the spacename belongs to internal FTS table
1155+
@param space_name space name to be checked
1156+
@return true if it is fts table or false otherwise */
1157+
static bool check_if_fts_table(const char *space_name) {
1158+
/* There are two types of FTS internal table
1159+
1) FTS common tables (FTS_<space_id>_<fts_common_tables>
1160+
2) FTS INDEX auxiliary table (FTS_<space_id>_<index_id>_<aux_table> */
1161+
const char *table_name_start = strrchr(space_name, '/');
11561162
if (table_name_start)
11571163
++table_name_start;
11581164
else
1159-
table_name_start = file_name;
1165+
table_name_start = space_name;
11601166

1167+
const char *table_name_end = strrchr(table_name_start, '.');
1168+
if (!table_name_end)
1169+
table_name_end =
1170+
table_name_start + strlen(table_name_start) - 1;
11611171
if (!starts_with(table_name_start,"FTS_"))
11621172
return false;
11631173

1164-
const char *table_name_end = strrchr(table_name_start, '.');
1165-
if (!table_name_end)
1166-
table_name_end = table_name_start + strlen(table_name_start);
1167-
ptrdiff_t table_name_len = table_name_end - table_name_end;
1174+
/* Skip FTS_ */
1175+
const char *table_name_suffix = strchr(table_name_start, '_');
1176+
if (!table_name_suffix ||
1177+
table_name_suffix == table_name_end) {
1178+
return false;
1179+
}
1180+
table_name_suffix++;
11681181

1169-
for (const char **suffix = fts_common_tables; *suffix; ++suffix)
1170-
if (!strncmp(table_name_start, *suffix, table_name_len))
1182+
/* Skip <table_id>_ */
1183+
table_name_suffix = strchr(table_name_suffix, '_');
1184+
if (!table_name_suffix ||
1185+
table_name_end == table_name_suffix) {
1186+
return false;
1187+
}
1188+
table_name_suffix++;
1189+
1190+
ptrdiff_t table_name_len = table_name_end - table_name_suffix;
1191+
1192+
/* Compare only common tables */
1193+
for (const char **suffix = fts_common_tables; *suffix; ++suffix) {
1194+
if (!strncmp(table_name_suffix, *suffix, table_name_len))
11711195
return true;
1196+
}
1197+
1198+
/* Skip index_id on fts table name */
1199+
table_name_suffix = strchr(table_name_suffix, '_');
1200+
if (!table_name_suffix ||
1201+
table_name_suffix == table_name_end) {
1202+
return false;
1203+
}
1204+
table_name_suffix++;
1205+
1206+
table_name_len = table_name_end - table_name_suffix;
11721207
for (size_t i = 0; fts_index_selector[i].suffix; ++i)
1173-
if (!strncmp(table_name_start, fts_index_selector[i].suffix,
1174-
table_name_len))
1208+
if (!strncmp(table_name_suffix, fts_index_selector[i].suffix,
1209+
table_name_len))
11751210
return true;
1176-
11771211
return false;
11781212
}
11791213

@@ -1198,7 +1232,20 @@ static void backup_file_op_fail(uint32_t space_id, int type,
11981232
msg("DDL tracking : create %" PRIu32 " \"%.*s\"",
11991233
space_id, int(len), name);
12001234
fail = !check_if_skip_table(spacename.c_str());
1201-
error= "create";
1235+
if (!opt_no_lock && fail &&
1236+
check_if_fts_table(spacename.c_str())) {
1237+
/* Ignore the FTS internal table because InnoDB does
1238+
create intermediate table and their associative FTS
1239+
internal table when table is being rebuilt during
1240+
prepare phase. Also, backup_set_alter_copy_lock()
1241+
downgrades the MDL_BACKUP_DDL before prepare phase
1242+
of alter. This leads to the FTS internal table being
1243+
created in the late phase of backup.
1244+
mariabackup --prepare should be able to handle
1245+
this case. */
1246+
fail = false;
1247+
}
1248+
error= "create";
12021249
break;
12031250
case FILE_MODIFY:
12041251
break;
@@ -5061,7 +5108,7 @@ class BackupStages {
50615108

50625109
bool stage_start(Backup_datasinks &backup_datasinks,
50635110
CorruptedPages &corrupted_pages) {
5064-
msg("BACKUP STAGE START");
5111+
msg("Starting BACKUP STAGE START");
50655112
if (!opt_no_lock) {
50665113
if (opt_safe_slave_backup) {
50675114
if (!wait_for_safe_slave(mysql_connection)) {
@@ -5075,6 +5122,7 @@ class BackupStages {
50755122
msg("Error on BACKUP STAGE START query execution");
50765123
return(false);
50775124
}
5125+
msg("Acquired locks for BACKUP STAGE START");
50785126
}
50795127

50805128
InnodbDataCopier innodb_data_copier(backup_datasinks,
@@ -5105,14 +5153,18 @@ class BackupStages {
51055153

51065154
DBUG_MARIABACKUP_EVENT_LOCK("after_aria_background", {});
51075155

5156+
msg("Finished BACKUP STAGE START");
51085157
return true;
51095158
}
51105159

51115160
bool stage_flush() {
5112-
msg("BACKUP STAGE FLUSH");
5113-
if (!opt_no_lock && !lock_for_backup_stage_flush(m_bs_con)) {
5114-
msg("Error on BACKUP STAGE FLUSH query execution");
5115-
return false;
5161+
msg("Starting BACKUP STAGE FLUSH");
5162+
if (!opt_no_lock) {
5163+
if (!lock_for_backup_stage_flush(m_bs_con)) {
5164+
msg("Error on BACKUP STAGE FLUSH query execution");
5165+
return false;
5166+
}
5167+
msg("Acquired locks for BACKUP STAGE FLUSH");
51165168
}
51175169
auto tables_in_use = get_tables_in_use(mysql_connection);
51185170
// Copy non-stats-log non-in-use tables of non-InnoDB-Aria-RocksDB engines
@@ -5160,17 +5212,20 @@ class BackupStages {
51605212
xb_mysql_query(mysql_connection,
51615213
"SET debug_sync='now WAIT_FOR copy_started'", false, true);
51625214
);
5163-
5215+
msg("Finished BACKUP STAGE FLUSH");
51645216
return true;
51655217
}
51665218

51675219
bool stage_block_ddl(Backup_datasinks &backup_datasinks,
51685220
CorruptedPages &corrupted_pages) {
5221+
msg("Started BACKUP STAGE BLOCK_DDL");
51695222
if (!opt_no_lock) {
51705223
if (!lock_for_backup_stage_block_ddl(m_bs_con)) {
5171-
msg("BACKUP STAGE BLOCK_DDL");
5224+
msg("Error on BACKUP STAGE BLOCK_DDL "
5225+
"query execution");
51725226
return false;
51735227
}
5228+
msg("Acquired locks for BACKUP STAGE BLOCK_DDL");
51745229
if (have_galera_enabled)
51755230
{
51765231
xb_mysql_query(mysql_connection, "SET SESSION wsrep_sync_wait=0", false);
@@ -5232,14 +5287,18 @@ class BackupStages {
52325287

52335288
DBUG_MARIABACKUP_EVENT_LOCK("after_stage_block_ddl", {});
52345289

5290+
msg("Finished BACKUP STAGE BLOCK_DDL");
52355291
return true;
52365292
}
52375293

52385294
bool stage_block_commit(Backup_datasinks &backup_datasinks) {
5239-
msg("BACKUP STAGE BLOCK_COMMIT");
5240-
if (!opt_no_lock && !lock_for_backup_stage_commit(m_bs_con)) {
5241-
msg("Error on BACKUP STAGE BLOCK_COMMIT query execution");
5242-
return false;
5295+
msg("Starting BACKUP STAGE BLOCK_COMMIT");
5296+
if (!opt_no_lock) {
5297+
if (!lock_for_backup_stage_commit(m_bs_con)) {
5298+
msg("Error on BACKUP STAGE BLOCK_COMMIT query execution");
5299+
return false;
5300+
}
5301+
msg("Acquired locks for BACKUP STAGE BLOCK_COMMIT");
52435302
}
52445303

52455304
// Copy log tables tail
@@ -5339,11 +5398,13 @@ class BackupStages {
53395398
"FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS", false);
53405399
}
53415400

5342-
return backup_datasinks.backup_low();
5401+
bool res= backup_datasinks.backup_low();
5402+
msg("Finishing BACKUP STAGE BLOCK_COMMIT");
5403+
return res;
53435404
}
53445405

53455406
bool stage_end(Backup_datasinks &backup_datasinks) {
5346-
msg("BACKUP STAGE END");
5407+
msg("Starting BACKUP STAGE END");
53475408
/* release all locks */
53485409
if (!opt_no_lock) {
53495410
unlock_all(m_bs_con);

0 commit comments

Comments
 (0)