개요 — 무엇을 하나
서비스 ▸ 데이터베이스(/service/database)는 등록된 데이터베이스 수집기(access=database)에 직접 연결해 부하 지표를 수집하고 스키마 구조를 분석하는 라이브 관제 화면입니다. 각 DB가 카드 하나로 표현되며, 카드마다 두 축의 부하를 한눈에 보여줍니다.
DB 관제는 2대 부하 축을 중심으로 설계되었습니다.
| 축 | 질문 | 핵심 지표 |
|---|---|---|
| ① 동시 실행 부하 | 지금 얼마나 몰려 있나 | threads_running, 연결 포화율(conn_pct), 대기 쿼리(waiting) |
| ② 처리량·비효율 | 얼마나 처리하고, 얼마나 낭비하나 | QPS(Δquestions/Δt), slow rate(Δslow_queries/Δt) |
여기에 더해 스키마 분석(총 용량·상위 DB·용량 상위 테이블·엔진 구성), 효율 점수(캐시 적중률·인덱스 사용률), InnoDB 메모리 관리(dirty page flush·checkpoint) 블록을 제공합니다.
이 화면은 대상 DB에 에이전트를 설치하지 않습니다. InfraGuard 앱이 등록된 접속정보로 원격 MySQL/MariaDB에 직접 붙어
SHOW GLOBAL STATUS·information_schema를 조회할 뿐입니다.
언제 쓰나
- 특정 DB가 갑자기 느려졌을 때 — 연결이 포화됐는지, 동시 실행이 폭증했는지, slow query가 늘었는지 즉시 판별.
- 커넥션 풀 튜닝 전후 —
threads_connected / max_connections포화율을 시간축으로 확인. - 용량 계획 — 어느 스키마·테이블이 디스크를 잡아먹는지, 엔진 구성이 어떤지 파악.
- InnoDB 플러시 압력 진단 — dirty page가 임계 아래에서 건강하게 순환하는지, checkpoint가 redo 용량 대비 얼마나 앞서갔는지.
- 캐시/인덱스 효율 점검 — 버퍼풀 적중률과 인덱스 사용률을 지표로 보고 튜닝 근거로 사용.
화면 구성
상단 KPI
| KPI | 의미 |
|---|---|
| DB 수 | 등록된 access=database 수집기 총 개수 |
| 정상 / 주의 / 중단 | 카드 상태(up/degraded/down) 집계 |
| 총 QPS | 전 카드 QPS 합계 |
| 연결 수 | 전 카드 threads_connected 합계 |
카드 헤더
- 호스트 라벨(수집기
host_alias→ config.host → cred_ref env 호스트 순). - 드라이버(
mysql/mariadb), 데이터베이스명, 가동시간(uptime), 상태 배지.
① 동시 실행 부하
- 연결 포화율 링게이지 =
threads_connected / max_connections. - 실행 중(
threads_running) — 실제로 CPU를 쓰는 스레드 수. - 대기(밀림)(
waiting) — 처리 시간이 임계(기본 2초) 이상인 쿼리 수.PROCESS권한 유무에 따라 서버 전역 또는 자기 연결만 집계(카드에 scope 표시).
② 처리량·비효율
- QPS 스파크라인 =
Δquestions / Δt(최근 60개 성공 샘플). - slow rate =
Δslow_queries / Δt, slow 누적(slow_queries).
카드 풋 — 효율 · lock
| 지표 | 계산 | 등급 |
|---|---|---|
| 캐시 적중률 | 1 − Δinnodb_buffer_pool_reads / Δinnodb_buffer_pool_read_requests |
우수 ≥99.5% · 양호 ≥98% · 보통 ≥90% |
| 인덱스 사용률 | Δhandler_read_key / (Δhandler_read_key + Δhandler_read_rnd_next) |
우수 ≥90% · 양호 ≥70% · 보통 ≥40% |
| lock | innodb_row_lock_time_avg(평균 row-lock 대기 ms) |
낮을수록 좋음 |
각 지표의 텍스트(캐시·인덱스·lock·checkpoint)에는 교육용 popover가 붙어 원인과 개선법(예: innodb_buffer_pool_size 증설, 커버링 인덱스, 갭 락 회피)을 설명합니다.
스키마 분석 (접이식)
기본은 접힌 상태이며 [펼치기]로 확장합니다. information_schema.tables에서 집계한 총 용량·테이블 수·스키마 수·용량 상위 스키마 8개·용량 상위 테이블 14개·엔진 구성을 보여줍니다.
스키마 분석은 서버에서 본질적으로 느린 쿼리(실측 약 3.5초)라 30분 장기 캐시로 우회합니다. 스케줄러(
infr:collect-db)가 캐시를 워밍하므로 웹 요청은 항상 캐시 히트합니다. 캐시가 비어 있으면 이 섹션은 잠시 숨겨졌다가 다음 폴링에서 나타납니다.
InnoDB 메모리 관리 (dirty page flush)
- Dirty 페이지 시계열 + 적절한 값(임계) overlay — MAX(
innodb_max_dirty_pages_pct)·LWM(innodb_max_dirty_pages_pct_lwm)을 절대 페이지 수로 환산해 겹칩니다(임의 상수가 아니라 서버가 실제로 aggressive flush를 시작하는 지점). - Checkpoint age(
Log sequence number − Last checkpoint at)와 redo 용량 대비 %. - 버퍼풀 크기·서버 RAM 대비 비율(alias로 조인한 OS 인스턴스의
mem_mb).
카드 배치
카드 그리드는 드래그로 순서 변경(SortableJS · 순서 localStorage 영속) + row-span masonry로 배치됩니다. 화면은 30초 폴링으로 갱신됩니다.
사용법
- 먼저 Administration ▸ 수집기에서 접근 방식
database수집기를 등록합니다.host/port/database/username+ 비밀번호(수집기에 Crypt 암호화 저장)를 입력하거나,cred_ref = env:PREFIX로.env의 기존 자격 세트를 재사용합니다. /service/database에 진입하면 등록된 DB가 카드로 나열됩니다. 진입 시 최신 샘플이 60초보다 오래됐으면 즉석 1회 샘플(ensureFresh)을 뜹니다.- 카드 헤더의 상태 배지로 문제 DB를 먼저 식별하고, 두 부하 축(동시성/처리량)에서 원인을 좁힙니다.
- 스키마 분석 [펼치기]로 용량 상위 스키마·테이블을 확인합니다(masonry가 높이 변화를 자동 재배치).
- 카드를 드래그해 관심 DB를 위로 배치합니다(순서는 브라우저에 저장).
cred_ref로 자격 재사용
cred_ref = env:PREFIX이면 .env에서 다음 키를 읽어 비밀을 DB에 저장하지 않습니다.
예: env:STATS_DB → blue 서버, env:STATS_GLORY_DB → glory 서버.
서버 전역 대기 쿼리를 보려면
waiting 집계를 서버 전역으로 하려면 모니터 계정에 PROCESS 권한이 필요합니다. 없으면 자기 연결만 집계됩니다. 최소권한 모니터 계정 예:
CREATE USER 'infra_monitor'@'%' IDENTIFIED BY 'YOUR_DB_PASSWORD';
GRANT PROCESS, SELECT ON *.* TO 'infra_monitor'@'%';
FLUSH PRIVILEGES;
scope 판정(
PROCESS유무)은 계정 고정이라 1시간 캐시됩니다. 나중에 권한을 부여하면 최대 1시간 뒤 반영됩니다(즉시 반영은 캐시 클리어).
데이터 소스
원천 쿼리 (원격 DB에서 실행)
| 쿼리 | 용도 |
|---|---|
SHOW GLOBAL STATUS |
threads·questions·slow_queries·bytes·buffer pool·handler·InnoDB 카운터 전량 |
SELECT @@GLOBAL.max_connections 등 |
max_connections, InnoDB flush 설정(1h 캐시) |
information_schema.processlist |
대기 쿼리 수 + scope 판정 |
information_schema.tables |
스키마 분석(30분 캐시) |
SHOW ENGINE INNODB STATUS |
checkpoint age(LSN − last checkpoint · PROCESS 필요) |
SHOW GRANTS FOR CURRENT_USER() |
PROCESS 권한 판정(scope) |
저장 테이블
수집한 샘플은 infr_db_metric(마이그레이션 000681) 시계열에 적재됩니다. 누적 카운터(questions/slow_queries/bytes_*)도 함께 저장해 다음 샘플에서 delta로 QPS·slow rate·효율 점수를 계산합니다.
infr_db_metric
collector_id host sampled_at uptime_sec
threads_connected/running/cached max_connections conn_pct
waiting waiting_scope
questions slow_queries qps slow_qps
bytes_received/sent recv_bps/sent_bps innodb_row_lock_waits
ok message raw(json: 효율·InnoDB 메모리 관리 파생값)
연결 누수 금지(§[1040] 교훈). 매 샘플마다 런타임 커넥션을 만들고
finally에서 즉시DB::purge합니다. PDO 타임아웃(기본 5초)으로 웹 요청·스케줄이 원격 지연에 묶이지 않게 합니다. 이 규율이 깨지면 공유 MySQL의max_connections가 고갈되어 프로덕션까지 영향을 줍니다.
수집 스케줄 · 게이팅
시계열은 아티즌 커맨드 infr:collect-db가 채웁니다. 단발 실행 후 종료(데몬 아님)하며 스케줄러가 매분 호출합니다.
# 특정 수집기만 즉시 1회(게이트 우회)
php artisan infr:collect-db --key=db@blue --force
운영 정책(Administration ▸ 운영 정책 · OpsPolicy)이 스케줄 실행을 게이팅합니다.
| 설정 | 기본 | 의미 |
|---|---|---|
db_collect_mode |
economy |
economy=콘솔 사용자(프레즌스)가 있을 때만 수집 · always=상시 |
db_collect_interval_sec |
60 |
수집 주기(초). 매분 tick이지만 실효 주기는 이 값 |
degraded/down 판정 임계값
DbCollectorService::statusOf가 OpsPolicy::dbThresholds()로 판정합니다.
| 사유(reason) | 조건 | 기본 임계 |
|---|---|---|
conn_saturation(연결 포화) |
conn_pct ≥ |
80% |
high_concurrency(높은 동시성) |
threads_running ≥ |
40 |
query_backlog(쿼리 밀림) |
waiting ≥ |
5 |
slow_query_rate(slow 증가) |
slow_qps ≥ |
1/s |
down(중단) |
샘플 없음·ok=false, 또는 최신 샘플이 5분보다 오래됨(stale) |
— |
사유가 하나라도 있으면 주의(degraded), 없으면 **정상(up)**입니다.
권한
- 이 화면은
infr.auth그룹에 속한 읽기 전용 콘솔입니다 — 조회 최소 레벨 demo=1. - 이 페이지에는 쓰기 엔드포인트가 없습니다. 대상 DB 접속정보 등록·수정은 Administration ▸ 수집기(admin=10,
level≥5게이트)에서 합니다. - 임계값·수집 모드 변경은 Administration ▸ 운영 정책(admin)에서 합니다.
문제해결 · FAQ
카드가 "중단(down)"으로 뜹니다
접속정보 없음(no_credentials)— config의 host/username이 비었거나cred_ref=env:PREFIX의 env 키가 없음.stale(최근 샘플 없음)— 최신 샘플이 5분 이상 오래됨. 스케줄러(infr:collect-db)가 도는지, economy 모드에서 콘솔 사용자가 있는지 확인.- 그 외 메시지 — 접속 실패 원인(인증 거부·호스트 도달 불가·타임아웃)이 그대로 표시됩니다.
php artisan infr:collect-db --key=<key> --force로 원인 확인.
QPS·slow rate·효율 점수가 "—"로 보입니다
파생값은 이전 성공 샘플과의 delta로 계산합니다. 첫 샘플이거나, DB 재시작으로 uptime이 줄었거나(카운터 리셋), 카운터가 역행하면 신뢰할 수 없어 null(—)로 둡니다. 두 번째 샘플 이후 정상 표시됩니다.
대기 쿼리가 "자기 연결만"이라고 나옵니다
모니터 계정에 글로벌 PROCESS 권한이 없어 information_schema.processlist에서 자기 연결만 보입니다. 위 서버 전역 대기 쿼리를 보려면 SQL로 PROCESS를 부여하세요(반영은 scope 캐시 만료 최대 1시간 뒤).
메모리 관리·checkpoint 섹션이 비어 있습니다
- 메모리 관리는
innodb_buffer_pool_pages_total이 있어야 표시됩니다(구버전 샘플이면 숨김). - checkpoint age는
SHOW ENGINE INNODB STATUS(→PROCESS권한)에서 파싱합니다. 권한이 없으면 checkpoint 라인·주석이 graceful하게 생략됩니다.
스키마 분석이 잠깐 비었다가 나타납니다
analysisCached는 캐시 조회 전용입니다. 최초 진입 시 캐시가 비어 있으면 섹션이 숨겨지고, 스케줄러가 캐시를 워밍한 뒤 다음 30초 폴링에서 나타납니다. 실패는 30초만 캐시(성공은 30분)하므로 일시 장애가 오래 고정되지 않습니다.
관련 항목
- DB 부하·튜닝 교육 — 락·캐시·인덱스·checkpoint popover의 배경 지식.
- 수집기 관리 —
access=database수집기 등록·비밀·cred_ref. - 운영 정책 — 수집 모드·주기·degrade 임계값.
- 세션(Redis) — 같은 방법론을 Redis 상태에 적용한 자매 화면.
- 서비스 개요 — DB 카드가 서비스 보드에 요약되는 라이브 관제.
- DB 수집기 파이프라인 — 수집 명령·연결 누수 방지 규율.
