IT 관련/Database

[MySQL] DB Connection close

nullzone 2017. 12. 30.
반응형


DB Connection close



DB Connection 에 대해서...


아주 오래전에  Oracle이 Database세상을 통치 하고 있을때, Oracle에서는 Concurrent user 라는 말을 사용했다. 

이 말은 Oracle 에서 동시에 접속 할수 있는 User를 지칭하는 말이다.(Oracle license 가 curcurrent User 단위였다)

즉, Oracle DB의 Concurrent User가 10이라고 하면 10개 이상의 connection은 허용되지 않는다는 의미다. 


웹서비스 입장에서 보면 이제는 Concurrent User 라는 이야기는 말이 안된다. 하나의 웹서비스에 10명이상이 접속하면 11번째는 접속이 않된다는 말이니... 이런 말도 안되는 DB가 있을수 있는가?



그런데 잘 생각해보면 

동시에 서비스에 1000명이 접속을 한다고 해서 1000명 모두가 동시에 DB접속을 하는건 아니다.

1번째 사용자가 게시판 메뉴를 선택하면 DB에 접속해서 게시판의 글 리스트를 받아 오고 DB접속을 끊거나 Pool로 반환 한다. 이걸 잘 살펴보면 동시 접속자가  1000명이 넘는 서비스도 DB접속은 10개라도 가능하다.  


DB는  클라이언트로부터 요청된 Query를 수행해서 결과를 리턴한다. 

DB는 입장에서 보면 이런 Query 수행을 하기 이전에 클라이언트와 연결을 맺어야 한다. 

이 부분이 DB Server 입장에서 Query 수행과는 별도로 꽤 많은 부하를 유발하게 된다. 

따라서 Connection Pool에 미리 connection 객체를 많들어 두고 클라이언트는 이를 필요 할때 사용하고, 사용이 끝나면 이를 반환하는 것리다.


전통적으로 Oracle -java 의 경우 connectionPool을 이용한다. 

물론 MySQL, MariaDB등에서는 굳이 이런 Connection Pool을 사용하지 않는다. 


나도 2000년 초반에 근무하게된 네이버+한게임 에서 근무 할때 게임쪽 서비스는 당연히 Connection Pool을 사용하는데 포털사의 웹서비스에서 Connection Pool 없이 direct로 DB에 접속하는 걸보고 살짝 혼란스러웠던적이 있다. 


아무튼 클라이언트 입장에서는 DB Connection을  사용하고 나서 사용한 Connection은 연결을 끊거나, Pool로 반드시 반환해야 한다는 것은 변함이 없다. 


SHOW STATUS LIKE '%connect%'; 처럼 show 명령을 사용 할 수도 있지만 

information_schema DB에 접근 하능 하다면 아래 쿼리를 사용하길 권한다. 


SELECT * FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME LIKE '%connect%';

VARIABLE_NAME                                  VARIABLE_VALUE  
---------------------------------------------  ----------------
ABORTED_CONNECTS                               13496           
CONNECTION_ERRORS_ACCEPT                       0               
CONNECTION_ERRORS_INTERNAL                     0               
CONNECTION_ERRORS_MAX_CONNECTIONS              0               
CONNECTION_ERRORS_PEER_ADDRESS                 1               
CONNECTION_ERRORS_SELECT                       0               
CONNECTION_ERRORS_TCPWRAP                      0               
CONNECTIONS                                    46600           
MAX_USED_CONNECTIONS                           49              
PERFORMANCE_SCHEMA_SESSION_CONNECT_ATTRS_LOST  0               
SLAVE_CONNECTIONS                              0               
SLAVES_CONNECTED                               0               
SSL_CLIENT_CONNECTS                            0               
SSL_CONNECT_RENEGOTIATES                       0               
SSL_FINISHED_CONNECTS                          0               
THREADS_CONNECTED                              2               
WSREP_CONNECTED                                OFF   

SELECT * FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME LIKE '%clients%';

VARIABLE_NAME    VARIABLE_VALUE  
---------------  ----------------
ABORTED_CLIENTS  7      

SELECT * FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME LIKE '%thread%';

VARIABLE_NAME                             VARIABLE_VALUE  
----------------------------------------  ----------------
DELAYED_INSERT_THREADS                    0               
INNODB_MASTER_THREAD_ACTIVE_LOOPS         3848            
INNODB_MASTER_THREAD_IDLE_LOOPS           2428387         
PERFORMANCE_SCHEMA_THREAD_CLASSES_LOST    0               
PERFORMANCE_SCHEMA_THREAD_INSTANCES_LOST  0               
SLOW_LAUNCH_THREADS                       0               
THREADPOOL_IDLE_THREADS                   0               
THREADPOOL_THREADS                        0               
THREADS_CACHED                            47              
THREADS_CONNECTED                         2               
THREADS_CREATED                           49              
THREADS_RUNNING                           1               
WSREP_THREAD_COUNT                        0       



Aborted_clients - 클라이언트 프로그램이 비 정상적으로 종료된 수 
Aborted_connects - MySQL 서버에 접속이 실패된 수 
Max_used_connections - 최대로 동시에 접속한 수 
Threads_cached - Thread Cache의 Thread 수 
Threads_connected - 현재 연결된 Thread 수 
Threads_created - 접속을 위해 생성된 Thread 수 
Threads_running - Sleeping 되어 있지 않은 Thread 수




상당히 많은 개발자들이 사용이 끝난 DB Connection을 끊거나, Pool로 반드시 반환을 빼먹는 경우가 많다. 

Threads_connected  - Threads_running 의 겂이 상당히 크다면 (sleeping Connect수) 프로그램에서 올바르게 connection을 종료 하지 않았거나 Pool로 반환을 하지 않았을 가능성이 크다. 



해서 나는 개발언어가 try..catch...finally를 지원한다면 아래와 같이 권하고 싶다. 



 try {
            $conn->beginTransaction();
            ...........
            ........... 
            $conn->commit();
 
        } catch (PDOException $e) {
            ...........
            $conn->rollBack();
        }
        finally{
            ...........
             $conn = null;
        }








반응형

댓글