Laravel MySql Connection problem too many connections - mysql

Too many connection problem in laravel5.8 application
You can see there 54k+ connection in mysql and 32 is in used only
how to remove unused connection so my application work fast.

Neither 54K connections since startup, nor a max of 32 connections simultaneously doing something, is "too many".
What is the real problem? Sluggishness? Find the slowest queries and let's work on speeding them up. Run SHOW FULL PROCESSLIST to see if any queries have been running for more than a few seconds; they are a prime candidate for optimizing. Or use the slowlog.

Connection is just a "count" of attempted connections. It does not relate to active connections nor max_used_connections.
Run the following commands simultaneously:
SHOW VARIABLES LIKE 'max_connections'
SET GLOBAL max_connections = 1000000;

Connection is just a "count" of attempted connections. It does not relate to active connections nor max_used_connections.
See MySQL show status - active or total connections?
If you really are having many current open connections, you should look into what these connections are. You might have a sub-optimal query in your code or a bot is spamming an open endpoint.
You can see process list by running the query
show processlist;
You can then kill connections for the short term solution or take care of whatever problem was causing the connections in the first place.
If you really do need that many connections (doubt it), you should look into scaling your database instance, e.g. by adding read replicas.

Related

Mysql thread connected is 1-3 but experienced too many connections

Yesterday I can see in the log that within 1 minute timespan, there is alot of mysql errors with too many connections failures. I am running default setting: 151 for max_connections and have not experienced this before.
When checking current state, my thread connections is only 1 and up to 3 at max.
Should i increase my max_connections or did i just temporary suffer from a DDoS?
Note: It solved itself and worked immediately after that minute.
Update 2: It just happend again. I can see multiple errors within some seconds timeframe the error log. Why does this happen?
Decrease max_connect_errors to, say, 100. This is a small protection against hackers.
Threads_running is always at least 1 because it includes your SHOW.
With max_connections = 151, Max_used_connections = 152 means that 151 user connections came in, plus one "extra" connection was allowed and used. For this reason, do not run your application as root (or any other SUPER user).
GRANT ... ON your_database.* ..., not ... ON *.* ... for any application logins. This seriously slows down hackers from getting at the mysql database.
root should be allowed only from localhost. This is another safety measure.
If your web server has an "access" log, look at it. You may see hundreds of similar looking hack attacks in a row. And you may a similar set of them often.
Be sure to escape any data coming from html forms. Do this as you build the INSERTs. Without this, you are wide open for attack.
Addenda
SELECT user, host FROM mysql.user WHERE Super_priv = 'Y';
will show you who has SUPER. As a first cut, it should include only host values of localhost, 127.0.0.1, or ::1, all of which are effectively localhost. This does not prevent hackers from first hacking the client, which may also be on localhost.
This may list those with another way in:
SELECT user, host FROM mysql.user WHERE Grant_priv = 'Y';
Back to the question
The Web server's (nginx's?) limit on the number of connections should be less than MySQL's max_connections. This will stop hackers (and users) at the door, rather than letting them clog up both the web server and MySQL.
Even on a well running system, 20 is a reasonable max for how many should be allowed into the web server simultaneously. If there are more, then they are probably stumbling over each other; it would be better to let a few get all the resources they need rather than take longer because of battling over resources.

MySQL Connection Limit Advice

I've hit a problem with my MySQL queries and was hoping someone could offer some help/advice.
I'm developing a PHP-based system which combines quite a lot of data in different tabs on one page (tab1 = profile, tab2 = address, tab3 = payments etc.) and as a result, one page can have up to 34/40 MySQL queries pulling from different tables or with different criteria.
The page load became really slow and I asked my web host if they knew what was wrong and they advised it's because of slow MySQL queries (some over 2 seconds). They also said that my MySQL user is only allowed 15 connections at a time.
If my page has 40 queries and only 15 connections are allowed at a time, does this mean they effectively queue and wait for one to complete? If this was the case then I can understand why the page is taking a while to load but i'm not sure of the solution. Is 15 MySQL queries considered a lot or is this quite a tight restriction by my host (HostMonster)?
Also, if there were 15 users accessing the system at the same time, would this 15 connections be split between each of them or is it 15 connections per user logged into the site? I assume they mean per database user but all people who access the system will be using the same database user so it seems impossible to create a system in which several users can access at one?
The whole connections thing has confused me a little.
Thanks in advance for any help!
Have one connection per page. Put the queries into sequence
Optimize those queries - see explain and use indexes
Perhaps combine queries to reduce the through put.
BTW 10+ queries per page is excessive IMHO.
If having max connect error problem then use this command from command line
mysqladmin flush-hosts -uuser -p'password'
this will flush hosts that MySQL has recorded and will build the list again. In the newer version of MYSQL 5.6 you get more information on this but not on previous version.
You can set the following
max_connect_errors 10000
to avoid the message to appear again.
15 queries or connection is not a problem at all, in busy databases we have seen thousand connections and tens of thousands of queries per second.

How to solve MySQL max_user_connections error

