음 php 프로그래머의 실수에 따라 DB사용을 하지 않으나 장시간 sleep이 나는 경우가 있다.
뭐 프로그램 짜다보면 그럴수 있을것이다 =3=a
- 프로그램이 mysql_pconnect 을 사용하거나 (apache keepalive 시간 동안 접속을 대기 탈 것이다.)
- mysql 접속후 mysql.close()를 안했거나
- 로그테이블 등의 크기가 커져서 lock 걸리는 시간이 증가하면 다른 접속자 로그를 쓰기 위해 wait 가 걸리기 때문에 mysql 커넥션이 과도하게 증가하기도 함..
- 서버 사양 대비 동시접속자수가 많거나…
서버 관리자 입장에서는 서버 메모리에 부담을 주고 sleep 프로세스의 과다 접속에 의해 my.cnf에서 설정된
max connctions 값 에 의해 추가 신규 접속이 불가능한 상황을 방지 해야 한다.
그리하여 이러한 스크립트를 만들었습니다 🙂 – (mysql.close()가 제대로 되지 않는 경우를 상정.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#!/bin/bash ######################################################################################################### # SQL 슬립쿼리 자동 킬 스크립트 # # - 로그 파일 위치 : /var/log/mysql_autometic_kill.log # # - 타겟아이디를 지정하는 이유는 ssh 접속 mysql 실행하고 있는 유져가 짤릴수도 있기 때문이다. # # # # last updated 2015.08.17 made in san0123a@naver.com # ######################################################################################################### ### 대상 아이디 및 슬립 시간에 따라 자동으로 kill 을 한다 ############################################### sleep_time="500" # 정리 시간 지정 500초 all_user_target="Y" # 모든 유져 대상 (Y/N) target_id=( account1 account2 account3 account4 NULL ) # 대상 계정 지정 array ######################################################################################################### mysql_path="/usr/local/mysql/bin/mysql" dbpa="mysql루트패스워드" # pid 생성 중복실행을 방지 ######################################################## if [[ -s $0.pid ]];then exist_pid=`cat $0.pid` if [[ -z `ps -e|grep "^$exist_pid "` ]];then rm -f $0.pid;exec_confirm="Y" else exec_confirm="N";echo -e "\e[1;32mShell has already running...\e[0m";fi else exec_confirm="Y";fi if [[ $exec_confirm == "Y" ]];then echo $$ > $0.pid ################################################################################### /bin/rm -f /tmp/kill_list.tmp /tmp/kill_list.sql find /var/log/ -name 'mysql_autometic_kill.log' -size +20000k -type f -exec cp /dev/null {} \; for i in `$mysql_path -uroot -p$dbpa mysql -s -N -e "SHOW FULL PROCESSLIST;"|awk '{print $1":"$4":"$5":"$6}'` do process_id=`echo $i|cut -d: -f 1` database=`echo $i|cut -d: -f 2` command=`echo $i|cut -d: -f 3` work_times=`echo $i|cut -d: -f 4` if [[ $all_user_target == "Y" ]];then kill_go="Y" elif [[ $all_user_target == "N" ]];then kill_go="N" for i2 in ${target_id[@]};do if [[ $i2 == $database ]];then kill_go="Y";fi;done fi if [[ $kill_go == "Y" ]];then if [[ $work_times -gt $sleep_time ]];then echo "kill $process_id;" >> /tmp/kill_list.sql echo " -> $process_id / $database / $work_times" >> /tmp/kill_list.tmp ((kills++)) fi;fi done if [[ -e /tmp/kill_list.txt ]];then stime=`date +"%Y/%m/%d %H:%M"` echo "$stime // $kills - sleep query kill." >> /var/log/mysql_autometic_kill.log cat /tmp/kill_list.tmp >> /var/log/mysql_autometic_kill.log;rm -f /tmp/kill_list.tmp echo "" >> /var/log/mysql_autometic_kill.log $mysql_path -uroot -p$dbpa < /tmp/kill_list.sql;rm -f /tmp/kill_list.sql fi ################################################################################### rm -f $0.pid fi # pid 생성 중복실행을 방지 - END ################################################## |
all_user_target 값을 Y로 해두면 모든 계정에 대해 kill을 수행합니다만.
ssh 접속해서 mysql 작업하면서 장시간 가만히 있으면 강제적으로 프로세스 종료 까지 될수 있습니다.
그래서 all_user_target=”N” 으로 하고 문제시 되는 계정만 target_id 에 설정하여 운용하도록 합니다. ‘ㅅ’a
PS. pconnect 를 사용하면 일반 connect 으로 사용하도록 유도 하고, log 테이블이 커졋다면 일정부분 날려서 정리를 해야 할꺼고 사양이 부족하다면 사양 업그레이드를 하거나 DB query cache 를 구현 하는 방법으로 해결 해야 할꺼 같다 ‘ ‘a 이 스크립트는 임시 방편일 뿐이다.