[Commits] Rev 4593: MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded in file:///home/psergey/dev2/mysql-5.6-leveldb/

Sergey Petrunya psergey at askmonty.org
Wed Feb 6 16:26:17 EET 2013


At file:///home/psergey/dev2/mysql-5.6-leveldb/

------------------------------------------------------------
revno: 4593
revision-id: psergey at askmonty.org-20130206142615-mzp7p1m169dx2tu2
parent: psergey at askmonty.org-20130204080738-baj6zjdpkhrpmucw
committer: Sergey Petrunya <psergey at askmonty.org>
branch nick: mysql-5.6-leveldb
timestamp: Wed 2013-02-06 18:26:15 +0400
message:
  MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded
  - Use interruptible sleep and check if the query is killed.
=== modified file 'mysql-test/r/leveldb.result'
--- a/mysql-test/r/leveldb.result	2013-02-01 17:50:22 +0000
+++ b/mysql-test/r/leveldb.result	2013-02-06 14:26:15 +0000
@@ -839,3 +839,26 @@ set autocommit=0;
 truncate table t48;
 set autocommit=1;
 drop table t48;
+#
+# MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded
+#
+create table t49 (pk int primary key, a int) engine=LevelDB;
+insert into t49 values (1,10),(2,20);
+begin;
+update t49 set a = 100 where pk = 1;
+connect  con1,localhost,root,,;
+set leveldb_lock_wait_timeout=5000;
+set @var1= to_seconds(now());
+update t49 set a = 1000 where pk = 1;
+connect  con2,localhost,root,,;
+kill query 5;
+connection con1;
+ERROR 70100: Query execution was interrupted
+set @var2= to_seconds(now());
+select (@var2 - at var1) < 400;
+(@var2 - at var1) < 400
+1
+connection default;
+disconnect con1;
+commit;
+drop table t49;

=== modified file 'mysql-test/t/leveldb.test'
--- a/mysql-test/t/leveldb.test	2013-02-01 17:50:22 +0000
+++ b/mysql-test/t/leveldb.test	2013-02-06 14:26:15 +0000
@@ -738,4 +738,33 @@ truncate table t48;
 set autocommit=1;
 drop table t48;
 
+--echo #
+--echo # MDEV-4059: LevelDB: query waiting for a lock cannot be killed until query timeout exceeded
+--echo #
+--enable_connect_log
 
+create table t49 (pk int primary key, a int) engine=LevelDB;
+insert into t49 values (1,10),(2,20);
+begin;
+update t49 set a = 100 where pk = 1;
+
+--connect (con1,localhost,root,,)
+--let $con1_id = `SELECT CONNECTION_ID()`
+set leveldb_lock_wait_timeout=5000;
+set @var1= to_seconds(now());
+send update t49 set a = 1000 where pk = 1;
+
+--connect (con2,localhost,root,,)
+eval kill query $con1_id;
+--connection con1
+--error ER_QUERY_INTERRUPTED
+--reap
+set @var2= to_seconds(now());
+
+select (@var2 - at var1) < 400;
+
+--connection default
+--disconnect con1
+
+commit;
+drop table t49;

=== modified file 'storage/leveldb/ha_leveldb.cc'
--- a/storage/leveldb/ha_leveldb.cc	2013-02-04 08:07:38 +0000
+++ b/storage/leveldb/ha_leveldb.cc	2013-02-06 14:26:15 +0000
@@ -97,7 +97,6 @@ static SHOW_VAR leveldb_status_variables
 
 ///////////////////////////////////////////////////////////////////////////////////////////
 