I'm getting following error when I try to log onto phpMyAdmin.
User ** already has more than 'max_user_connections' active connections
Could anyone let me know how to close these DB connections from MySQL server end?
Thank you for your time!
Read max_connections document to solve your problem
If clients encounter Too many connections errors when attempting to
connect to the mysqld server, all available connections are in use by
other clients.
The permitted number of connections is controlled by the
max_connections system variable. The default value is 151 to improve
performance when MySQL is used with the Apache Web server. To support
more connections, set max_connections to a larger value.
First: Check your current database max_connection variable
SHOW VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
Then Try to increase the max_connection parameter either with running command like:
SET GLOBAL max_connections = 300;
Or set this parameter in my.cnf that mostly is located at /etc/my.cnf
vi /etc/my.cnf
max_connections = 300
Finally: Restart MySQL service
FYI
you can also check max_user_connections. however, they are related like this:
max_connections set the total connection limit
max_user_connections set limit per user
====
As Sushilzzz asked: can this be caused by low RAM?
Short answer: No
Long Answer: yes, If Ram Size is low and MySQL can't respond as fast as needed there will be many open connections and you can easily hit the max connection.
The estimated number of max connections per 1GB of ram is 100 (if you don't have any other process using ram at the same time). I usually use ~75 for max_connection per 1GB of RAM
RAM max_connection
1GB 70
2GB 150
4GB 300
8GB 500
This happens due to limit specified in the mysql configuration, the system variable max_user_connections.
Solutions
Killing the queries which are stuck at the backend is only a solution I would suggest if it is a SELECT query. Queries that change data, like UPDATE/DELETE/INSERT, are not to be killed.
Secondly, you can use the command mysqladmin processlist to check what is going on inside mysql.
If locking is causing your problem, you can check which engine you are using and change it to another. IBM's SolidDB documentation on table locks might help you. Though there may be another reason for this. (For example, perhaps your queries are taking too long because of an unoptimized query, or the table size is too big, or you have a spammed database).
Your best bet is to increase max_connections. For a MySQL instance serving multiple different web apps (raw php, WordPress, phpBB), you probably want a value of at least 60 for this.
Issue this command and you'll find out how many global connections you have available:
show global variables like '%connections%'
You can find out how many connections are in use at any given moment like this:
show status like '%connected%'
You can find out what each connection is doing like this:
show full processlist
I would try for a global value of at least 100 connections if I were you. Your service provider ought to be able to help you if you don't have access to do this. It needs to be done in the my.cnf file configuration for MySQL. Don't set it too high or you run the risk of your MySQL server process gobbling up all your RAM.
A second approach allows you to allocate those overall connections to your different MySQL users. If you have different MySQL usernames for each of your web apps, this approach will work for you. This approach is written up here. https://www.percona.com/blog/2014/07/29/prevent-mysql-downtime-set-max_user_connections/
The final approach to controlling this problem is more subtle. You're probably using the Apache web server as underlying tech. You can reduce the number of Apache tasks running at the same time to, paradoxically, increase throughput. That's because Apache queues up requests. If it has a few tasks efficiently banging through the queue, that is often faster than lots of tasks because there's less contention. It also requires fewer MySQL connections, which will solve your immediate problem. That's explained here: Restart Mysql automatically when ubuntu on EC2 micro instance kills it when running out of memory
By the way, web apps like WordPress use a persistent connection pool. That is, they establish connections to the MySQL data base, hold them open, and reuse them. If your apps are busy, each connection's lifetime ought to be several minutes.
First, this is a hack, but works, especially on a shared host.
We all have bad "neighbors" sometimes, right?
If you have access to your /etc/ increase the limit from 30 to 50, in your my.cnf or through the information schema.
To ignore the error message the visitor might see, use #mysql_connect().
If there are more than 30 MUCs, use the "or die()" statement to stop the query.
Replace the "or die" message with die(header(location: THIS PAGE)) and be sure to mysql_close();
Yes, it will cause a delay in page loading. But better to load than a white screen of death -or worse error messages that visitors have no understanding of.
It looks like queries stuck on the server. Restart and everything will be ok.
If you are on shared hosting, just contact your hosting provider they will fix it.
I'm namecheap user and they solved it.
In my case 1 have a limit of 10 user connections; And I do not have the right to change the max user connections variable. You can check the amount user connection like so.
show variables like "max_user_connections";
You can set the max amount of user connections like so if you have permission.
SET GLOBAL max_connections = 300;
Else you can view the processes in use like so
Show full processlist;
And kill some of the process with I like so. In you case replace number by a id in previous table Show full processlist;
kill 10254745;

Perfectly good queries on my sql taking more than 5 seconds

Lately we are seeing some queries in mysql(master) logs but no idea why they are shown there:
Queries are select/update table where id = <some integer>.
There is index on id
table size is below 100 000
Rows scanned are in hundreds (sometimes < 100)
Server is running on extremely good hardware
there are no joins involved
We do not see any heavy activity running on database at that time
tables are innodb
the same queries generally don’t even take 50ms, but sometimes all the execution of these queries take about 4-8 seconds
One observation was all the similar "non-slow-but-weirdly-taking-high-time" queries take almost the same amount of time for some duration . I.e. queries like stated in the top will all take about 4.35 seconds with variation of 0.05 seconds.
Does the network latency/packets-drop affect mysql query timing?
show processlist;
show global status like '%onnect%';
show global status like '%open%';
Is anything backed up? Is it waiting in a queue? waiting for file handles? What are your max_connections, open-files-limit, thread_concurrency ?
One side question: does the network latency/packets-drop affect mysql query timing?
Yes, the timeout must occur before the query is resent by the client
Do you see these problems locally or over the network? If the latter, then obviously packet drops can affect your performance if you are measuring from the client.
Is it running in a virtual machine that can affect the performance?
Disk problems?
How is serialization set up? Can it be a contention problem by many processes accessing the same row?
You may want to enable the query/slow query logs to see if there is any sort of pattern that causes this.
Mysql slow log is not representative source to learn about your slow queries. If something makes server work slow all queries usually go to slow log.
E.g. if you have some slow blocking select on MyISAM a lot of PK updates will go to slow log.
You need to search for other slow queries or server problems. What about load average on this particular machine? Isn't mysql displaced into swap memory? Other applications? Queries per second?

Identifying who makes a lot of INSERT requests in MySQL

Recently, I noticed that my MySQL server processes a lot of INSERT's. How can I detect user or DB on which is this activivty??
insert 33 k 97.96 k 44.21%
SHOW FULL PROCESSLIST will return every connection, user, and query currently active, if you have the PROCESS permission. That's more for immediate problems, but it has the least overhead.
If you use query logging, then instead of the regular query log (it can slow your server down noticeably) use the binary log to keep it minimal. It only tracks actions that change tables, like CREATE/DROP/ALTER and INSERT/UPDATE/REPLACE.
What you should log periodically (once a minute):
SHOW FULL PROCESSLIST;
SHOW GLOBAL STATUS;
with slow log enabled this will give you huge chance that any question can be solved.
If you have binary logging enabled you can check time/user who inserted rows.
If you have general log enabled then everything is logged.
Look in your query logs. This will show every connect into MySQL, and show every command that they execute.