summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsensssz <hjmsens@gmail.com>2016-10-22 10:19:41 -0400
committersensssz <hjmsens@gmail.com>2016-10-22 10:19:41 -0400
commitadaebd25ebc8d9a38214f543bf6bbee094a84e75 (patch)
tree2fd7fbfa9a5bbfc48e710867f58f57c089bf9227
parent36841ac7991842d4efb4da4a62c919a4547f8190 (diff)
downloadmariadb-git-adaebd25ebc8d9a38214f543bf6bbee094a84e75.tar.gz
A few bug fixes. Use thd_is_slave_replication.
-rw-r--r--sql/rpl_parallel.cc2
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h2
-rw-r--r--storage/innobase/include/trx0trx.h2
-rw-r--r--storage/innobase/lock/lock0lock.cc117
-rw-r--r--storage/innobase/trx/trx0trx.cc6
6 files changed, 91 insertions, 39 deletions
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index b794ddd0f90..f895fe39888 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -990,7 +990,6 @@ handle_rpl_parallel_thread(void *arg)
rpl_sql_thread_info sql_info(NULL);
int err;
- is_slave_replication = true;
struct rpl_parallel_thread *rpt= (struct rpl_parallel_thread *)arg;
my_thread_init();
@@ -1411,7 +1410,6 @@ handle_rpl_parallel_thread(void *arg)
mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
my_thread_end();
- is_slave_replication = false;
return NULL;
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index af0a369a23c..1af3b9a9cca 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -72,7 +72,6 @@
#include <sys/syscall.h>
#endif
-bool is_slave_replication = false;
/*
The following is used to initialise Table_ident with a internal
table name
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a068143f7c5..994a161a646 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -152,8 +152,6 @@ extern MYSQL_PLUGIN_IMPORT const char **errmesg;
extern bool volatile shutdown_in_progress;
-extern bool is_slave_replication;
-
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
extern "C" char **thd_query(MYSQL_THD thd);
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 42d59cb396f..19462b1d664 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1096,6 +1096,8 @@ struct trx_t {
time_t start_time; /*!< time the state last time became
TRX_STATE_ACTIVE */
+ clock_t start_time_micro; /*!< start time of the transaction
+ in microseconds. */
lsn_t commit_lsn; /*!< lsn at the time of the commit */
table_id_t table_id; /*!< Table to drop iff dict_operation
== TRX_DICT_OP_TABLE, or 0. */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index c18e3b8f60a..032f5271b43 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -53,6 +53,7 @@ Created 5/7/1996 Heikki Tuuri
#include "row0mysql.h"
#include "pars0pars.h"
+#include <inttypes.h>
#include <set>
#ifdef WITH_WSREP
@@ -1774,7 +1775,7 @@ has_higher_priority(
} else if (!lock_get_wait(lock2)) {
return false;
}
- return lock1->trx->start_time < lock2->trx->start_time;
+ return lock1->trx->start_time_micro <= lock2->trx->start_time_micro;
}
/*********************************************************************//**
@@ -1784,7 +1785,7 @@ If the lock is not a wait lock, insert it to the head of the hash list.
Otherwise, insert it to the middle of the wait locks according to the age of
the transaciton. */
static
-void
+dberr_t
lock_rec_insert_by_trx_age(
lock_t *in_lock) /*!< in: lock to be insert */{
ulint space;
@@ -1807,7 +1808,11 @@ lock_rec_insert_by_trx_age(
if (node == NULL || !lock_get_wait(in_lock) || has_higher_priority(in_lock, node)) {
cell->node = in_lock;
in_lock->hash = node;
- return;
+ if (lock_get_wait(in_lock)) {
+ lock_grant(in_lock, true);
+ return DB_SUCCESS_LOCKED_REC;
+ }
+ return DB_SUCCESS;
}
while (node != NULL && has_higher_priority((lock_t *) node->hash,
in_lock)) {
@@ -1816,6 +1821,20 @@ lock_rec_insert_by_trx_age(
next = (lock_t *) node->hash;
node->hash = in_lock;
in_lock->hash = next;
+
+ if (lock_get_wait(in_lock) && !lock_rec_has_to_wait_in_queue(in_lock)) {
+ lock_grant(in_lock, true);
+ if (cell->node != in_lock) {
+ // Move it to the front of the queue
+ node->hash = in_lock->hash;
+ next = (lock_t *) cell->node;
+ cell->node = in_lock;
+ in_lock->hash = next;
+ }
+ return DB_SUCCESS_LOCKED_REC;
+ }
+
+ return DB_SUCCESS;
}
static
@@ -1897,7 +1916,7 @@ RecLock::lock_add(lock_t* lock, bool add_to_hash)
++lock->index->table->n_rec_locks;
if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
- && !is_slave_replication) {
+ && !thd_is_replication_slave_thread(lock->trx->mysql_thd)) {
if (wait_lock) {
HASH_INSERT(lock_t, hash, lock_hash, key, lock);
} else {
@@ -2252,15 +2271,14 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
if (err != DB_DEADLOCK
&& innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
- && !is_slave_replication
+ && !thd_is_replication_slave_thread(lock->trx->mysql_thd)
&& !trx_is_high_priority(lock->trx)) {
HASH_DELETE(lock_t, hash, lock_hash_get(lock->type_mode),
m_rec_id.fold(), lock);
- lock_rec_insert_by_trx_age(lock);
- if (lock_get_wait(lock) && !lock_rec_has_to_wait_in_queue(lock)) {
- lock_grant(lock, true);
- return DB_SUCCESS_LOCKED_REC;
+ dberr_t res = lock_rec_insert_by_trx_age(lock);
+ if (res != DB_SUCCESS) {
+ return res;
}
}
@@ -2682,6 +2700,7 @@ lock_grant(
bool owns_trx_mutex) /*!< in: whether lock->trx->mutex is owned */
{
ut_ad(lock_mutex_own());
+ ut_ad(trx_mutex_own(lock->trx) == owns_trx_mutex);
lock_reset_lock_and_trx_wait(lock);
@@ -2999,11 +3018,26 @@ lock_grant_and_move_on_page(
previous = (lock_t *) hash_get_nth_cell(lock_hash,
hash_calc_hash(rec_fold, lock_hash))->node;
+ if (previous == NULL) {
+ return;
+ }
+ if (previous->un_member.rec_lock.space == space &&
+ previous->un_member.rec_lock.page_no == page_no) {
+ lock = previous;
+ }
+ else {
+ while (previous->hash &&
+ (previous->hash->un_member.rec_lock.space != space ||
+ previous->hash->un_member.rec_lock.page_no != page_no)) {
+ previous = previous->hash;
+ }
+ lock = previous->hash;
+ }
+
+ ut_ad(previous->hash == lock || previous == lock);
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
- for (lock = lock_rec_get_first_on_page_addr(lock_hash, space,
- page_no);
- lock != NULL;) {
+ for (;lock != NULL;) {
/* If the lock is a wait lock on this page, and it does not need to wait. */
if ((lock->un_member.rec_lock.space == space)
@@ -3011,20 +3045,21 @@ lock_grant_and_move_on_page(
&& lock_get_wait(lock)
&& !lock_rec_has_to_wait_in_queue(lock)) {
- bool exit_trx_mutex = false;
-
- if (lock->trx->abort_type != TRX_SERVER_ABORT) {
- ut_ad(trx_mutex_own(lock->trx));
- trx_mutex_exit(lock->trx);
- exit_trx_mutex = true;
- }
-
- lock_grant(lock, false);
-
- if (exit_trx_mutex) {
- ut_ad(!trx_mutex_own(lock->trx));
- trx_mutex_enter(lock->trx);
- }
+
+ bool exit_trx_mutex = false;
+
+ if (lock->trx->abort_type != TRX_SERVER_ABORT) {
+ ut_ad(trx_mutex_own(lock->trx));
+ trx_mutex_exit(lock->trx);
+ exit_trx_mutex = true;
+ }
+
+ lock_grant(lock, false);
+
+ if (exit_trx_mutex) {
+ ut_ad(!trx_mutex_own(lock->trx));
+ trx_mutex_enter(lock->trx);
+ }
if (previous != NULL) {
/* Move the lock to the head of the list. */
@@ -3084,9 +3119,14 @@ lock_rec_dequeue_from_page(
MONITOR_INC(MONITOR_RECLOCK_REMOVED);
MONITOR_DEC(MONITOR_NUM_RECLOCK);
+
+ /* Check if waiting locks in the queue can now be granted:
+ grant locks if there are no conflicting locks ahead. Stop at
+ the first X lock that is waiting or has been granted. */
if (innodb_lock_schedule_algorithm
- == INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS || is_slave_replication) {
+ == INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS ||
+ thd_is_replication_slave_thread(in_lock->trx->mysql_thd)) {
/* Check if waiting locks in the queue can now be granted:
grant locks if there are no conflicting locks ahead. Stop at
@@ -3121,7 +3161,7 @@ lock_rec_dequeue_from_page(
}
} else {
lock_grant_and_move_on_page(lock_hash, space, page_no);
- }
+ }
}
/*************************************************************//**
@@ -4974,9 +5014,21 @@ lock_grant_and_move_on_rec(
previous = (lock_t *) hash_get_nth_cell(lock_hash,
hash_calc_hash(rec_fold, lock_hash))->node;
+ if (previous == NULL) {
+ return;
+ }
+ if (previous == first_lock) {
+ lock = previous;
+ } else {
+ while (previous->hash &&
+ previous->hash != first_lock) {
+ previous = previous->hash;
+ }
+ lock = previous->hash;
+ }
/* Grant locks if there are no conflicting locks ahead.
Move granted locks to the head of the list. */
- for (lock = first_lock; lock != NULL;) {
+ for (;lock != NULL;) {
/* If the lock is a wait lock on this page, and it does not need to wait. */
if (lock->un_member.rec_lock.space == space
@@ -5065,7 +5117,8 @@ released:
lock_rec_reset_nth_bit(lock, heap_no);
if (innodb_lock_schedule_algorithm
- == INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS || is_slave_replication) {
+ == INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS ||
+ thd_is_replication_slave_thread(lock->trx->mysql_thd)) {
/* Check if we can now grant waiting lock requests */
@@ -5152,7 +5205,7 @@ lock_release(
ut_d(lock_check_dict_lock(lock));
if (lock_get_type_low(lock) == LOCK_REC) {
-
+
lock_rec_dequeue_from_page(lock);
} else {
dict_table_t* table;
@@ -8110,7 +8163,7 @@ DeadlockChecker::get_first_lock(ulint* heap_no) const
ut_a(lock != m_wait_lock ||
(innodb_lock_schedule_algorithm
== INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
- && !is_slave_replication));
+ && !thd_is_replication_slave_thread(lock->trx->mysql_thd)));
/* Check that the lock type doesn't change. */
ut_ad(lock_get_type_low(lock) == lock_get_type_low(m_wait_lock));
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 6869aae9d67..34794ebb1da 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -60,6 +60,7 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0pool.h"
#include "ut0vec.h"
+#include <inttypes.h>
#include <set>
#include <new>
@@ -1444,7 +1445,7 @@ trx_start_low(
ut_ad(trx_sys_validate_trx_list());
- trx_sys_mutex_exit();
+ trx_sys_mutex_exit();
} else {
trx->id = 0;
@@ -1484,10 +1485,11 @@ trx_start_low(
} else {
trx->start_time = ut_time();
}
+ trx->start_time_micro = clock();
ut_a(trx->error_state == DB_SUCCESS);
- MONITOR_INC(MONITOR_TRX_ACTIVE);
+ MONITOR_INC(MONITOR_TRX_ACTIVE);
}
/****************************************************************//**