From 293cb04959172f65b9d62124fd20339c47658eb0 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 7 Apr 2016 19:26:25 +0300 Subject: MDEV-9621 INSERT DELAYED fails on insert for tables with many columns This fix also fixes a connection hang when trying to do INSERT DELAYED to a crashed table. Added crash_mysqld.inc to allow easy crash+restart of mysqld --- sql/sql_insert.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'sql/sql_insert.cc') diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f8a755c8d5e..9b4238b513d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2014,6 +2014,7 @@ public: mysql_cond_t cond, cond_client; volatile uint tables_in_use,stacked_inserts; volatile bool status; + bool retry; /** When the handler thread starts, it clones a metadata lock ticket which protects against GRL and ticket for the table to be inserted. @@ -2038,7 +2039,7 @@ public: Delayed_insert(SELECT_LEX *current_select) :locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0), - status(0), handler_thread_initialized(FALSE), group_count(0) + status(0), retry(0), handler_thread_initialized(FALSE), group_count(0) { DBUG_ENTER("Delayed_insert constructor"); thd.security_ctx->user=(char*) delayed_user; @@ -2291,7 +2292,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, } if (di->thd.killed) { - if (di->thd.is_error()) + if (di->thd.is_error() && ! di->retry) { /* Copy the error message. Note that we don't treat fatal @@ -2517,7 +2518,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) copy->vcol_set= copy->def_vcol_set; } copy->tmp_set.bitmap= 0; // To catch errors - bzero((char*) bitmap, share->column_bitmap_size + (share->vfields ? 3 : 2)); + bzero((char*) bitmap, share->column_bitmap_size * (share->vfields ? 3 : 2)); copy->read_set= ©->def_read_set; copy->write_set= ©->def_write_set; @@ -2526,7 +2527,6 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) /* Got fatal error */ error: tables_in_use--; - status=1; mysql_cond_signal(&cond); // Inform thread about abort DBUG_RETURN(0); } @@ -2768,13 +2768,20 @@ bool Delayed_insert::open_and_lock_table() /* Use special prelocking strategy to get ER_DELAYED_NOT_SUPPORTED error for tables with engines which don't support delayed inserts. + + We can't do auto-repair in insert delayed thread, as it would hang + when trying to an exclusive MDL_LOCK on the table during repair + as the connection thread has a SHARED_WRITE lock. */ if (!(table= open_n_lock_single_table(&thd, &table_list, TL_WRITE_DELAYED, - MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK, + MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | + MYSQL_OPEN_IGNORE_REPAIR, &prelocking_strategy))) { - thd.fatal_error(); // Abort waiting inserts + /* If table was crashed, then upper level should retry open+repair */ + retry= table_list.crashed; + thd.fatal_error(); // Abort waiting inserts return TRUE; } -- cgit v1.2.1