I was recently struck by a problem which is unusual. In order to keep an eye on the database server I use nagios, cacti, merlin and some local scripts to monitor the database instance and ensure that it is working properly. That normally works fine. The different monitor processes do various things, one of which is to monitor the replication status of a slave, and warn me if the replication is not working or if it’s behind. This is done with the command
SHOW SLAVE STATUS.
The server I was looking at runs some large local batch jobs aggregating data. Unfortunately, I was experiencing that replication was interfering with these batch jobs so decided to see if things would perform better if I stopped replication and let the batch jobs complete, restarting replication afterwards.
So the command
STOP SLAVE was sent to the server, and this took some time. In the meantime
SHOW SLAVE STATUS hangs. The
STOP SLAVE command waits for the SQL replication thread to finish it’s task but that thread was waiting on the tables being used by the batch process, which was already running. The consequence of this was that
STOP SLAVE waited, all calls to
SHOW SLAVE STATUS blocked and with nagios, cacti, merlin and the local scripts all doing periodic
SHOW SLAVE STATUS commands which would hang I ended up with the mysqld running out of user connections. Nasty!
While I see if MySQL can do something about the behaviour of stopping the slave and showing the slave status I’m going to implement grants which limit the monitor users so they are only allowed to have a user concurrent connections open. This is done using the syntax
GRANT whatever ON whereever TO some_user WITH MAX_USER_CONNECTIONS 5;
5 looks like a good number for nagios, merlin and the local scripts and 10 is probably sufficient as I collect a lot of graph data for the mysql server and the cacti requests are often done in parallel.
So if you monitor MySQL it may be worth you applying some sort of connection limit on your monitoring scripts, if not on other database users.