메뉴 바로가기본문 바로가기

답변문의 답변드리겠습니다.

2026.10.19조회 20

안녕하세요~ 고객님, ipTIME 기술팀 입니다.

문의하신 내용에 답변 드리겠습니다.

개발부서에 전달하겠습니다.

감사합니다.

일단 제쪽에서 원인은 찾아서 해결 했습니다.

------------------

[버그 리포트 및 개선 건의]

ipTIME ICC 도커(icc:1_018) 구동 시 일 1.1TB+ 디스크 쓰기 폭주 원인 및 패치 건의

1. 현상 요약
ipTIME ICC(통합 관제 컨트롤러) 도커 컨테이너(icc:1_018) 운영 중, 관리 사이트(Site)가 단 2곳뿐임에도 불구하고 약 9.7일 동안 물리 디스크에 11.4TB(하루 평균 1.17TB, 상시 15~40MB/s)의 비정상적인 디스크 쓰기가 발생하여 심각한 I/O 병목이 발생하는 문제를 확인했습니다.

정밀 분석 결과, 단순 DB 설정 문제를 넘어 plugin_icc.so 내부의 Logs 테이블 처리 쿼리 결함과 이벤트 큐 적체 현상이 결합되어 발생하는 구조적 버그임을 확인하여 개선을 건의드립니다.


2. 정밀 원인 분석 (Root Cause)

[원인 1] 사이트 연결/끊김 시 실행되는 UPDATE 쿼리의 WHERE 조건 누락 및 인덱스 미비 (핵심 원인) 사이트가 재연결될 때마다 plugin_icc.so에서 아래 쿼리를 호출합니다.
-------------------------------------------------- UPDATE `Logs` SET checked = 'System' WHERE type = 'event' AND s_id = '6' AND device_mac IS NULL AND `key` = 'event.site.disconnected'
--------------------------------------------------
- 문제점 A (WHERE 조건 누락): 조건절에 `AND checked = 'Active'` (또는 `checked != 'System'`) 조건이 빠져 있어, 이미 과거에 'System'으로 처리된 수십만 건의 과거 로그까지 매번 업데이트 대상으로 스캔합니다.
- 문제점 B (복합 인덱스 부재): `Logs` 테이블에 단일 컬럼 인덱스(idx_s_id, idx_type, idx_mac, idx_key)만 존재하고 복합 인덱스가 없다 보니, MariaDB 옵티마이저가 매 쿼리마다 수십만 건의 행을 Index Merge 및 풀스캔하며 쿼리 1회당 수십 MB의 디스크 I/O를 발생시킵니다. (1초에 125,000건 이상의 Handler_update 및 11MB/s 이상의 Redo 로그 기록 발생 실측)

[원인 2] `event.site.*` 이벤트 로그의 자동 정리(Retention) 누락 plugin_icc.so 내 로그 정리 쿼리를 확인해 보면 다음과 같습니다.
-------------------------------------------------- DELETE FROM Logs WHERE `key` LIKE 'event.station%%' && date < DATE_SUB(NOW(), INTERVAL 15 DAY)
--------------------------------------------------
- 단말 이벤트(`event.station%`)만 15일 경과 시 삭제하고, 사이트 연결/끊김 이벤트(`event.site.connected`, `event.site.disconnected`)는 삭제 대상에서 누락되어 있습니다.
- 그 결과 네트워크 순단이나 재연결이 반복되면 `Logs` 테이블에 수십만 건(실측 53만 건 이상)의 `event.site.*` 레코드가 무한정 누적되며, [원인 1]의 UPDATE 쿼리 부하를 기하급수적으로 증폭시킵니다.

[원인 3] servd 이벤트 큐(Event Runner)의 무제한 적체 및 지연 처리 현상
- 특정 시점(예: 네트워크 불안정 등)에 다수의 사이트 연결/끊김 이벤트가 발생하면, DB(Logs 테이블)의 UPDATE 처리 속도가 느려지면서 `servd` 프로세스 메모리에 미처리 이벤트 큐가 수십만 건(메모리 120MB 이상) 적체됩니다.
- 이후 사이트 연결이 아예 해제된 상태에서도, `servd`가 일주일 전에 메모리에 쌓인 과거 `connected / disconnected` 이벤트를 초당 수십 건씩 꺼내어 며칠 내내 DB에 계속 INSERT 및 UPDATE를 반복(실측: 10월 19일 시점에 10월 12일 자 이벤트를 계속 DB에 기록)하며 디스크에 하루 1TB 이상의 쓰기를 유발합니다.
- 동일한 사이트(s_id)의 연결/끊김 상태 변경 이벤트는 큐에 중복 적재하지 않고 최신 상태만 반영(Debounce / Coalesce)하도록 개선이 필요합니다.

