MDEV-6871 Multi-value insert on MyISAM table that makes slaves crash (when using --skip-external-locking=0)
Problem was that repair() did lock and unlock tables, which leaved already locked tables in wrong state include/my_check_opt.h: Added option T_NO_LOCKS to disable locking during repair() Fixed duplicated bit T_NO_CREATE_RENAME_LSN mysql-test/suite/rpl/r/myisam_external_lock.result: Test case for MDEV-6871 mysql-test/suite/rpl/t/myisam_external_lock-slave.opt: Test case for MDEV-6871 mysql-test/suite/rpl/t/myisam_external_lock.test: Test case for MDEV-6871 storage/maria/ha_maria.cc: Don't lock tables during enable_indexes() Removed some calls to current_thd storage/myisam/ha_myisam.cc: Don't lock tables during enable_indexes() Removed some calls to current_thd
This commit is contained in:
parent
743e2ae433
commit
4a32d9c058
@ -63,7 +63,9 @@ extern "C" {
|
||||
#define T_ZEROFILL (1ULL << 32)
|
||||
#define T_ZEROFILL_KEEP_LSN (1ULL << 33)
|
||||
/** If repair should not bump create_rename_lsn */
|
||||
#define T_NO_CREATE_RENAME_LSN (1ULL << 33)
|
||||
#define T_NO_CREATE_RENAME_LSN (1ULL << 34)
|
||||
/** If repair shouldn't do any locks */
|
||||
#define T_NO_LOCKS (1ULL << 35)
|
||||
|
||||
#define T_REP_ANY (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
|
||||
|
||||
|
12
mysql-test/suite/rpl/r/myisam_external_lock.result
Normal file
12
mysql-test/suite/rpl/r/myisam_external_lock.result
Normal file
File diff suppressed because one or more lines are too long
2
mysql-test/suite/rpl/t/myisam_external_lock-slave.opt
Normal file
2
mysql-test/suite/rpl/t/myisam_external_lock-slave.opt
Normal file
@ -0,0 +1,2 @@
|
||||
--log-slave-updates=0
|
||||
--skip_external_locking=0
|
24
mysql-test/suite/rpl/t/myisam_external_lock.test
Normal file
24
mysql-test/suite/rpl/t/myisam_external_lock.test
Normal file
File diff suppressed because one or more lines are too long
@ -1554,6 +1554,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
|
||||
MARIA_SHARE *share= file->s;
|
||||
ha_rows rows= file->state->records;
|
||||
TRN *old_trn= file->trn;
|
||||
my_bool locking= 0;
|
||||
DBUG_ENTER("ha_maria::repair");
|
||||
|
||||
/*
|
||||
@ -1589,12 +1590,18 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
|
||||
param->out_flag= 0;
|
||||
strmov(fixed_name, share->open_file_name.str);
|
||||
|
||||
// Don't lock tables if we have used LOCK TABLE
|
||||
if (!thd->locked_tables_mode &&
|
||||
maria_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
/*
|
||||
Don't lock tables if we have used LOCK TABLE or if we come from
|
||||
enable_index()
|
||||
*/
|
||||
if (!thd->locked_tables_mode && ! (param->testflag & T_NO_LOCKS))
|
||||
{
|
||||
_ma_check_print_error(param, ER(ER_CANT_LOCK), my_errno);
|
||||
DBUG_RETURN(HA_ADMIN_FAILED);
|
||||
locking= 1;
|
||||
if (maria_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
{
|
||||
_ma_check_print_error(param, ER(ER_CANT_LOCK), my_errno);
|
||||
DBUG_RETURN(HA_ADMIN_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!do_optimize ||
|
||||
@ -1726,7 +1733,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
|
||||
mysql_mutex_unlock(&share->intern_lock);
|
||||
thd_proc_info(thd, old_proc_info);
|
||||
thd_progress_end(thd); // Mark done
|
||||
if (!thd->locked_tables_mode)
|
||||
if (locking)
|
||||
maria_lock_database(file, F_UNLCK);
|
||||
|
||||
/* Reset trn, that may have been set by repair */
|
||||
@ -1960,6 +1967,13 @@ int ha_maria::enable_indexes(uint mode)
|
||||
param.op_name= "recreating_index";
|
||||
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
|
||||
T_CREATE_MISSING_KEYS | T_SAFE_REPAIR);
|
||||
/*
|
||||
Don't lock and unlock table if it's locked.
|
||||
Normally table should be locked. This test is mostly for safety.
|
||||
*/
|
||||
if (likely(file->lock_type != F_UNLCK))
|
||||
param.testflag|= T_NO_LOCKS;
|
||||
|
||||
if (bulk_insert_single_undo == BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR)
|
||||
{
|
||||
bulk_insert_single_undo= BULK_INSERT_SINGLE_UNDO_AND_REPAIR;
|
||||
@ -2199,7 +2213,7 @@ bool ha_maria::check_and_repair(THD *thd)
|
||||
{
|
||||
/* Remove error about crashed table */
|
||||
thd->warning_info->clear_warning_info(thd->query_id);
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_CRASHED_ON_USAGE,
|
||||
"Zerofilling moved table %s", table->s->path.str);
|
||||
sql_print_information("Zerofilling moved table: '%s'",
|
||||
|
@ -1068,6 +1068,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
||||
char fixed_name[FN_REFLEN];
|
||||
MYISAM_SHARE* share = file->s;
|
||||
ha_rows rows= file->state->records;
|
||||
my_bool locking= 0;
|
||||
DBUG_ENTER("ha_myisam::repair");
|
||||
|
||||
param.db_name= table->s->db.str;
|
||||
@ -1081,12 +1082,18 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
||||
// Release latches since this can take a long time
|
||||
ha_release_temporary_latches(thd);
|
||||
|
||||
// Don't lock tables if we have used LOCK TABLE
|
||||
if (! thd->locked_tables_mode &&
|
||||
mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
/*
|
||||
Don't lock tables if we have used LOCK TABLE or if we come from
|
||||
enable_index()
|
||||
*/
|
||||
if (!thd->locked_tables_mode && ! (param.testflag & T_NO_LOCKS))
|
||||
{
|
||||
mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno);
|
||||
DBUG_RETURN(HA_ADMIN_FAILED);
|
||||
locking= 1;
|
||||
if (mi_lock_database(file, table->s->tmp_table ? F_EXTRA_LCK : F_WRLCK))
|
||||
{
|
||||
mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno);
|
||||
DBUG_RETURN(HA_ADMIN_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
if (!do_optimize ||
|
||||
@ -1205,7 +1212,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK ¶m, bool do_optimize)
|
||||
update_state_info(¶m, file, 0);
|
||||
}
|
||||
thd_proc_info(thd, old_proc_info);
|
||||
if (! thd->locked_tables_mode)
|
||||
if (locking)
|
||||
mi_lock_database(file,F_UNLCK);
|
||||
DBUG_RETURN(error ? HA_ADMIN_FAILED :
|
||||
!optimize_done ? HA_ADMIN_ALREADY_DONE : HA_ADMIN_OK);
|
||||
@ -1437,6 +1444,13 @@ int ha_myisam::enable_indexes(uint mode)
|
||||
param.op_name= "recreating_index";
|
||||
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
|
||||
T_CREATE_MISSING_KEYS);
|
||||
/*
|
||||
Don't lock and unlock table if it's locked.
|
||||
Normally table should be locked. This test is mostly for safety.
|
||||
*/
|
||||
if (likely(file->lock_type != F_UNLCK))
|
||||
param.testflag|= T_NO_LOCKS;
|
||||
|
||||
param.myf_rw&= ~MY_WAIT_IF_FULL;
|
||||
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
|
||||
param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method);
|
||||
@ -1515,7 +1529,7 @@ int ha_myisam::indexes_are_disabled(void)
|
||||
void ha_myisam::start_bulk_insert(ha_rows rows)
|
||||
{
|
||||
DBUG_ENTER("ha_myisam::start_bulk_insert");
|
||||
THD *thd= current_thd;
|
||||
THD *thd= table->in_use;
|
||||
ulong size= min(thd->variables.read_buff_size,
|
||||
(ulong) (table->s->avg_row_length*rows));
|
||||
DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
|
||||
@ -1589,7 +1603,7 @@ int ha_myisam::end_bulk_insert()
|
||||
*/
|
||||
|
||||
if (((err= enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE)) != 0) &&
|
||||
current_thd->killed)
|
||||
table->in_use->killed)
|
||||
{
|
||||
delete_all_rows();
|
||||
/* not crashed, despite being killed during repair */
|
||||
|
Loading…
x
Reference in New Issue
Block a user