실행중인 프로세스가 갑자기 죽으며 Core 파일이 생성

Core 파일이 계속 생성되는 경우 Disk Full로 장애 발생

Core 파일 분석 후 이슈를 해소하여 시스템 안정성 확보 

Core 파일 생성을 위한 설정

1. ulimit -c unlimited
2. ulimit -a 로 확인
- 'core file size          (blocks, -c) unlimited' 면 설정 완료
- 만약 core file의 size를 제한하고 싶다면 'unlimited'가 아닌 kb단위의 size를 지정해주면 된다.

분석 방법

1. debug 대상 파일 확인

프로그램이 여러개가 돌고 있는 환경이라면 특정 dump가 어떤 프로그램이 만든것인지 확인 필요

file [core dump file]

* /proc/sys/kernel/core_pattern 에서 정의된 형태로 생성

   %p : pid

   %u : uid

   %g : gid

   %s : signal number

   %t : dump time(unix)

   %h : hostname

   %e : process

 

2. debugging

gdb [core발생 프로그램] [core file]

이후, gdb interface로 화면이 전환되면서 core에 관한 간략한 정보가 뜬다.
그리고 다음의 command를 입력하면 상세한 정보를 확인하는데 도움을 준다.

- bt(back trace) : core 발생 직전의 call stack 확인
- bt full : 전체 call stack 확인
- f[스택프레임 번호] : 특정 stack 확인
- list : stack의 code 보기
- info local : stack의 수행 당시 변수 값 확인
- info arg : stack의 argument 확인
- where : 간략화


의심되는 stack frame 분석

 info frame : 보다 상세한 정보 제공

 stack frame at 0x : 해당 함수 sp

 called by frame at 0x : 해당 함수를 호출한 함수의 SP(ex. main)

 Arglist at 0x : 해당 함수가 호출하는 함수의 bp

 args : 인자 정보

 saved registers : rip, ebp..

   (EX) (gdb) f [frame num] + (gdb) info frame

         (gdb) info frame [frame num]

 

해당 stack의 argument/local value 확인

 info frame 보다 간결하지만 인간친화적

 

  (EX) (gdb) info arg

        (gdb) info local

 

3. process debugging

gdb [프로세스명] [pid]

실행중인 프로세스를 gdb로 붙어서 확인

 

참고

https://incredible-larva.tistory.com/entry/core-dump-%EB%B6%84%EC%84%9D%EC%9D%84-%EC%9C%84%ED%95%9C-gdb-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC

https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=hymne&logNo=221841282483 

현상

threads 및 connection 증가

mysqldump FLUSH TABLES 지속

해결방안

* 고비용 쿼리 실행 시점과 backup 실행 시점을 겹치지 않도록 조정

* master 장비에서 백업이 실행되고 있다면, 이중화 구성 후 Slave 장비에서 백업 실행

* 고비용 쿼리 튜닝

* 장비 성능 점검 후 메모리 증설
* Flush method 변경 및 Swap 강제 해제

# /etc/my.cnf
innodb_flush_method = O_DIRECT
 
# shell
swapoff -a
swapon -a

* Kernel parameter 변경

# /etc/sysctl.conf
vm.swappiness = 60 -> 0
 
# shell
swapoff -a
swapon -a

FOUND_ROWS 적용 전

페이징 처리를 위해 limit 사용 시 전체 게시물의 수를 알기 위해 쿼리를 한번 더 해야 한다.

 

1. 해당 조건을 만족하는 게시물의 전체 수 조회
2. 그 페이지에서 보여줄 내용 조회

FOUND_ROWS 적용 후

SQL_CALC_FOUND_ROWS & FOUND_ROWS

 

SELECT 최상단에 SQL_CALC_FOUND_ROWS 라는 옵션만 주고 FOUND_ROWS() 를 사용하면 된다.

쿼리는 마찬가지로 두번이지만 두 번째 쿼리는 훨씬 빠르다.

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_enchovy WHERE id < 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

첫번째 쿼리 검색 결과 : 10개

두번째 쿼리 카운트 값 : WHERE조건에 해당되는 Rows 카운트 ( 1~100사이에 누락된 번호가 없다면 99을 리턴 )

 

주의사항

1. SQL_CALC_FOUND_ROWS 키워드는 UNION의 첫 번째 SELECT에 나타나야 한다.
2. FOUND_ROWS()의 값은 UNION ALL을 사용하는 경우에만 정확합니다. ALL이 없는 UNION을 사용하면 중복 제거가 발생하고 FOUND_ROWS()의 값은 근사치만 된다.
3. UNION에 LIMIT가 없는 경우 SQL_CALC_FUND_ROWS는 무시되고 UNION을 처리하기 위해 생성된 임시 테이블의 행 수를 반환한다.

4. 복제시) FOUND_ROWS() 은 statement-based 형태로는 안정적으로 복제되지 않습니다, 이경우 row-based 형태로 자동 변경되어 복제가 됩니다.

 

※ MySQL 4.7.16 이전 버전에는 버그가 있어, 원하는 결과를 리턴하지 않음

* 5.7.16 이전 버전의 Query중 SybQuery가 있다면, SubQuery 내의 결과 Row 수를 FOUND_ROWS()로 Retrun
* 5.7.16 버그 픽스 이후는 전체쿼리문을 하나의 구문으로 보고 결과 ROW수를 FOUND_ROWS()로 return
  FOUND_ROWS() 함수의 기능은 이전 SELECT 된 쿼리의 ROWS를 RETURN 하는 함수(즉, 5.7버전의 기능이 정확)

    

FOUND_ROWS() 함수는 MySQL 8.0.17에서 더 이상 사용되지 않으며 향후 버전의 MySQL에서 제거될 것으로 예상된다..

참고

https://string.tistory.com/93


to Top