[원인 4] 컨테이너 내 MariaDB 5.5 기본 설정 파일(/etc/my.cnf) 부재
- 컨테이너 내부에 `/etc/my.cnf` 파일이 없어 MariaDB 5.5 초기 기본값으로 구동됩니다.
* `innodb_log_file_size = 5M` (기본값): Redo 로그가 5MBx2=10MB에 불과해 수 초마다 강제 체크포인트(Checkpoint)가 발생하며 `ibdata1`에 과도한 플러시 발생
* `innodb_buffer_pool_size = 128M` (기본값): `ibdata1` 크기가 커지면 메모리 부족으로 디스크 스래싱 발생
* `innodb_flush_log_at_trx_commit = 1` (기본값): 매 이벤트 쿼리마다 물리 디스크 강제 fsync() 호출


3. 패치 및 개선 제안 사항

(1) plugin_icc.so 내 SQL 쿼리 및 테이블 스키마 개선
- `Logs` 업데이트 쿼리에 미확인 건만 갱신하도록 조건 추가:
UPDATE `Logs` SET checked = 'System' WHERE type = 'event' AND s_id = '%d' AND device_mac IS NULL AND `key` = 'event.site.disconnected' AND checked = 'Active';
- `Logs` 테이블에 복합 인덱스 기본 추가:
ALTER TABLE `Logs` ADD INDEX `idx_site_event` (`s_id`, `type`, `key`, `checked`, `device_mac`);
- 15일 경과 로그 삭제 쿼리에 `event.site.%`도 포함되도록 수정:
DELETE FROM `Logs` WHERE (`key` LIKE 'event.station%%' OR `key` LIKE 'event.site%%') AND date < DATE_SUB(NOW(), INTERVAL 15 DAY);

(2) servd 사이트 연결/끊김 이벤트 디바운싱(Debounce) 또는 큐 중복 제거
- 짧은 시간 내 반복되는 `event.site.connected` / `event.site.disconnected` 이벤트가 큐에 수만 건씩 쌓여 뒷북 처리되지 않도록 큐 크기 제한 또는 상태 병합 처리

