Critical Operation Manual

유령 데몬 사건
완전 메뉴얼

실체 규명 · 대응 · 설계 원칙
작성일: 2026-01-03 05:52:46 (Asia/Seoul)

0 이 문서의 목적 (중요)

이 문서는 메모가 아니다.

이번 “유령 데몬 사건”의 전 과정, 판단, 실체 규명, 최종 설계 결론을 다음에도 다시 헷갈리지 않기 위해 남기는 운영 메뉴얼이다.

1. 사건 요약

데몬이 죽지 않는 문제가 아니라,
유저 세션(pmaadmin)이 지속적으로 데몬을 재생성하고 있었다.

2. 처음 나타난 현상

daemon_upbit_Ticker 데이터 무한 적재
파일 삭제/수정에도 계속 작동
Kill 명령에도 좀비처럼 부활
"유령 데몬"으로 인식됨

3. 잘못된 가설들 (뻘짓 정리)

가설 1: DB 이벤트(event_scheduler)가 범인

event_scheduler는 ON이었지만 실제 EVENTS는 비어 있었음
범인 아님

가설 2: 데몬 프로세스가 혼자 살아 있음

데몬을 kill 해도 다시 생김. 파일을 수정해도 영향 없음
데몬은 원인이 아니라 결과물

가설 3: 파일에 exit 넣으면 데몬이 멈춘다

파일 정지는 미래 실행 차단일 뿐, 이미 떠 있는 데몬에는 영향 없음
개념 혼동

4. 결정적 전환점

핵심 질문: "누가 실제로 DB에 INSERT를 치고 있는가?"

SHOW FULL PROCESSLIST;

1~2초 간격, 최소 10~20회 연속 실행 후 포착된 증거:

  • User: pmaadmin
  • Host: localhost
  • Command: Query
  • Info: INSERT INTO...

👉 진범 확정

5. 최종 실체 규명

진범

유저 세션 (웹 계층)
DB 계정: pmaadmin
php / phpMyAdmin / 웹 요청을 통해 매우 짧게 INSERT → COMMIT → 종료

데몬의 정체

데몬은 유령이다.
스스로 존재하지 않으며, 명령자가 살려내는 결과물일 뿐이다.



💡 왜 계속 안 잡혔으며, 왜 죽여도 안 됐는가?

스텔스성

INSERT가 찰나의 순간에 실행되고 사라짐. SHOW PROCESSLIST 한두 번으로는 "없는 것처럼" 보임.

무한 재생성

데몬을 죽이면 명령자(유저 세션)가 이를 감지하거나 재실행하여 새로운 PID로 다시 태어남.

"데몬을 못 죽인 게 아니라, 죽여도 계속 다시 만들어졌던 것"

8. 정답 구조 (원칙)

1

데몬은 관리 대상 X

쫓아다닐 필요 없음. 결과물일 뿐.

2

명령자가 핵심 통제 대상

실행, 중지, 재생성의 주체는 명령자다.

3

파일 레벨 제어

파일이 곧 실행 여부이자 신분증이다.

9. 파일 중지 가드 (Future Block)

<?php
// DAEMON EXECUTION BLOCKED
exit;

미래의 실행을 100% 차단하지만, 이미 떠 있는 데몬은 별도 사살 필요.

11. 고유 ID 전략

$DAEMON_ID = pathinfo(__FILE__, PATHINFO_FILENAME);

파일명이 곧 고유 ID다.

10. 대응 프로세스 & 13. 최종 원칙

🚀 사살과 재발 방지 순서

  1. 파일 무력화 (중지 가드 삽입 or 파일명 변경)
  2. 이미 떠 있는 데몬 1회 사살
  3. 이후 감시 (끝)

⚖️ 불변의 운영 원칙

  • 데몬은 태어나지 못하게 한다.
  • 이미 태어난 건 한 번만 죽인다.
  • 모든 제어는 PHP 파일로 한다.
  • 유저 세션은 실행만 하고 판단하지 않는다.
  • 파일명이 곧 고유 ID다.

14. 이 문서의 의미

추측의 기록
감정의 기록
실체 규명과 정답 설계의 기록 ⭕

"다음에 같은 증상이 오면, 이 문서 1번부터 그대로 따라 하면 끝"