forked from percona/percona-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug #20201006 spamming show processlist prevents old
connection threads from cleaning up. Analysis ========= Issue here is, delay in connection cleanup for which global connection counter is already decremented, makes room for new connections. Hence more than expected connections are observed in the server. Connections running statement "SHOW PROCESSLIST" or "SELECT on INFORMATION_SCHEMA.PROCESSLIST" acquires mutex LOCK_thd_remove for reading information of all the connections in server. Connections in cleanup phase, acquires mutex to remove thread from global thread list. Many such concurrent connections increases contention on mutex LOCK_thd_remove. In connection cleanup phase, connection count is decreased first and then the thd is removed from global thd list. This order makes new connection (above max_connections) possible while existing connections removal is still pending because of mutex LOCK_thd_remove being held by show processlist. Fix: ===== In connection clean phase, thd is removed from the global thd list first and then global connection count is decremented. Added code to wait for connection_count be be zero during shutdown to ensure connection threads are done with their task.
- Loading branch information
Ajo Robert
committed
Nov 23, 2015
1 parent
30fba0a
commit 3b633ba
Showing
7 changed files
with
158 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
|
||
# -- Bug#20201006: Spamming show processlist prevents old connection | ||
# -- threads from cleaning up. | ||
SET @saved_max_connections = @@global.max_connections; | ||
SET GLOBAL max_connections = 2; | ||
|
||
# -- Check that we allow only max_connections + 1 connections here | ||
connect con_1, localhost, root; | ||
connect con_2, localhost, root; | ||
connect(localhost,root,,test,MYSQL_PORT,MYSQL_SOCK); | ||
connect con_3, localhost, root; | ||
ERROR HY000: Too many connections | ||
|
||
# -- Ensure we have max_connections + 1 connections. | ||
SELECT count(*)= @@global.max_connections + 1 FROM information_schema.processlist; | ||
count(*)= @@global.max_connections + 1 | ||
1 | ||
|
||
# -- Take LOCK_thd_remove and close one connection then | ||
# attempt new one [should fail]... | ||
SET DEBUG_SYNC='fill_schema_processlist_after_copying_threads SIGNAL disconnect_connection WAIT_FOR continue'; | ||
SELECT user FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY user;; | ||
connection default; | ||
SET DEBUG_SYNC='now WAIT_FOR disconnect_connection'; | ||
disconnect con_1; | ||
connect(localhost,root,,test,MYSQL_PORT,MYSQL_SOCK); | ||
connect con_3, localhost, root; | ||
ERROR HY000: Too many connections | ||
|
||
# -- Release the lock. Now new connection should go through | ||
SET DEBUG_SYNC='now SIGNAL continue'; | ||
connection con_2; | ||
user | ||
root | ||
SET DEBUG_SYNC='RESET'; | ||
|
||
# -- Waiting for connection to close... | ||
connect con_3, localhost, root; | ||
|
||
# -- Closing connections... | ||
disconnect con_3; | ||
disconnect con_2; | ||
connection default; | ||
|
||
# -- Resetting variables... | ||
SET GLOBAL max_connections= @saved_max_connections; | ||
|
||
# -- End of Bug#20201006. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
# This test makes no sense with the embedded server | ||
--source include/not_embedded.inc | ||
|
||
--source include/have_debug_sync.inc | ||
|
||
# Save the initial number of concurrent sessions | ||
--source include/count_sessions.inc | ||
|
||
--echo | ||
--echo # -- Bug#20201006: Spamming show processlist prevents old connection | ||
--echo # -- threads from cleaning up. | ||
|
||
--enable_connect_log | ||
SET @saved_max_connections = @@global.max_connections; | ||
SET GLOBAL max_connections = 2; | ||
|
||
--echo | ||
--echo # -- Check that we allow only max_connections + 1 connections here | ||
--connect (con_1, localhost, root) | ||
--connect (con_2, localhost, root) | ||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK | ||
--error ER_CON_COUNT_ERROR | ||
--connect (con_3, localhost, root) | ||
|
||
--echo | ||
--echo # -- Ensure we have max_connections + 1 connections. | ||
SELECT count(*)= @@global.max_connections + 1 FROM information_schema.processlist; | ||
|
||
--echo | ||
--echo # -- Take LOCK_thd_remove and close one connection then | ||
--echo # attempt new one [should fail]... | ||
SET DEBUG_SYNC='fill_schema_processlist_after_copying_threads SIGNAL disconnect_connection WAIT_FOR continue'; | ||
--send SELECT user FROM INFORMATION_SCHEMA.PROCESSLIST GROUP BY user; | ||
|
||
--connection default | ||
SET DEBUG_SYNC='now WAIT_FOR disconnect_connection'; | ||
--disconnect con_1 | ||
|
||
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK | ||
--error ER_CON_COUNT_ERROR | ||
--connect (con_3, localhost, root) | ||
|
||
--echo | ||
--echo # -- Release the lock. Now new connection should go through | ||
SET DEBUG_SYNC='now SIGNAL continue'; | ||
--connection con_2 | ||
reap; | ||
|
||
SET DEBUG_SYNC='RESET'; | ||
|
||
--echo | ||
--echo # -- Waiting for connection to close... | ||
let $wait_condition = | ||
SELECT COUNT(*) = 2 | ||
FROM information_schema.processlist; | ||
--source include/wait_condition.inc | ||
|
||
--connect (con_3, localhost, root) | ||
|
||
--echo | ||
--echo # -- Closing connections... | ||
--disconnect con_3 | ||
--disconnect con_2 | ||
--source include/wait_until_disconnected.inc | ||
|
||
--connection default | ||
|
||
--echo | ||
--echo # -- Resetting variables... | ||
SET GLOBAL max_connections= @saved_max_connections; | ||
|
||
--disable_connect_log | ||
|
||
--echo | ||
--echo # -- End of Bug#20201006. | ||
--echo | ||
|
||
# Wait till all disconnects are completed | ||
--source include/wait_until_count_sessions.inc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters