diff options
author | sensssz <hjmsens@gmail.com> | 2016-10-22 10:19:41 -0400 |
---|---|---|
committer | sensssz <hjmsens@gmail.com> | 2016-10-22 10:19:41 -0400 |
commit | adaebd25ebc8d9a38214f543bf6bbee094a84e75 (patch) | |
tree | 2fd7fbfa9a5bbfc48e710867f58f57c089bf9227 | |
parent | 36841ac7991842d4efb4da4a62c919a4547f8190 (diff) | |
download | mariadb-git-adaebd25ebc8d9a38214f543bf6bbee094a84e75.tar.gz |
A few bug fixes. Use thd_is_slave_replication.
-rw-r--r-- | sql/rpl_parallel.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 2 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 117 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 6 |
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); } /****************************************************************//** |