(3) 도커 이미지 내 `/etc/my.cnf` 기본 튜닝값 탑재
--------------------------------------------------
[mysqld]
innodb_buffer_pool_size = 512M innodb_log_file_size = 128M innodb_flush_log_at_trx_commit = 2 innodb_doublewrite = 0
--------------------------------------------------
------
```

질문

QnA
제  목문의 답변드리겠습니다.
이름고객지원실
제품명iptime icc
인터넷 회선KT 기가슬림
목록보기
안녕하세요~ 고객님, ipTIME 기술팀 입니다.

문의하신 내용에 답변 드리겠습니다.

개발부서에 전달하겠습니다.

감사합니다.

일단 제쪽에서 원인은 찾아서 해결 했습니다.

------------------

[버그 리포트 및 개선 건의]

ipTIME ICC 도커(icc:1_018) 구동 시 일 1.1TB+ 디스크 쓰기 폭주 원인 및 패치 건의

1. 현상 요약
ipTIME ICC(통합 관제 컨트롤러) 도커 컨테이너(icc:1_018) 운영 중, 관리 사이트(Site)가 단 2곳뿐임에도 불구하고 약 9.7일 동안 물리 디스크에 11.4TB(하루 평균 1.17TB, 상시 15~40MB/s)의 비정상적인 디스크 쓰기가 발생하여 심각한 I/O 병목이 발생하는 문제를 확인했습니다.

정밀 분석 결과, 단순 DB 설정 문제를 넘어 plugin_icc.so 내부의 Logs 테이블 처리 쿼리 결함과 이벤트 큐 적체 현상이 결합되어 발생하는 구조적 버그임을 확인하여 개선을 건의드립니다.


2. 정밀 원인 분석 (Root Cause)

[원인 1] 사이트 연결/끊김 시 실행되는 UPDATE 쿼리의 WHERE 조건 누락 및 인덱스 미비 (핵심 원인)
사이트가 재연결될 때마다 plugin_icc.so에서 아래 쿼리를 호출합니다.
--------------------------------------------------
UPDATE `Logs` SET checked = 'System'
WHERE type = 'event' AND s_id = '6' AND device_mac IS NULL AND `key` = 'event.site.disconnected'
--------------------------------------------------
- 문제점 A (WHERE 조건 누락): 조건절에 `AND checked = 'Active'` (또는 `checked != 'System'`) 조건이 빠져 있어, 이미 과거에 'System'으로 처리된 수십만 건의 과거 로그까지 매번 업데이트 대상으로 스캔합니다.
- 문제점 B (복합 인덱스 부재): `Logs` 테이블에 단일 컬럼 인덱스(idx_s_id, idx_type, idx_mac, idx_key)만 존재하고 복합 인덱스가 없다 보니, MariaDB 옵티마이저가 매 쿼리마다 수십만 건의 행을 Index Merge 및 풀스캔하며 쿼리 1회당 수십 MB의 디스크 I/O를 발생시킵니다. (1초에 125,000건 이상의 Handler_update 및 11MB/s 이상의 Redo 로그 기록 발생 실측)

[원인 2] `event.site.*` 이벤트 로그의 자동 정리(Retention) 누락
plugin_icc.so 내 로그 정리 쿼리를 확인해 보면 다음과 같습니다.
--------------------------------------------------
DELETE FROM Logs WHERE `key` LIKE 'event.station%%' && date < DATE_SUB(NOW(), INTERVAL 15 DAY)
--------------------------------------------------
- 단말 이벤트(`event.station%`)만 15일 경과 시 삭제하고, 사이트 연결/끊김 이벤트(`event.site.connected`, `event.site.disconnected`)는 삭제 대상에서 누락되어 있습니다.
- 그 결과 네트워크 순단이나 재연결이 반복되면 `Logs` 테이블에 수십만 건(실측 53만 건 이상)의 `event.site.*` 레코드가 무한정 누적되며, [원인 1]의 UPDATE 쿼리 부하를 기하급수적으로 증폭시킵니다.

[원인 3] servd 이벤트 큐(Event Runner)의 무제한 적체 및 지연 처리 현상
- 특정 시점(예: 네트워크 불안정 등)에 다수의 사이트 연결/끊김 이벤트가 발생하면, DB(Logs 테이블)의 UPDATE 처리 속도가 느려지면서 `servd` 프로세스 메모리에 미처리 이벤트 큐가 수십만 건(메모리 120MB 이상) 적체됩니다.
- 이후 사이트 연결이 아예 해제된 상태에서도, `servd`가 일주일 전에 메모리에 쌓인 과거 `connected / disconnected` 이벤트를 초당 수십 건씩 꺼내어 며칠 내내 DB에 계속 INSERT 및 UPDATE를 반복(실측: 10월 19일 시점에 10월 12일 자 이벤트를 계속 DB에 기록)하며 디스크에 하루 1TB 이상의 쓰기를 유발합니다.
- 동일한 사이트(s_id)의 연결/끊김 상태 변경 이벤트는 큐에 중복 적재하지 않고 최신 상태만 반영(Debounce / Coalesce)하도록 개선이 필요합니다.

[원인 4] 컨테이너 내 MariaDB 5.5 기본 설정 파일(/etc/my.cnf) 부재
- 컨테이너 내부에 `/etc/my.cnf` 파일이 없어 MariaDB 5.5 초기 기본값으로 구동됩니다.
* `innodb_log_file_size = 5M` (기본값): Redo 로그가 5MBx2=10MB에 불과해 수 초마다 강제 체크포인트(Checkpoint)가 발생하며 `ibdata1`에 과도한 플러시 발생
* `innodb_buffer_pool_size = 128M` (기본값): `ibdata1` 크기가 커지면 메모리 부족으로 디스크 스래싱 발생
* `innodb_flush_log_at_trx_commit = 1` (기본값): 매 이벤트 쿼리마다 물리 디스크 강제 fsync() 호출


3. 패치 및 개선 제안 사항

(1) plugin_icc.so 내 SQL 쿼리 및 테이블 스키마 개선
- `Logs` 업데이트 쿼리에 미확인 건만 갱신하도록 조건 추가:
UPDATE `Logs` SET checked = 'System' WHERE type = 'event' AND s_id = '%d' AND device_mac IS NULL AND `key` = 'event.site.disconnected' AND checked = 'Active';
- `Logs` 테이블에 복합 인덱스 기본 추가:
ALTER TABLE `Logs` ADD INDEX `idx_site_event` (`s_id`, `type`, `key`, `checked`, `device_mac`);
- 15일 경과 로그 삭제 쿼리에 `event.site.%`도 포함되도록 수정:
DELETE FROM `Logs` WHERE (`key` LIKE 'event.station%%' OR `key` LIKE 'event.site%%') AND date < DATE_SUB(NOW(), INTERVAL 15 DAY);

(2) servd 사이트 연결/끊김 이벤트 디바운싱(Debounce) 또는 큐 중복 제거
- 짧은 시간 내 반복되는 `event.site.connected` / `event.site.disconnected` 이벤트가 큐에 수만 건씩 쌓여 뒷북 처리되지 않도록 큐 크기 제한 또는 상태 병합 처리

(3) 도커 이미지 내 `/etc/my.cnf` 기본 튜닝값 탑재
--------------------------------------------------
[mysqld]
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
innodb_flush_log_at_trx_commit = 2
innodb_doublewrite = 0
--------------------------------------------------
------
```

[2026-10-19 12:42:07]
목록보기
▲A/S 신청합니다.
▼HG25008 허브 BTV IGMP안됩니다
챗봇 상담
설치도우미 바로가기
펌웨어 업그레이드 바로가기
펌웨어 복구도우미 바로가기
ipTIME 검색기 바로가기
EasyMesh 접속기 바로가기
ipDISK ipCloud 바로가기
ipCAM Tools 바로가기
DDNS 관리 바로가기

경기도 용인시 기흥구 죽전로 15 6층 (보정동, 벤포스타2빌딩 6층)

통신판매업신고번호 : 용인 기흥 제 388호
사업자등록번호 : 129-81-44050 | 대표자 : 김인

ALL contents are copyright 2004-EFM Networks Co
All right reserved