Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 3b40432

Browse files
PushapglHerman Lee
authored andcommitted
Disable concurrency ticket when ACL CACHE lock is acquired in exclusive mode
Summary: **Summary** When workload is overloaded with operations that require innodb concurrency ticket(like lot of inserts), critical operations like create user, drop user gets stuck waiting for concurrency ticket. In addition to innodb concurrency ticket, operations like create user, drop user, etc also holds the ACL CACHE lock in MDL_EXCLUSIVE mode which further slows down workload. Added a change to skip waiting for concurrency ticket if the we are already holding ACL CACHE lock in MDL_EXCLUSIVE mode. Reviewed By: hermanlee Differential Revision: D30683406
1 parent 0f566bd commit 3b40432

8 files changed

Lines changed: 77 additions & 2 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CREATE TABLE tbl1 (
2+
col1_1 INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
3+
col1_2 INT NOT NULL,
4+
col1_3 INT NOT NULL,
5+
col1_4 INT NOT NULL);
6+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (2, 3, 4);
7+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (3, 4, 5);
8+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (4, 5, 6);
9+
include/assert.inc [Increase in Innodb_concurrency_ticket_skip_count should be 0]
10+
CREATE USER user1;
11+
include/assert.inc [Increase in Innodb_concurrency_ticket_skip_count should be > 0]
12+
DROP USER user1;
13+
include/assert.inc [Increase in Innodb_concurrency_ticket_skip_count should be > 0]
14+
DROP TABLE tbl1;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Check concurrency ticket is not skipped with regular inserts
2+
3+
let $old_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
4+
CREATE TABLE tbl1 (
5+
col1_1 INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
6+
col1_2 INT NOT NULL,
7+
col1_3 INT NOT NULL,
8+
col1_4 INT NOT NULL);
9+
10+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (2, 3, 4);
11+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (3, 4, 5);
12+
INSERT INTO tbl1 (col1_2, col1_3, col1_4) VALUES (4, 5, 6);
13+
let $new_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
14+
--let $assert_cond= $new_concurrency_ticket_skip_count - $old_concurrency_ticket_skip_count = 0
15+
--let $assert_text= Increase in Innodb_concurrency_ticket_skip_count should be 0
16+
--source include/assert.inc
17+
18+
19+
# Check concurrency ticket is skipped with commands
20+
# which acquire ACL_CACHE_LOCK with EXCLUSIVE MODE
21+
22+
let $old_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
23+
CREATE USER user1;
24+
let $new_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
25+
--let $assert_cond= $new_concurrency_ticket_skip_count - $old_concurrency_ticket_skip_count > 0
26+
--let $assert_text= Increase in Innodb_concurrency_ticket_skip_count should be > 0
27+
--source include/assert.inc
28+
29+
let $old_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
30+
DROP USER user1;
31+
let $new_concurrency_ticket_skip_count= query_get_value(show status like "Innodb_concurrency_ticket_skip_count", Value, 1);
32+
--let $assert_cond= $new_concurrency_ticket_skip_count - $old_concurrency_ticket_skip_count > 0
33+
--let $assert_text= Increase in Innodb_concurrency_ticket_skip_count should be > 0
34+
--source include/assert.inc
35+
36+
DROP TABLE tbl1;

