Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
a24e6258
Commit
a24e6258
authored
Oct 23, 2016
by
sensssz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change all space indentions to tab.
parent
fd30d07f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
278 additions
and
280 deletions
+278
-280
storage/innobase/include/lock0lock.h
storage/innobase/include/lock0lock.h
+5
-5
storage/innobase/lock/lock0lock.cc
storage/innobase/lock/lock0lock.cc
+270
-271
storage/innobase/trx/trx0trx.cc
storage/innobase/trx/trx0trx.cc
+3
-4
No files found.
storage/innobase/include/lock0lock.h
View file @
a24e6258
...
...
@@ -41,12 +41,12 @@ Created 5/7/1996 Heikki Tuuri
#include "lock0prdt.h"
/** Alternatives for innodb_lock_schedule_algorithm, which can be changed by
setting innodb_lock_schedule_algorithm. */
setting innodb_lock_schedule_algorithm. */
enum
innodb_lock_schedule_algorithm_t
{
/*!< First Come First Served */
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
,
/*!< Variance-Aware-Transaction-Scheduling */
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
/*!< First Come First Served */
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
,
/*!< Variance-Aware-Transaction-Scheduling */
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
};
extern
ulong
innodb_lock_schedule_algorithm
;
...
...
storage/innobase/lock/lock0lock.cc
View file @
a24e6258
...
...
@@ -81,7 +81,7 @@ static
const
lock_t
*
lock_rec_has_to_wait_in_queue
(
/*==========================*/
const
lock_t
*
wait_lock
);
/*!< in: waiting record lock */
const
lock_t
*
wait_lock
);
/*!< in: waiting record lock */
/*************************************************************//**
Grants a lock to a waiting lock request and releases the waiting transaction.
...
...
@@ -91,7 +91,7 @@ void
lock_grant
(
/*=======*/
lock_t
*
lock
,
/*!< in/out: waiting lock request */
bool
owns_trx_mutex
);
/*!< in: whether lock->trx->mutex is owned */
bool
owns_trx_mutex
);
/*!< in: whether lock->trx->mutex is owned */
extern
"C"
void
thd_rpl_deadlock_check
(
MYSQL_THD
thd
,
MYSQL_THD
other_thd
);
extern
"C"
int
thd_need_wait_reports
(
const
MYSQL_THD
thd
);
...
...
@@ -1778,19 +1778,19 @@ the transaciton. */
static
dberr_t
lock_rec_insert_by_trx_age
(
lock_t
*
in_lock
)
/*!< in: lock to be insert */
{
lock_t
*
in_lock
)
/*!< in: lock to be insert */
{
ulint
space
;
ulint
page_no
;
ulint
rec_fold
;
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
lock_t
*
node
;
lock_t
*
next
;
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
space
=
in_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
in_lock
->
un_member
.
rec_lock
.
page_no
;
space
=
in_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
in_lock
->
un_member
.
rec_lock
.
page_no
;
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
cell
=
hash_get_nth_cell
(
hash
,
hash_calc_hash
(
rec_fold
,
hash
));
...
...
@@ -1799,10 +1799,10 @@ 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
;
if
(
lock_get_wait
(
in_lock
))
{
lock_grant
(
in_lock
,
true
);
return
DB_SUCCESS_LOCKED_REC
;
}
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
,
...
...
@@ -1811,81 +1811,81 @@ 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
;
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
bool
lock_queue_validate
(
const
lock_t
*
in_lock
)
/*!< in: lock whose hash list is to be validated */
{
ulint
space
;
ulint
page_no
;
ulint
rec_fold
;
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
lock_t
*
next
;
bool
wait_lock
=
false
;
if
(
in_lock
==
NULL
)
{
return
true
;
}
space
=
in_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
in_lock
->
un_member
.
rec_lock
.
page_no
;
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
cell
=
hash_get_nth_cell
(
hash
,
hash_calc_hash
(
rec_fold
,
hash
));
next
=
(
lock_t
*
)
cell
->
node
;
while
(
next
!=
NULL
)
{
// If this is a granted lock, check that there's no wait lock before it.
if
(
!
lock_get_wait
(
next
))
{
ut_ad
(
!
wait_lock
);
}
else
{
wait_lock
=
true
;
}
next
=
next
->
hash
;
}
return
true
;
const
lock_t
*
in_lock
)
/*!< in: lock whose hash list is to be validated */
{
ulint
space
;
ulint
page_no
;
ulint
rec_fold
;
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
lock_t
*
next
;
bool
wait_lock
=
false
;
if
(
in_lock
==
NULL
)
{
return
true
;
}
space
=
in_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
in_lock
->
un_member
.
rec_lock
.
page_no
;
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
cell
=
hash_get_nth_cell
(
hash
,
hash_calc_hash
(
rec_fold
,
hash
));
next
=
(
lock_t
*
)
cell
->
node
;
while
(
next
!=
NULL
)
{
// If this is a granted lock, check that there's no wait lock before it.
if
(
!
lock_get_wait
(
next
))
{
ut_ad
(
!
wait_lock
);
}
else
{
wait_lock
=
true
;
}
next
=
next
->
hash
;
}
return
true
;
}
static
void
lock_rec_insert_to_head
(
lock_t
*
in_lock
,
/*!< in: lock to be insert */
ulint
rec_fold
)
/*!< in: rec_fold of the page */
{
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
lock_t
*
node
;
if
(
in_lock
==
NULL
)
{
return
;
}
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
cell
=
hash_get_nth_cell
(
hash
,
hash_calc_hash
(
rec_fold
,
hash
));
node
=
(
lock_t
*
)
cell
->
node
;
if
(
node
!=
in_lock
)
{
cell
->
node
=
in_lock
;
in_lock
->
hash
=
node
;
}
ulint
rec_fold
)
/*!< in: rec_fold of the page */
{
hash_table_t
*
hash
;
hash_cell_t
*
cell
;
lock_t
*
node
;
if
(
in_lock
==
NULL
)
{
return
;
}
hash
=
lock_hash_get
(
in_lock
->
type_mode
);
cell
=
hash_get_nth_cell
(
hash
,
hash_calc_hash
(
rec_fold
,
hash
));
node
=
(
lock_t
*
)
cell
->
node
;
if
(
node
!=
in_lock
)
{
cell
->
node
=
in_lock
;
in_lock
->
hash
=
node
;
}
}
/**
...
...
@@ -1897,25 +1897,25 @@ RecLock::lock_add(lock_t* lock, bool add_to_hash)
{
ut_ad
(
lock_mutex_own
());
ut_ad
(
trx_mutex_own
(
lock
->
trx
));
bool
wait_lock
=
m_mode
&
LOCK_WAIT
;
bool
wait_lock
=
m_mode
&
LOCK_WAIT
;
if
(
add_to_hash
)
{
ulint
key
=
m_rec_id
.
fold
();
hash_table_t
*
lock_hash
=
lock_hash_get
(
m_mode
);
hash_table_t
*
lock_hash
=
lock_hash_get
(
m_mode
);
++
lock
->
index
->
table
->
n_rec_locks
;
if
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&&
!
thd_is_replication_slave_thread
(
lock
->
trx
->
mysql_thd
))
{
if
(
wait_lock
)
{
HASH_INSERT
(
lock_t
,
hash
,
lock_hash
,
key
,
lock
);
}
else
{
lock_rec_insert_to_head
(
lock
,
m_rec_id
.
fold
());
}
}
else
{
HASH_INSERT
(
lock_t
,
hash
,
lock_hash
,
key
,
lock
);
}
if
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&&
!
thd_is_replication_slave_thread
(
lock
->
trx
->
mysql_thd
))
{
if
(
wait_lock
)
{
HASH_INSERT
(
lock_t
,
hash
,
lock_hash
,
key
,
lock
);
}
else
{
lock_rec_insert_to_head
(
lock
,
m_rec_id
.
fold
());
}
}
else
{
HASH_INSERT
(
lock_t
,
hash
,
lock_hash
,
key
,
lock
);
}
}
if
(
wait_lock
)
{
...
...
@@ -2257,21 +2257,21 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
dberr_t
err
=
deadlock_check
(
lock
);
ut_ad
(
trx_mutex_own
(
m_trx
));
// Move it only when it does not cause a deadlock.
if
(
err
!=
DB_DEADLOCK
&&
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&&
!
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
);
dberr_t
res
=
lock_rec_insert_by_trx_age
(
lock
);
if
(
res
!=
DB_SUCCESS
)
{
return
res
;
}
}
// Move it only when it does not cause a deadlock.
if
(
err
!=
DB_DEADLOCK
&&
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&&
!
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
);
dberr_t
res
=
lock_rec_insert_by_trx_age
(
lock
);
if
(
res
!=
DB_SUCCESS
)
{
return
res
;
}
}
return
(
err
);
}
...
...
@@ -2688,16 +2688,16 @@ void
lock_grant
(
/*=======*/
lock_t
*
lock
,
/*!< in/out: waiting lock request */
bool
owns_trx_mutex
)
/*!< in: whether lock->trx->mutex is owned */
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
);
ut_ad
(
trx_mutex_own
(
lock
->
trx
)
==
owns_trx_mutex
);
lock_reset_lock_and_trx_wait
(
lock
);
if
(
!
owns_trx_mutex
)
{
trx_mutex_enter
(
lock
->
trx
);
}
if
(
!
owns_trx_mutex
)
{
trx_mutex_enter
(
lock
->
trx
);
}
if
(
lock_get_mode
(
lock
)
==
LOCK_AUTO_INC
)
{
dict_table_t
*
table
=
lock
->
un_member
.
tab_lock
.
table
;
...
...
@@ -2730,9 +2730,9 @@ lock_grant(
}
}
if
(
!
owns_trx_mutex
)
{
trx_mutex_exit
(
lock
->
trx
);
}
if
(
!
owns_trx_mutex
)
{
trx_mutex_exit
(
lock
->
trx
);
}
}
/**
...
...
@@ -2999,74 +2999,73 @@ lock_rec_cancel(
static
void
lock_grant_and_move_on_page
(
hash_table_t
*
lock_hash
,
ulint
space
,
ulint
page_no
)
{
lock_t
*
lock
;
lock_t
*
previous
;
ulint
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
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
!=
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
)
&&
(
lock
->
un_member
.
rec_lock
.
page_no
==
page_no
)
&&
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
);
}
if
(
previous
!=
NULL
)
{
/* Move the lock to the head of the list. */
HASH_GET_NEXT
(
hash
,
previous
)
=
HASH_GET_NEXT
(
hash
,
lock
);
lock_rec_insert_to_head
(
lock
,
rec_fold
);
}
else
{
/* Already at the head of the list. */
previous
=
lock
;
}
/* Move on to the next lock. */
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
previous
));
}
else
{
previous
=
lock
;
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
lock
));
}
}
hash_table_t
*
lock_hash
,
ulint
space
,
ulint
page_no
)
{
lock_t
*
lock
;
lock_t
*
previous
;
ulint
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
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
!=
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
)
&&
(
lock
->
un_member
.
rec_lock
.
page_no
==
page_no
)
&&
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
);
}
if
(
previous
!=
NULL
)
{
/* Move the lock to the head of the list. */
HASH_GET_NEXT
(
hash
,
previous
)
=
HASH_GET_NEXT
(
hash
,
lock
);
lock_rec_insert_to_head
(
lock
,
rec_fold
);
}
else
{
/* Already at the head of the list. */
previous
=
lock
;
}
/* Move on to the next lock. */
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
previous
));
}
else
{
previous
=
lock
;
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
lock
));
}
}
}
/*************************************************************//**
...
...
@@ -3104,20 +3103,20 @@ lock_rec_dequeue_from_page(
lock_hash
=
lock_hash_get
(
in_lock
->
type_mode
);
HASH_DELETE
(
lock_t
,
hash
,
lock_hash
,
lock_rec_fold
(
space
,
page_no
),
in_lock
);
lock_rec_fold
(
space
,
page_no
),
in_lock
);
UT_LIST_REMOVE
(
trx_lock
->
trx_locks
,
in_lock
);
MONITOR_INC
(
MONITOR_RECLOCK_REMOVED
);
MONITOR_DEC
(
MONITOR_NUM_RECLOCK
);
/* Check if waiting locks in the queue can now be granted:
/* 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
||
thd_is_replication_slave_thread
(
in_lock
->
trx
->
mysql_thd
))
{
==
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
...
...
@@ -3125,11 +3124,11 @@ lock_rec_dequeue_from_page(
for
(
lock
=
lock_rec_get_first_on_page_addr
(
lock_hash
,
space
,
page_no
);
lock
!=
NULL
;
lock
=
lock_rec_get_next_on_page
(
lock
))
{
lock
!=
NULL
;
lock
=
lock_rec_get_next_on_page
(
lock
))
{
if
(
lock_get_wait
(
lock
)
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
/* Grant the lock */
ut_ad
(
lock
->
trx
!=
in_lock
->
trx
);
...
...
@@ -3150,9 +3149,9 @@ lock_rec_dequeue_from_page(
}
}
}
}
else
{
lock_grant_and_move_on_page
(
lock_hash
,
space
,
page_no
);
}
}
else
{
lock_grant_and_move_on_page
(
lock_hash
,
space
,
page_no
);
}
}
/*************************************************************//**
...
...
@@ -4989,62 +4988,62 @@ lock_table_for_trx(
static
void
lock_grant_and_move_on_rec
(
hash_table_t
*
lock_hash
,
lock_t
*
first_lock
,
ulint
heap_no
)
{
lock_t
*
lock
;
lock_t
*
previous
;
ulint
space
;
ulint
page_no
;
ulint
rec_fold
;
space
=
first_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
first_lock
->
un_member
.
rec_lock
.
page_no
;
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
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
!=
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
&&
lock
->
un_member
.
rec_lock
.
page_no
==
page_no
&&
lock_rec_get_nth_bit
(
lock
,
heap_no
)
&&
lock_get_wait
(
lock
)
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
lock_grant
(
lock
,
false
);
if
(
previous
!=
NULL
)
{
/* Move the lock to the head of the list. */
HASH_GET_NEXT
(
hash
,
previous
)
=
HASH_GET_NEXT
(
hash
,
lock
);
lock_rec_insert_to_head
(
lock
,
rec_fold
);
}
else
{
/* Already at the head of the list. */
previous
=
lock
;
}
/* Move on to the next lock. */
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
previous
));
}
else
{
previous
=
lock
;
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
lock
));
}
}
hash_table_t
*
lock_hash
,
lock_t
*
first_lock
,
ulint
heap_no
)
{
lock_t
*
lock
;
lock_t
*
previous
;
ulint
space
;
ulint
page_no
;
ulint
rec_fold
;
space
=
first_lock
->
un_member
.
rec_lock
.
space
;
page_no
=
first_lock
->
un_member
.
rec_lock
.
page_no
;
rec_fold
=
lock_rec_fold
(
space
,
page_no
);
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
!=
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
&&
lock
->
un_member
.
rec_lock
.
page_no
==
page_no
&&
lock_rec_get_nth_bit
(
lock
,
heap_no
)
&&
lock_get_wait
(
lock
)
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
lock_grant
(
lock
,
false
);
if
(
previous
!=
NULL
)
{
/* Move the lock to the head of the list. */
HASH_GET_NEXT
(
hash
,
previous
)
=
HASH_GET_NEXT
(
hash
,
lock
);
lock_rec_insert_to_head
(
lock
,
rec_fold
);
}
else
{
/* Already at the head of the list. */
previous
=
lock
;
}
/* Move on to the next lock. */
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
previous
));
}
else
{
previous
=
lock
;
lock
=
static_cast
<
lock_t
*>
(
HASH_GET_NEXT
(
hash
,
lock
));
}
}
}
/*************************************************************//**
...
...
@@ -5106,26 +5105,26 @@ lock_rec_unlock(
released:
ut_a
(
!
lock_get_wait
(
lock
));
lock_rec_reset_nth_bit
(
lock
,
heap_no
);
if
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
||
thd_is_replication_slave_thread
(
lock
->
trx
->
mysql_thd
))
{
/* Check if we can now grant waiting lock requests */
for
(
lock
=
first_lock
;
lock
!=
NULL
;
lock
=
lock_rec_get_next
(
heap_no
,
lock
))
{
if
(
lock_get_wait
(
lock
)
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
/* Grant the lock */
ut_ad
(
trx
!=
lock
->
trx
);
lock_grant
(
lock
,
false
);
}
}
}
else
{
lock_grant_and_move_on_rec
(
lock_sys
->
rec_hash
,
first_lock
,
heap_no
);
}
if
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
||
thd_is_replication_slave_thread
(
lock
->
trx
->
mysql_thd
))
{
/* Check if we can now grant waiting lock requests */
for
(
lock
=
first_lock
;
lock
!=
NULL
;
lock
=
lock_rec_get_next
(
heap_no
,
lock
))
{
if
(
lock_get_wait
(
lock
)
&&
!
lock_rec_has_to_wait_in_queue
(
lock
))
{
/* Grant the lock */
ut_ad
(
trx
!=
lock
->
trx
);
lock_grant
(
lock
,
false
);
}
}
}
else
{
lock_grant_and_move_on_rec
(
lock_sys
->
rec_hash
,
first_lock
,
heap_no
);
}
lock_mutex_exit
();
trx_mutex_exit
(
trx
);
...
...
@@ -6358,9 +6357,9 @@ lock_rec_queue_validate(
ut_a
(
lock_rec_has_to_wait_in_queue
(
lock
));
}
}
ut_ad
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
||
lock_queue_validate
(
lock
));
ut_ad
(
innodb_lock_schedule_algorithm
==
INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS
||
lock_queue_validate
(
lock
));
func_exit:
if
(
!
locked_lock_trx_sys
)
{
...
...
storage/innobase/trx/trx0trx.cc
View file @
a24e6258
...
...
@@ -60,7 +60,6 @@ Created 3/26/1996 Heikki Tuuri
#include "ut0pool.h"
#include "ut0vec.h"
#include <inttypes.h>
#include <set>
#include <new>
...
...
@@ -1445,7 +1444,7 @@ trx_start_low(
ut_ad
(
trx_sys_validate_trx_list
());
trx_sys_mutex_exit
();
trx_sys_mutex_exit
();
}
else
{
trx
->
id
=
0
;
...
...
@@ -1485,11 +1484,11 @@ trx_start_low(
}
else
{
trx
->
start_time
=
ut_time
();
}
trx
->
start_time_micro
=
clock
();
trx
->
start_time_micro
=
clock
();
ut_a
(
trx
->
error_state
==
DB_SUCCESS
);
MONITOR_INC
(
MONITOR_TRX_ACTIVE
);
MONITOR_INC
(
MONITOR_TRX_ACTIVE
);
}
/****************************************************************//**
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment