Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

MYSQL-15: Implement server-side statement timeout support

Allow threads waiting inside a storage engine to be interrupted if
the connection or statement is terminated. This is a prerequisite
for implementing server-side statement timeout support with
granularity of milliseconds. For example, due to the way that the
InnoDB background lock timeout thread works, interrupted transactions
are only detected once every second.
  • Loading branch information...
commit d1c50c6704b1732fb6d33e2d0309cb13204e2032 1 parent 7d0453f
authored February 25, 2012
18  sql/handler.cc
@@ -651,6 +651,24 @@ void ha_close_connection(THD* thd)
651 651
   plugin_foreach(thd, closecon_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
652 652
 }
653 653
 
  654
+static my_bool kill_handlerton(THD *thd, plugin_ref plugin, void *)
  655
+{
  656
+  handlerton *hton= plugin_data(plugin, handlerton *);
  657
+
  658
+  if (hton->state == SHOW_OPTION_YES && hton->kill_connection)
  659
+  {
  660
+    if (thd_get_ha_data(thd, hton))
  661
+      hton->kill_connection(hton, thd);
  662
+  }
  663
+
  664
+  return FALSE;
  665
+}
  666
+
  667
+void ha_kill_connection(THD *thd)
  668
+{
  669
+  plugin_foreach(thd, kill_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, 0);
  670
+}
  671
+
654 672
 /* ========================================================================
655 673
  ======================= TRANSACTIONS ===================================*/
656 674
 
4  sql/handler.h
@@ -788,6 +788,9 @@ struct handlerton
788 788
    longlong (*control)(handlerton *hton, const char *cmd,
789 789
                        Item **args, uint arg_count);
790 790
 
  791
+   /* Terminate connection/statement notification. */
  792
+   void (*kill_connection)(handlerton *hton, THD *thd);
  793
+
791 794
    /*
792 795
      Iterators creator.
793 796
      Presence of the pointer should be checked before using
@@ -2222,6 +2225,7 @@ int ha_finalize_handlerton(st_plugin_int *plugin);
2222 2225
 TYPELIB *ha_known_exts(void);
2223 2226
 int ha_panic(enum ha_panic_function flag);
2224 2227
 void ha_close_connection(THD* thd);
  2228
+void ha_kill_connection(THD *thd);
2225 2229
 bool ha_flush_logs(handlerton *db_type);
2226 2230
 void ha_drop_database(char* path);
2227 2231
 int ha_create_table(THD *thd, const char *path,
4  sql/sql_class.cc
@@ -1483,6 +1483,10 @@ void THD::awake(THD::killed_state state_to_set)
1483 1483
       MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (this));
1484 1484
   }
1485 1485
 
  1486
+  /* Interrupt target waiting inside a storage engine. */
  1487
+  if (state_to_set != THD::NOT_KILLED)
  1488
+    ha_kill_connection(this);
  1489
+
1486 1490
   /* Broadcast a condition to kick the target if it is waiting on it. */
1487 1491
   if (mysys_var)
1488 1492
   {
31  storage/innobase/handler/ha_innodb.cc
@@ -340,6 +340,7 @@ static PSI_file_info	all_innodb_files[] = {
340 340
 static INNOBASE_SHARE *get_share(const char *table_name);
341 341
 static void free_share(INNOBASE_SHARE *share);
342 342
 static int innobase_close_connection(handlerton *hton, THD* thd);
  343
+static void innobase_kill_connection(handlerton *hton, THD* thd);
343 344
 static int innobase_commit(handlerton *hton, THD* thd, bool all);
344 345
 static int innobase_rollback(handlerton *hton, THD* thd, bool all);
345 346
 static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
@@ -2277,6 +2278,7 @@ innobase_init(
2277 2278
         innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
2278 2279
 	innobase_hton->alter_table_flags = innobase_alter_table_flags;
2279 2280
 	innobase_hton->control = innobase_control;
  2281
+	innobase_hton->kill_connection = innobase_kill_connection;
2280 2282
 
2281 2283
 	ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
2282 2284
 
@@ -3230,6 +3232,35 @@ innobase_close_connection(
3230 3232
 	DBUG_RETURN(0);
3231 3233
 }
3232 3234
 
  3235
+/*****************************************************************//**
  3236
+Cancel any pending lock request associated with the current THD. */
  3237
+static
  3238
+void
  3239
+innobase_kill_connection(
  3240
+/*======================*/
  3241
+        handlerton*	hton,	/*!< in:  innobase handlerton */
  3242
+	THD*	thd)	/*!< in: handle to the MySQL thread being killed */
  3243
+{
  3244
+	trx_t*	trx;
  3245
+
  3246
+	DBUG_ENTER("innobase_kill_connection");
  3247
+	DBUG_ASSERT(hton == innodb_hton_ptr);
  3248
+
  3249
+	mutex_enter(&kernel_mutex);
  3250
+
  3251
+	trx = thd_to_trx(thd);
  3252
+
  3253
+	/* Cancel a pending lock request. */
  3254
+	if (trx && trx->wait_lock) {
  3255
+
  3256
+		lock_cancel_waiting_and_release(trx->wait_lock);
  3257
+	}
  3258
+
  3259
+	mutex_exit(&kernel_mutex);
  3260
+
  3261
+	DBUG_VOID_RETURN;
  3262
+}
  3263
+
3233 3264
 
3234 3265
 /*************************************************************************//**
3235 3266
 ** InnoDB database tables

0 notes on commit d1c50c6

Please sign in to comment.
Something went wrong with that request. Please try again.