lablup / lablup/backend.ai

destroyed 상태 endpoint에 대해 manager가 route를 무한 재생성하여 routings 테이블이 무한 증식함

Open
#13,446 0 comments 0 reactions 0 assignees View on GitHub
backend-request
Dominant language
Python
Stars
670
Forks
183
Avg merge
15h 13m
Merged PRs (30d)
368

Description

## 요약

`lifecycle_stage='destroyed'` 상태인 endpoint에 대해 매니저가 계속 route(routing)를 생성하며, 생성된 route는 전부 `failed_to_start`로 끝난다. 매니저가 떠 있는 동안 무한히 누적되어 `routings` 테이블이 계속 증가한다.

## 재현 환경

- 환경: 로컬 개발 서버 (10.82.130.172)
- 버전: 26.8.0rc1 / main `feccbe55d` / alembic head `c1a7d3f05e28`
- DB: PostgreSQL 16.3-alpine (halfstack)
- 계정: admin@lablup.com (superadmin)
- 데이터: 다른 호스트(10.122.10.215)의 운영 데이터를 백업 복원한 상태

## 재현 방법

1. `lifecycle_stage='destroyed'` 이면서 `replicas > 0` 인 endpoint가 존재하는 DB 상태를 준비한다 (본 건에서는 백업 복원 결과 해당 endpoint가 453개 존재했다).
1. 매니저를 기동한다 (`./dev start all`).
1. 수 분간 대기 후 `routings` 테이블의 행 수 변화를 관찰한다.

```sql
-- 최근 10분간 생성된 route를 endpoint의 lifecycle_stage 별로 집계
SELECT e.lifecycle_stage, count(DISTINCT r.endpoint) AS endpoints, count(*) AS new_routings
FROM routings r JOIN endpoints e ON e.id = r.endpoint
WHERE r.created_at > now() - interval '10 min'
GROUP BY 1 ORDER BY 3 DESC;
```

## 기대 동작

`destroyed` 상태의 endpoint는 종료된 상태이므로 replica 재조정 대상에서 제외되어야 하며, 새로운 route가 생성되지 않아야 한다.

## 실제 동작

`destroyed` endpoint에 대해 route가 계속 생성되고 전부 `failed_to_start`로 종료된다.

관측값 (매니저 기동 후 약 10분 시점):

| 항목 | 값 |
|---|---|

|—|—|
|---|---|

| 최근 10분간 신규 route | 351건 — **전부** `status='failed_to_start'` |
|---|---|

| 신규 route를 만든 endpoint | 35개 — **전부** `lifecycle_stage='destroyed'` |
|---|---|

| 해당 endpoint들의 `replicas` | 전부 `1` |
|---|---|

| DB 전체에서 `destroyed` + `replicas > 0` endpoint | 453개 |
|---|---|

| `destroyed` endpoint 총계 | 454개 (`ready`는 2개뿐) |
|---|---|

| 증가 속도 | 약 117행/분 |
|---|---|

| `routings` 테이블 증가량 | 약 1.9 MB/시간 |
|---|---|

`ready` 상태 endpoint는 2개뿐인데도(`replicas` 각각 0, 1) route 생성은 오직 `destroyed` endpoint에서만 발생했다.

시간 경과에 따른 실측:

```
15:31:22 routings=107667 failed_to_start=312
15:31:42 routings=107667 failed_to_start=351
15:32:02 routings=107706 failed_to_start=351
```

### 장기 운영 환경에서의 누적 규모

동일 데이터의 원본 호스트(10.122.10.215)에서는 DB가 \*6GB\*까지 증가했고, 그 대부분이 `failed_to_start` route \*239만 건\*과 그에 연동된 히스토리 테이블(`route_history`, `replica_group_history`, `deployment_history`)이었다. 백업 시 이 데이터를 제외하자 22MB(압축)로 줄었다.

## 원인 추정

미파악 — 본 리포트는 관측 사실 기록 목적이며 원인 분석은 수행하지 않았다. `lifecycle_stage='destroyed'` endpoint가 manager / sokovan deployment reconcile 로직에서 replica 재조정(scale-up) 대상에서 제외되지 않고 있는 것으로 추정된다.

## 영향

- `routings` 및 연동 히스토리 테이블이 무한 증가 → DB 용량 고갈
- 장기 운영 환경에서 DB 6GB 도달 (실측)
- route 생성/실패 사이클이 계속 돌면서 스케줄러 부하 발생

## 관련 컴포넌트

- 테이블: `routings`, `endpoints`, `route_history`, `replica_group_history`, `deployment_history`
- 컴포넌트: manager / sokovan deployment reconcile

JIRA Issue: BA-7175

Contributor guide

Open the contributing guide

Research direction

Start by tracing the manager and sokovan deployment reconcile logic for endpoints with lifecycle_stage='destroyed' and replicas > 0. Reproduce with ./dev start all and the provided SQL query, then verify that destroyed endpoints no longer create routes or failed_to_start records and that routings and related history tables stop growing.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.