‎sql/auth/auth_common.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,10 @@ void acl_log_connect(const char *user, const char *host, const char *auth_as,
716716
int acl_authenticate(THD *thd, enum_server_command command);
717717
bool acl_check_host(THD *thd, const char *host, const char *ip);
718718

719+
/* sql_auth_cache */
720+
bool assert_acl_cache_read_lock(THD *thd);
721+
bool assert_acl_cache_write_lock(THD *thd);
722+
719723
/*
720724
User Attributes are the once which are defined during CREATE/ALTER/GRANT
721725
statement. These attributes are divided into following categories.

‎sql/auth/auth_internal.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ const ACL_internal_table_access *get_cached_table_access(
117117

118118
/* sql_auth_cache */
119119
ulong get_sort(uint count, ...);
120-
bool assert_acl_cache_read_lock(THD *thd);
121-
bool assert_acl_cache_write_lock(THD *thd);
122120

123121
/*sql_authentication */
124122
bool sha256_rsa_auth_status();

‎storage/innobase/handler/ha_innodb.cc‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,9 @@ static SHOW_VAR innodb_status_variables[] = {
12311231
{"buffer_pool_write_requests",
12321232
(char *)&export_vars.innodb_buffer_pool_write_requests, SHOW_LONG,
12331233
SHOW_SCOPE_GLOBAL},
1234+
{"concurrency_ticket_skip_count",
1235+
(char *)&export_vars.innodb_concurrency_ticket_skip_count, SHOW_LONG,
1236+
SHOW_SCOPE_GLOBAL},
12341237
{"data_fsyncs", (char *)&export_vars.innodb_data_fsyncs, SHOW_LONG,
12351238
SHOW_SCOPE_GLOBAL},
12361239
{"data_pending_fsyncs", (char *)&export_vars.innodb_data_pending_fsyncs,

‎storage/innobase/include/srv0srv.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,9 @@ constexpr uint32_t SRV_MAX_N_IO_THREADS = 130;
777777
/** Number of deadlocks */
778778
extern ulint srv_lock_deadlocks;
779779

780+
/** Number of times concurrency ticket is skipped */
781+
extern ulint srv_concurrency_ticket_skip_count;
782+
780783
/** Number of lock wait timeouts */
781784
extern ulint srv_lock_wait_timeouts;
782785

@@ -1198,6 +1201,9 @@ struct export_var_t {
11981201
ulint innodb_dblwr_pages_written; /*!< srv_dblwr_pages_written */
11991202
ulint innodb_dblwr_writes; /*!< srv_dblwr_writes */
12001203
ulint innodb_ft_optimize_queue_count; /*!< ft_optimize_queue_count */
1204+
ulint innodb_concurrency_ticket_skip_count; /*!<
1205+
srv_concurrency_ticket_skip_count
1206+
*/
12011207
char innodb_redo_log_resize_status[512]; /*!< Redo log resize status */
12021208
bool innodb_redo_log_read_only; /*!< Is redo log read-only ? */
12031209
ulonglong innodb_redo_log_uuid; /*!< Redo log UUID */

‎storage/innobase/row/row0mysql.cc‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
3434
#include <debug_sync.h>
3535
#include <gstream.h>
3636
#include <spatial.h>
37+
#include <sql_acl.h>
3738
#include <sql_class.h>
3839
#include <sql_const.h>
3940
#include <sys/types.h>
@@ -4804,6 +4805,13 @@ bool row_prebuilt_t::skip_concurrency_ticket() const {
48044805
return true;
48054806
}
48064807
}
4808+
/** Skip concurrency ticket if a thread is already holding
4809+
ACL CACHE lock in MDL_EXCLUSIVE mode.
4810+
*/
4811+
if (thd != nullptr && assert_acl_cache_write_lock(thd)) {
4812+
srv_concurrency_ticket_skip_count++;
4813+
return true;
4814+
}
48074815
return false;
48084816
}
48094817

‎storage/innobase/srv/srv0srv.cc‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ ulong srv_force_recovery_crash;
550550
/** Number of deadlocks */
551551
ulint srv_lock_deadlocks = 0;
552552

553+
/** Number of times concurrency ticket is skipped */
554+
ulint srv_concurrency_ticket_skip_count = 0;
555+
553556
/** Number of row lock wait timeouts */
554557
ulint srv_lock_wait_timeouts = 0;
555558

@@ -1717,6 +1720,9 @@ void srv_export_innodb_status(void) {
17171720

17181721
export_vars.innodb_lock_deadlocks = srv_lock_deadlocks;
17191722

1723+
export_vars.innodb_concurrency_ticket_skip_count =
1724+
srv_concurrency_ticket_skip_count;
1725+
17201726
export_vars.innodb_lock_wait_timeouts = srv_lock_wait_timeouts;
17211727

17221728
export_vars.innodb_log_waits = srv_stats.log_waits;

0 commit comments

Comments
 (0)