PostgreSQL데이터베이스 서버의 동적 추적을 지원하는 기능을 제공합니다. 이를 통해 코드의 특정 지점에서 외부 유틸리티를 호출하여 실행을 추적할 수 있습니다.
많은 프로브 또는 추적 지점이 이미 소스 코드에 삽입되었습니다. 이러한 프로브는 데이터베이스 개발자와 관리자가 사용하도록 고안되었습니다. 기본적으로 프로브는 다음으로 컴파일되지 않습니다.포스트그레SQL; 사용자는 토토 베이를 사용할 수 있도록 구성 스크립트에 명시적으로 지시해야 합니다.
현재,DTrace유틸리티가 지원되며 이 글을 쓰는 시점에는 Solaris, macOS, FreeBSD, NetBSD 및 Oracle Linux에서 사용할 수 있습니다.SystemTap11479_11666src/include/utils/probes.h.
기본적으로 프로브는 사용할 수 없으므로 다음에서 프로브를 사용할 수 있도록 구성 스크립트에 명시적으로 지시해야 합니다.포스트그레SQL. DTrace 지원을 포함하려면 다음을 지정하세요.--활성화-dtrace구성합니다. 참조섹션 17.3.3.6자세한 정보는.
다음과 같이 소스 코드에 다수의 표준 프로브가 제공됩니다.표 27.49; 표 27.50탐색에 사용된 유형을 표시합니다. 향상을 위해 더 많은 토토 베이를 추가할 수 있습니다.포스트그레SQL의 관측 가능성.
표 27.49. 내장 DTrace 프로브
| 이름 | 매개변수 | 설명 |
|---|---|---|
거래 시작 |
(LocalTransactionId) |
새 트랜잭션 시작 시 실행되는 토토 베이. arg0은 트랜잭션 ID입니다. |
트랜잭션-커밋 |
(LocalTransactionId) |
트랜잭션이 성공적으로 완료되면 실행되는 토토 베이입니다. arg0은 트랜잭션 ID입니다. |
트랜잭션 중단 |
(LocalTransactionId) |
트랜잭션이 성공적으로 완료되지 않을 때 실행되는 토토 베이. arg0은 트랜잭션 ID입니다. |
쿼리-시작 |
(const char *) |
쿼리 처리가 시작될 때 실행되는 토토 베이. arg0은 쿼리 문자열입니다. |
쿼리 완료 |
(const char *) |
쿼리 처리가 완료되면 실행되는 토토 베이입니다. arg0은 쿼리 문자열입니다. |
쿼리-분석-시작 |
(const char *) |
질의 분석이 시작될 때 실행되는 토토 베이. arg0은 쿼리 문자열입니다. |
쿼리-분석 완료 |
(const char *) |
질의 구문 분석이 완료되면 실행되는 토토 베이. arg0은 쿼리 문자열입니다. |
쿼리-재작성-시작 |
(const char *) |
쿼리 재작성이 시작될 때 실행되는 토토 베이. arg0은 쿼리 문자열입니다. |
쿼리-재작성-완료 |
(const char *) |
쿼리 재작성이 완료되면 실행되는 토토 베이. arg0은 쿼리 문자열입니다. |
쿼리-계획-시작 |
() |
쿼리 계획이 시작될 때 실행되는 토토 베이. |
쿼리-계획-완료 |
() |
쿼리 계획이 완료되면 실행되는 토토 베이. |
쿼리-실행-시작 |
() |
쿼리 실행이 시작될 때 실행되는 토토 베이. |
쿼리-실행-완료 |
() |
쿼리 실행이 완료되면 실행되는 토토 베이. |
진술-상태 |
(const char *) |
서버 프로세스가 업데이트할 때마다 실행되는 토토 베이pg_stat_activity.상태. arg0은 새 상태 문자열입니다. |
체크포인트-시작 |
(int) |
체크포인트가 시작될 때 실행되는 토토 베이. arg0은 종료, 즉시 또는 강제와 같은 다양한 체크포인트 유형을 구별하는 데 사용되는 비트 플래그를 보유합니다. |
체크포인트 완료 |
(정수, 정수, 정수, 정수, 정수) |
체크포인트가 완료되면 실행되는 프로브입니다. (다음에 나열된 프로브는 체크포인트 처리 중에 순차적으로 실행됩니다.) arg0은 작성된 버퍼 수입니다. arg1은 총 버퍼 수입니다. arg2, arg3 및 arg4에는 각각 추가, 제거 및 재활용된 WAL 파일 수가 포함됩니다. |
clog-checkpoint-start |
(부울) |
체크포인트의 CLOG 부분이 시작될 때 실행되는 토토 베이. arg0은 일반 체크포인트의 경우 true이고 종료 체크포인트의 경우 false입니다. |
clog-checkpoint-done |
(부울) |
체크포인트의 CLOG 부분이 완료되면 실행되는 토토 베이. arg0은 for와 같은 의미를 갖습니다.clog-checkpoint-start. |
subtrans-checkpoint-start |
(부울) |
체크포인트의 SUBTRANS 부분이 시작될 때 실행되는 토토 베이. arg0은 일반 체크포인트의 경우 true이고 종료 체크포인트의 경우 false입니다. |
subtrans-checkpoint-done |
(부울) |
체크포인트의 SUBTRANS 부분이 완료되면 실행되는 토토 베이. arg0은 for와 같은 의미를 갖습니다.subtrans-checkpoint-start. |
multixact-checkpoint-start |
(부울) |
체크포인트의 MultiXact 부분이 시작될 때 실행되는 토토 베이입니다. arg0은 일반 체크포인트의 경우 true이고 종료 체크포인트의 경우 false입니다. |
multixact-checkpoint-done |
(부울) |
체크포인트의 MultiXact 부분이 완료되면 실행되는 토토 베이입니다. arg0은 for와 같은 의미를 갖습니다.multixact-checkpoint-start. |
버퍼-체크포인트-시작 |
(int) |
체크포인트의 버퍼 쓰기 부분이 시작될 때 실행되는 토토 베이입니다. arg0은 종료, 즉시 또는 강제와 같은 다양한 체크포인트 유형을 구별하는 데 사용되는 비트 플래그를 보유합니다. |
버퍼-동기화-시작 |
(정수, 정수) |
체크포인트 중에 더티 버퍼 쓰기를 시작할 때 실행되는 프로브(어떤 버퍼를 써야 하는지 식별한 후). arg0은 총 버퍼 수입니다. arg1은 현재 더티되어 작성되어야 하는 숫자입니다. |
버퍼-동기화-작성 |
(int) |
체크포인트 중 각 버퍼가 작성된 후 실행되는 토토 베이입니다. arg0은 버퍼의 ID 번호입니다. |
버퍼-동기화 완료 |
(정수, 정수, 정수) |
더티 버퍼가 모두 기록되면 실행되는 토토 베이입니다. arg0은 총 버퍼 수입니다. arg1은 체크포인트 프로세스에서 실제로 쓴 버퍼 수입니다. arg2는 기록될 것으로 예상되는 숫자입니다(arg1 of버퍼-동기화-시작); 차이점은 체크포인트 중에 버퍼를 플러시하는 다른 프로세스를 반영합니다. |
버퍼-체크포인트-동기화-시작 |
() |
더티 버퍼가 커널에 작성된 후 fsync 요청 발행을 시작하기 전에 실행되는 토토 베이. |
버퍼-체크포인트-완료 |
() |
디스크에 대한 버퍼 동기화가 완료되면 실행되는 토토 베이. |
2단계-체크포인트-시작 |
() |
체크포인트의 2단계 부분이 시작될 때 실행되는 토토 베이. |
2단계-체크포인트-완료 |
() |
체크포인트의 2단계 부분이 완료되면 실행되는 토토 베이. |
버퍼-확장-시작 |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int) |
관계 확장이 시작될 때 실행되는 토토 베이. arg0에는 확장할 포크가 포함되어 있습니다. arg1, arg2 및 arg3에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg4는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER23820_23913 |
버퍼 확장 완료 |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber) |
관계 확장이 완료되면 실행되는 토토 베이. arg0에는 확장할 포크가 포함되어 있습니다. arg1, arg2 및 arg3에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg4는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER24497_24625버퍼-확장-시작리소스 제약으로 인해. arg6에는 첫 번째 새 블록의 BlockNumber가 포함됩니다. |
버퍼-읽기-시작 |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int) |
버퍼 읽기가 시작될 때 실행되는 토토 베이. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER(-1) 공유 버퍼의 경우. |
버퍼 읽기 완료 |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) |
버퍼 읽기가 완료되면 실행되는 토토 베이. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER25932_26024 |
버퍼 플러시 시작 |
(ForkNumber, BlockNumber, Oid, Oid, Oid) |
공유 버퍼에 대한 쓰기 요청을 발행하기 전에 실행되는 토토 베이. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. |
버퍼 플러시 완료 |
(ForkNumber, BlockNumber, Oid, Oid, Oid) |
쓰기 요청이 완료되면 실행되는 토토 베이. (이는 단지 데이터를 커널에 전달하는 시간을 반영할 뿐이며 일반적으로 실제로 아직 디스크에 기록되지 않았습니다.) 인수는 for와 동일합니다.버퍼 플러시 시작. |
월-버퍼-쓰기-더티-시작 |
() |
사용 가능한 WAL 버퍼 공간이 더 이상 없기 때문에 서버 프로세스가 더티 WAL 버퍼를 쓰기 시작할 때 실행되는 프로브입니다. (이런 일이 자주 발생하면 다음을 의미합니다.wal_buffers너무 작습니다.) |
월-버퍼-쓰기-더티-완료 |
() |
더티 WAL 버퍼 쓰기가 완료되면 실행되는 토토 베이. |
월-삽입 |
(부호 없는 문자, 부호 없는 문자) |
WAL 레코드가 삽입될 때 실행되는 프로브. arg0은 레코드에 대한 리소스 관리자(rmid)입니다. arg1에는 정보 플래그가 포함되어 있습니다. |
월-스위치 |
() |
WAL 세그먼트 전환이 요청될 때 실행되는 토토 베이. |
smgr-md-read-start |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int) |
관계에서 블록을 읽기 시작할 때 실행되는 토토 베이. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER(-1) 공유 버퍼의 경우. |
smgr-md-읽기-완료 |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) |
블록 읽기가 완료되면 실행되는 토토 베이입니다. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER29426_29584 |
smgr-md-write-start |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int) |
관계에 블록을 쓰기 시작할 때 실행되는 토토 베이. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER(-1) 공유 버퍼의 경우. |
smgr-md-write-done |
(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) |
블록 쓰기가 완료되면 실행되는 토토 베이입니다. arg0 및 arg1에는 페이지의 포크 및 블록 번호가 포함됩니다. arg2, arg3 및 arg4에는 관계를 식별하는 테이블스페이스, 데이터베이스 및 관계 OID가 포함됩니다. arg5는 로컬 버퍼에 대한 임시 관계를 생성한 백엔드의 ID입니다. 또는INVALID_PROC_NUMBER30784_30946 |
정렬-시작 |
(int, bool, int, int, bool, int) |
정렬 작업이 시작될 때 실행되는 프로브. arg0은 힙, 인덱스 또는 데이텀 정렬을 나타냅니다. arg1은 고유 값 적용의 경우 true입니다. arg2는 키 열의 수입니다. arg3은 허용되는 작업 메모리의 킬로바이트 수입니다. 정렬 결과에 대한 무작위 액세스가 필요한 경우 arg4는 true입니다. arg5는 다음과 같은 경우 직렬을 나타냅니다.0, 병렬 작업자인 경우1또는 병렬 리더인 경우2. |
정렬 완료 |
(부울, 긴) |
정렬이 완료되면 실행되는 토토 베이. arg0은 외부 정렬의 경우 true이고 내부 정렬의 경우 false입니다. arg1은 외부 정렬에 사용되는 디스크 블록 수 또는 내부 정렬에 사용되는 메모리(KB)입니다. |
lwlock-획득 |
(문자 *, LWLockMode) |
LWLock이 획득되었을 때 실행되는 토토 베이. arg0은 LWLock의 트랜치입니다. arg1은 요청된 잠금 모드(독점 또는 공유)입니다. |
lwlock-release |
(문자 *) |
LWLock이 해제되었을 때 실행되는 토토 베이(그러나 해제된 웨이터는 아직 깨어나지 않았습니다). arg0은 LWLock의 트랜치입니다. |
lwlock-대기-시작 |
(문자 *, LWLockMode) |
LWLock을 즉시 사용할 수 없고 서버 프로세스가 잠금을 사용할 수 있을 때까지 기다리기 시작한 경우 실행되는 토토 베이입니다. arg0은 LWLock의 트랜치입니다. arg1은 요청된 잠금 모드(독점 또는 공유)입니다. |
lwlock-wait-done |
(문자 *, LWLockMode) |
서버 프로세스가 LWLock 대기에서 해제되었을 때 실행되는 토토 베이(실제로는 아직 잠금이 없습니다). arg0은 LWLock의 트랜치입니다. arg1은 요청된 잠금 모드(독점 또는 공유)입니다. |
lwlock-condacquire |
(문자 *, LWLockMode) |
호출자가 대기 없음을 지정했을 때 LWLock이 성공적으로 획득되었을 때 실행되는 토토 베이. arg0은 LWLock의 트랜치입니다. arg1은 요청된 잠금 모드(독점 또는 공유)입니다. |
lwlock-condacquire-fail |
(문자 *, LWLockMode) |
호출자가 대기 없음을 지정했을 때 LWLock이 성공적으로 획득되지 않았을 때 실행되는 토토 베이. arg0은 LWLock의 트랜치입니다. arg1은 요청된 잠금 모드(독점 또는 공유)입니다. |
잠금-대기-시작 |
(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) |
잠금을 사용할 수 없기 때문에 중량 잠금(lmgr 잠금)에 대한 요청이 대기하기 시작했을 때 실행되는 토토 베이입니다. arg0부터 arg3까지는 잠긴 객체를 식별하는 태그 필드입니다. arg4는 잠긴 객체의 유형을 나타냅니다. arg5는 요청되는 잠금 유형을 나타냅니다. |
잠금-대기-완료 |
(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) |
무거운 잠금(lmgr 잠금)에 대한 요청이 대기를 마쳤을 때(즉, 잠금을 획득했을 때) 실행되는 토토 베이입니다. 인수는 for와 동일합니다.잠금-대기-시작. |
교착상태 발견 |
() |
교착 상태 감지기에 의해 교착 상태가 발견되면 실행되는 프로브. |
표 27.50. 프로브 매개변수에 사용되는 정의된 유형
| 유형 | 정의 |
|---|---|
LocalTransactionId |
부호 없는 정수 |
LW잠금 모드 |
int |
잠금 모드 |
int |
블록번호 |
부호 없는 정수 |
오이드 |
부호 없는 정수 |
포크번호 |
int |
부울 |
부호 없는 문자 |
아래 예는 스냅샷의 대안으로 시스템의 트랜잭션 수를 분석하기 위한 DTrace 스크립트를 보여줍니다.pg_stat_database성능 테스트 전후:
#!/usr/sbin/dtrace -qs
postgresql$1:::트랜잭션-시작
@start["시작"] = 개수();
자체-ts = 타임스탬프;
postgresql$1:::트랜잭션-중단
@abort["중단"] = count();
postgresql$1:::트랜잭션-커밋
/자신-ts/
@commit["커밋"] = count();
@time["총 시간(ns)"] = sum(timestamp - self-ts);
자체-ts=0;
실행되면 예제 D 스크립트는 다음과 같은 출력을 제공합니다:
# ./txn_count.d `pgrep -n postgres` 또는 ./txn_count.d <PID ^C 시작 71 커밋 70 총 시간(ns) 2312105013
SystemTap은 기본 추적 지점이 호환되더라도 추적 스크립트에 대해 DTrace와 다른 표기법을 사용합니다. 주목할 만한 한 가지 점은 이 글을 쓰는 시점에서 SystemTap 스크립트는 하이픈 대신 이중 밑줄을 사용하여 프로브 이름을 참조해야 한다는 것입니다. 이 문제는 향후 SystemTap 릴리스에서 수정될 예정입니다.
DTrace 스크립트는 신중하게 작성하고 디버깅해야 한다는 점을 기억해야 합니다. 그렇지 않으면 수집된 추적 정보가 의미가 없게 될 수 있습니다. 문제가 발견되는 대부분의 경우 결함이 있는 것은 기본 시스템이 아니라 계측입니다. 동적 추적을 사용하여 찾은 정보를 논의할 때 해당 정보도 확인하고 논의할 수 있도록 사용된 스크립트를 동봉해야 합니다.
개발자가 원하는 곳 어디에서나 코드 내에서 새로운 프로브를 정의할 수 있지만 이를 위해서는 재컴파일이 필요합니다. 다음은 새 프로브를 삽입하는 단계입니다.
프로브를 통해 사용할 수 있는 프로브 이름 및 데이터 결정
다음에 프로브 정의 추가src/backend/utils/probes.d
포함pg_trace.h프로브 포인트가 포함된 모듈에 아직 존재하지 않는 경우 삽입TRACE_POSTGRESQL소스 코드의 원하는 위치에서 매크로를 조사
새 토토 베이를 사용할 수 있는지 다시 컴파일하고 확인
예: 다음은 트랜잭션 ID로 모든 새 트랜잭션을 추적하기 위해 프로브를 추가하는 방법에 대한 예입니다.
탐색 이름을 정할지 결정거래 시작다음 유형의 매개변수가 필요합니다.LocalTransactionId
다음에 프로브 정의 추가src/backend/utils/probes.d:
프로브 transaction__start(LocalTransactionId);
탐색 이름에 이중 밑줄 사용에 유의하세요. 프로브를 사용하는 DTrace 스크립트에서는 이중 밑줄을 하이픈으로 바꿔야 하므로거래 시작사용자를 위해 문서화할 이름입니다.
컴파일 시,transaction__start다음이라는 매크로로 변환됩니다.TRACE_POSTGRESQL_TRANSACTION_START(여기서 밑줄은 단일임을 확인하세요), 이는 다음을 포함하여 사용할 수 있습니다.pg_trace.h. 소스 코드의 적절한 위치에 매크로 호출을 추가합니다. 이 경우 다음과 같습니다.
TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
새 바이너리를 다시 컴파일하고 실행한 후 다음 DTrace 명령을 실행하여 새로 추가된 프로브를 사용할 수 있는지 확인하세요. 비슷한 출력이 표시됩니다.
# dtrace -ln 트랜잭션 시작 ID 제공자 모듈 기능 이름 18705 postgresql49878 postgres StartTransactionCommand 트랜잭션 시작 18755 postgresql49877 postgres StartTransactionCommand 트랜잭션 시작 18805 postgresql49876 postgres StartTransactionCommand 트랜잭션 시작 18855 postgresql49875 postgres StartTransactionCommand 트랜잭션 시작 18986 postgresql49873 postgres StartTransactionCommand 트랜잭션 시작
C 코드에 추적 매크로를 추가할 때 주의해야 할 몇 가지 사항이 있습니다:
탐침의 매개변수에 대해 지정된 데이터 유형이 매크로에 사용된 변수의 데이터 유형과 일치하는지 주의해야 합니다. 그렇지 않으면 컴파일 오류가 발생합니다.
대부분의 플랫폼에서 다음과 같은 경우PostgreSQL다음으로 구축됨--활성화-dtrace, 제어가 매크로를 통과할 때마다 추적 매크로에 대한 인수가 평가됩니다.추적이 이루어지지 않더라도. 몇 가지 지역 변수의 값만 보고하는 경우 일반적으로 걱정할 가치가 없습니다. 그러나 비용이 많이 드는 함수 호출을 인수에 넣지 않도록 주의하세요. 그렇게 해야 한다면 추적이 실제로 활성화되어 있는지 확인하여 매크로를 보호하는 것이 좋습니다.
if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED())
TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));
각 추적 매크로에는 해당하는활성화됨매크로.