클라이언트에서 mysql서버로 접속할 수 있는 수를 지정할 수 있는 방법이 있다.

최대 접속 수 확인은 이렇게 한다.

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 214   |
+-----------------+-------+

으로 max_connections를 확인하면 된다.

이것을 변경하기 위해,
DB서비스 재시작 없이 online으로

mysql> set global max_connections=500;

online으로 설정한 값은 즉시 반영된다.
혹은 영구적으로 my.cnf 혹은 옵션으로 사용하고 있는 설정파일에 추가하고 서비스를 재시작하면 된다.

[mysqld]
max_connections = 500

설정파일에 설정하고 서비스를 재시작하고 확인을 해본다.

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 214   |
+-----------------+-------+

여전히 214로 확인된다!
아니 왜?

안돼!

connection 수가 변경되지 않는다.

찾아본 결과 mysql에서 동시에 오픈할 수 있는 file descriptor의 수에 따라 제한이 된다고 한다.
mysql에서 커넥션 별로 소켓을 열어 연결을 하고 있기 때문이다.

mysql> show variables like 'open_files_limit';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1024  |
+---------------- -+-------+

이 수치는 우분투, 데비안 계열에서 패키지 매니져로 기본설치할 경우 지정되는 값인가보다.

connection 수에서 구할 수 있는 file descriptor개수는
wanted_files = 10 + max_connections + table_cache_size * 2 이렇다고 한다.
[mysql document - open_files_limit]

mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| table_open_cache | 400   |
+---------------- -+-------+

따라서
1024 = 10 + 214 + 400 * 2

딱 맞아 떨어진다!

감동

위의 문제로!
online으로 변경했을 때도, variable의 max_connections 값은 바꼈지만 실제론 max에 미치진 않아도 어느 정도 커넥션이 몰리면 더이상 접속이 불가능한 상황이 나타나는 것 같다.
(max_connections보다 많은 커넥션이 요청되면 Too many connections이라는 오류 메시지가 나타지만 file descriptor의 수가 부족해서 연결이 실패하는 경우엔 Too many connections 메시지가 나타나지 않는 것 같다. file open을 하지 못하면 Too many open files. 에러메시지가 난다고 하지만, 단순히 커넥션을 하지 못하는 메시지가 나타났다.)

open_files_limit를 변경해보자. 우선 OS에서 열 수 있는 File descriptor 값을 확인해본다.

$ ulimit -a
$ ulimit -aH

$ ulimit -Sn
$ ulimit -Hn

soft, hard 설정값을 확인해본다.

변경을 위해 /etc/security/limits.conf을 수정한다. mysql 유저나 *(모든) 유저에 지정된 nofile 값을 변경한다.

*            soft    nofile          65536
*            hard    nofile          65536

그런 후 mysql 서비스에도 값을 변경한다.

서비스 실행 명령에 옵션으로 추가해도 되지만, Mysql 문서에서는 systemd 옵션에 추가하도록 하길 권장하고 있다.

추가하는 방법은 /lib/systemd/system/mysql.service에 바로 추가하기 보다는 설정을 override할 수 있도록 /lib/systemd/system/mysql.service.d폴더를 만들어 새로운 파일을 생성해서 추가하도록 한다.

$ vi /lib/systemd/system/mysql.service.d/limit_nofile.conf

위의 descriptor 계산식에 따르면 3000개의 connection에는 3810개면 된다. 넉넉잡아 4000개로 지정해보자.

[Service]
LimitNOFILE=4000

수정 후 서비스 설정을 reload 후 재시작 하도록 한다.

$ systemctl daemon-reload
$ systemctl mysql restart

변경 후 테스트를 해보지 않았지만... 해결되었으면 한다.

추가 참고 명령어.

$ cat /var/lib/mysql/*.pid   # process id 확인
$ ps auxww | grep <pid>      # process 실행 명령어 확인
$ cat /proc/<pid>/limits     # process에 지정된 limits 확인

참고
https://codepoets.co.uk/2015/mysql-max_connections-stuck-on-214
http://woowabros.github.io/experience/2018/04/17/linux-maxuserprocess-openfiles.html
https://dev.mysql.com/doc/refman/5.5/en/server-options.html#option_mysqld_open-files-limit
https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_open_files_limit
https://support.plesk.com/hc/en-us/articles/213393029-MySQL-values-open-files-limit-and-max-connections-are-not-applied