-
 /**
   @brief
   Function we use in the creation of our hash to get key.
@@ -119,6 +118,16 @@ static PSI_mutex_info all_leveldb_mutexe
   { &ex_key_mutex_LEVELDB_SHARE_mutex, "LEVELDB_SHARE::mutex", 0}
 };
 
+#ifdef HAVE_PSI_INTERFACE
+PSI_stage_info stage_waiting_on_row_lock= { 0, "Waiting for row lock", 0};
+
+static PSI_stage_info *all_leveldb_stages[]=
+{
+  & stage_waiting_on_row_lock
+};
+#endif
+
+
 static void init_leveldb_psi_keys()
 {
   const char* category= "leveldb";
@@ -129,6 +138,9 @@ static void init_leveldb_psi_keys()
 
   count= array_elements(all_leveldb_mutexes);
   PSI_server->register_mutex(category, all_leveldb_mutexes, count);
+
+  count= array_elements(all_leveldb_stages);
+  mysql_stage_register(category, all_leveldb_stages, count);
 }
 #endif
 
@@ -2465,4 +2477,3 @@ ulong Primary_key_comparator::get_hashnr
   return((ulong) nr);
 }
 
-

=== modified file 'storage/leveldb/ha_leveldb.h'
--- a/storage/leveldb/ha_leveldb.h	2013-02-01 17:50:22 +0000
+++ b/storage/leveldb/ha_leveldb.h	2013-02-06 14:26:15 +0000
@@ -29,6 +29,17 @@
 
 #include "sql_string.h"
 
+#ifdef HAVE_PSI_INTERFACE
+extern PSI_stage_info stage_waiting_on_row_lock;
+
+extern "C"
+void thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, mysql_mutex_t *mutex,
+                    const PSI_stage_info *stage, PSI_stage_info *old_stage);
+extern "C"
+void thd_exit_cond(MYSQL_THD thd, const PSI_stage_info *stage);
+
+#endif
+
 /** @brief
   LEVELDB_SHARE is a structure that will be shared among all open handlers.
   This example implements the minimum of what you will probably need.

=== modified file 'storage/leveldb/ldb_locks.cc'
--- a/storage/leveldb/ldb_locks.cc	2013-01-25 11:09:37 +0000
+++ b/storage/leveldb/ldb_locks.cc	2013-02-06 14:26:15 +0000
@@ -87,10 +87,6 @@ void LockTable::cleanup()
   lf_hash_destroy(&lf_hash);
 }
 
-#ifdef WITH_PERFORMANCE_SCHEMA
-//PSI_stage_info stage_leveldb_lock= { 0, "leveldb lock", 0};
-#endif
-
 
 /*
   Get a lock for given row
@@ -199,16 +195,21 @@ Row_lock* LockTable::get_lock(LF_PINS *p
 
       struct timespec wait_timeout;
       set_timespec(wait_timeout, timeout_sec);
-#ifdef WITH_PERFORMANCE_SCHEMA
-  //    PSI_stage_info old_stage;
-  //    caller_thd->ENTER_COND(&found_lock->cond, found_lock->mutex,
-  //                           &stage_show_explain, &old_stage);
+#ifdef HAVE_PSI_INTERFACE
+      THD *thd= current_thd;
+      PSI_stage_info old_stage;
+      thd_enter_cond(thd, &found_lock->cond, &found_lock->mutex,
+                     &stage_waiting_on_row_lock, &old_stage);
 #endif
       while (found_lock->busy)
       {
         res= mysql_cond_timedwait(&found_lock->cond, &found_lock->mutex, 
                                   &wait_timeout);
-        if (res == ETIMEDOUT)
+        bool killed= false;
+#ifdef HAVE_PSI_INTERFACE
+        killed= thd_killed(thd);
+#endif
+        if (res == ETIMEDOUT || killed)
         {
           if (found_lock->busy)
           {
@@ -224,9 +225,6 @@ Row_lock* LockTable::get_lock(LF_PINS *p
           fprintf(stderr, "wait failed: %d\n", res);
       }
       
-#ifdef WITH_PERFORMANCE_SCHEMA
-  //    caller_thd->EXIT_COND(&old_stage);
-#endif
       /*
         Ok, now we own the mutex again, and the lock is released. Take it.
       */
@@ -234,7 +232,12 @@ Row_lock* LockTable::get_lock(LF_PINS *p
       found_lock->busy= 1;
       found_lock->owner_data= pins;
       found_lock->waiters--; // we're not waiting anymore
+#ifdef HAVE_PSI_INTERFACE
+      // caller_thd->EXIT_COND(&old_stage);
+      thd_exit_cond(thd, &old_stage);
+#else
       mysql_mutex_unlock(&found_lock->mutex);
+#endif
     }
   }
 



More information about the commits mailing list