Programing

MySql Proccesslist가 "Sleep"항목으로 채워져 "너무 많은 연결"이 발생합니까?

lottogame 2020. 12. 13. 08:31
반응형

MySql Proccesslist가 "Sleep"항목으로 채워져 "너무 많은 연결"이 발생합니까?


php / mysql 연결과 관련된 오랜 문제에 대해 귀하의 도움을 요청하고 싶습니다.

"SHOW PROCESSLIST"명령을 실행할 때마다 5 개의 웹 서버에서 나오는 데이터베이스 서버에 대한 약 400 개의 유휴 (상태 : 절전) 연결이 표시됩니다.

최근에 트래픽 수가 증가하고 그 이후로 MySQL이 "많은 연결에 대한"문제를 반복적으로보고하기 전까지는 그다지 문제가되지 않았습니다 (빠른 해결책을 찾지 못했습니다). 이러한 연결 중 350 개 이상이 "휴면"상태에 있습니다. . 또한 서버는 동일한 서버에 잠자기 연결이 있어도 MySQL 연결을 얻을 수 없습니다.

이러한 모든 연결은 아파치 서버가 다시 설정되면 사라집니다.

데이터베이스 연결을 생성하는 데 사용되는 PHP 코드는 일반 "mysql"모듈, "mysqli"모듈, PEAR :: DB 및 Zend Framework Db 어댑터를 사용합니다. (다른 프로젝트). 어떤 프로젝트도 영구 연결을 사용하지 않습니다.

연결 제한을 높이는 것은 가능하지만 현재 450 개이고 어쨌든 한 번에 20-100 개의 "실제"연결 만 있기 때문에 좋은 해결책이 아닌 것 같습니다.

내 질문:

절전 상태에 너무 많은 연결이있는 이유는 무엇이며 어떻게 방지 할 수 있습니까?

-업데이트 :

한 번에 실행되는 Apache 요청 수는 동시 요청 50 개를 초과하지 않으므로 연결을 닫는 데 문제가 있거나 아파치가 phpscript가 첨부되지 않은 상태로 포트를 열어 둡니다.

도움이되는 경우 my.cnf :

innodb_buffer_pool_size = 1024M

max_allowed_packet = 5M
net_buffer_length = 8K

read_buffer_size = 2M
read_rnd_buffer_size = 8M

query_cache_size = 512M
myisam_sort_buffer_size = 128M

max_connections = 450
thread_cache = 50
key_buffer_size = 1280M
join_buffer_size = 16M

table_cache = 2048
sort_buffer_size = 64M
tmp_table_size = 512M
max_heap_table_size = 512M

thread_concurrency = 8

log-slow-queries = /daten/mysql-log/slow-log
long_query_time = 1
log_queries_not_using_indexes

innodb_additional_mem_pool_size = 64M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table

기본적으로 다음과 같은 경우 절전 상태에서 연결됩니다.

  • PHP 스크립트가 MySQL에 연결
  • 일부 쿼리가 실행 됨
  • 그런 다음 PHP 스크립트는 시간이 걸리는 작업을 수행합니다.
    • DB에서 분리하지 않고
  • 마지막으로 PHP 스크립트가 종료됩니다.
    • 즉, MySQL 서버에서 연결이 끊어집니다.

따라서 일반적으로 데이터베이스 측에서 실제로 아무것도 수행하지 않고 연결된 상태로 유지되는 많은 PHP 프로세스가있을 때 많은 프로세스가 절전 상태에있게됩니다.

기본 아이디어입니다. 너무 오래 실행되는 PHP 프로세스가 없는지 확인하거나 더 이상 데이터베이스에 액세스 할 필요가없는 즉시 연결을 끊도록합니다.


또 다른 것은 서버에 부하가있을 때 자주 보는 것입니다.

  • Apache에 점점 더 많은 요청이 있습니다.
    • 생성해야 할 많은 페이지를 의미합니다.
  • 각 PHP 스크립트는 페이지를 생성하기 위해 DB에 연결하고 몇 가지 쿼리를 수행합니다.
  • These queries take more and more time, as the load on the DB server increases
  • Which means more processes keep stacking up

A solution that can help is to reduce the time your queries take -- optimizing the longest ones.


Increasing number of max-connections will not solve the problem.

We were experiencing the same situation on our servers. This is what happens

User open a page/view, that connect to the database, query the database, still query(queries) were not finished and user leave the page or move to some other page. So the connection that was open, will remains open, and keep increasing number of connections, if there are more users connecting with the db and doing something similar.

You can set interactive_timeout MySQL, bydefault it is 28800 (8hours) to 1 hour

SET interactive_timeout=3600

Before increasing the max_connections variable, you have to check how many non-interactive connection you have by running show processlist command.

If you have many sleep connection, you have to decrease the value of the "wait_timeout" variable to close non-interactive connection after waiting some times.

  • To show the wait_timeout value:

SHOW SESSION VARIABLES LIKE 'wait_timeout';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| wait_timeout | 28800 |

+---------------+-------+

the value is in second, it means that non-interactive connection still up to 8 hours.

  • To change the value of "wait_timeout" variable:

SET session wait_timeout=600; Query OK, 0 rows affected (0.00 sec)

After 10 minutes if the sleep connection still sleeping the mysql or MariaDB drop that connection.


So I was running 300 PHP processes simulatenously and was getting a rate of between 60 - 90 per second (my process involves 3x queries). I upped it to 400 and this fell to about 40-50 per second. I dropped it to 200 and am back to between 60 and 90!

So my advice to anyone with this problem is experiment with running less than more and see if it improves. There will be less memory and CPU being used so the processes that do run will have greater ability and the speed may improve.


The above solutions like run a query

SET session wait_timeout=600;

Will only work until mysql is restarted. For a persistant solution, edit mysql.conf and add after [mysqld]:

wait_timeout=300
interactive_timeout = 300

Where 300 is the number of seconds you want.


Alright so after trying every solution out there to solve this exact issues on a wordpress blog, I might have done something either really stupid or genius... With no idea why there's an increase in Mysql connections, I used the php script below in my header to kill all sleeping processes..

So every visitor to my site helps in killing the sleeping processes..

<?php
$result = mysql_query("SHOW processlist");
while ($myrow = mysql_fetch_assoc($result)) {
if ($myrow['Command'] == "Sleep") {
mysql_query("KILL {$myrow['Id']}");}
}
?>

참고URL : https://stackoverflow.com/questions/2407732/mysql-proccesslist-filled-with-sleep-entries-leading-to-too-many-connections

반응형