설명
리눅스 커널 파라미터 중 하나로, 스왑 메모리 활용 수준을 조절한다.
값의 범위: 0 ~ 200 (기본값: 60)
NOTE
커널 공식 문서 기준 최대값은 200이다. 100을 초과하는 값은 zram/zswap 같은 고속 스왑 장치가 있는 경우에만 의미 있다.
| 값 | 설명 |
|---|---|
vm.swappiness = 0 | 파일 캐시가 소진될 때까지 스왑 안 함 ⚠️ |
vm.swappiness = 1 | 스왑 사용 최소화 (DB 서버 권장) |
vm.swappiness = 10 | 스왑 크게 회피 |
vm.swappiness = 60 | 기본값 |
vm.swappiness = 100 | 스왑과 파일 캐시를 동등하게 처리 |
vm.swappiness = 200 | 스왑 적극 사용 (고속 스왑 장치 전용) |
MariaDB 공식 문서 및 Percona에서는 1을 권장한다.
Red Hat 공식 문서는 Oracle DB 서버에 10을 권장한다.
DB 장비는
10으로 설정하여 운영 중.
동작 원리
커널의 메모리 회수 서브시스템(kswapd)은 메모리가 부족해지면 아래 수식을 통해 스왑과 파일 캐시 해제 중 어느 쪽을 먼저 처리할지 결정한다.
anon_prio = swappiness # 익명 페이지(힙/스택) 회수 가중치
file_prio = 200 - swappiness # 파일 캐시 해제 가중치
swappiness = 1이면 file_prio = 199로, 파일 캐시를 99.5% 먼저 해제한 뒤 극소량의 익명 페이지만 스왑한다. DB 프로세스의 InnoDB 버퍼 풀이 최대한 보호된다.
swappiness = 0 경고 (커널 3.5+)
커널 3.5 이후로 swappiness=0의 동작이 변경되었다. 이전에는 스왑을 거의 사용하지 않는 안전한 설정이었으나, 변경 이후 익명 페이지 스캔이 완전히 차단되어 스왑 공간이 남아 있어도 OOM Killer가 발동할 수 있다.
| 커널 3.5 이전 | 커널 3.5+ (RHEL 6.4+) | |
|---|---|---|
swappiness = 0 | 스왑 거의 안 함 (안전) | OOM Killer 발동 위험 |
swappiness = 1 | 스왑 거의 안 함 | 스왑 극도 회피, 안전 |
Red Hat 공식 문서: “Since RHEL 6.4, setting swappiness=0 more aggressively avoids swapping out, which increases the risk of OOM killing under strong memory and I/O pressure.”
따라서 DB 서버에서는 0 대신 1을 사용해야 한다.
DB 서버에서 스왑이 위험한 이유
- 레이턴시 폭발: HDD 스왑 접근 시간 ~10ms vs RAM ~100ns (약 100,000배 차이)
- 락 지속 시간 증가: 스왑된 메모리 접근 중 뮤텍스 보유 → 전체 쿼리 큐 대기
- InnoDB 버퍼 풀 효율 저하: 버퍼 풀이 스왑되면 디스크 I/O가 두 배 발생 (스왑 read + 데이터 read)
- MariaDB 공식 경고: “MariaDB’s internal algorithms assume that memory is not swap, and are highly inefficient if it is”
설정값 확인
# 아래 3가지 방법으로 확인 가능
sysctl vm.swappiness
sysctl -a | grep swappiness
cat /proc/sys/vm/swappinessvm.swappiness = 60
vm.swappiness = 60
60
설정 방법
즉시(임시) 적용
재기동 시 이전 설정값 또는 기본값으로 복귀됨.
sudo sysctl -w vm.swappiness=1vm.swappiness = 1
영구 적용
방법 1: /etc/sysctl.d/ (권장)
패키지 업그레이드 시 /etc/sysctl.conf가 덮어쓰일 위험 없이 독립 파일로 관리할 수 있다.
# 설정 파일 생성
sudo tee /etc/sysctl.d/99-db-tuning.conf << 'EOF'
# Database server memory tuning
vm.swappiness = 1
EOF
# 모든 sysctl.d 파일 즉시 반영
sudo sysctl --system
# 확인
sysctl vm.swappiness# Database server memory tuning
vm.swappiness = 1
* Applying /etc/sysctl.d/10-bufferbloat.conf ...
* Applying /etc/sysctl.d/10-console-messages.conf ...
...
* Applying /etc/sysctl.d/99-db-tuning.conf ...
vm.swappiness = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.conf ...
vm.swappiness = 1
방법 2: /etc/sysctl.conf
# /etc/sysctl.conf 에 아래 내용 추가 또는 기존 값 수정
vm.swappiness = 1
# 설정 재로드 (또는 장비 재기동)
sudo sysctl -p
sysctl -p는/etc/sysctl.conf하나만 로드하고,sysctl --system은/etc/sysctl.d/전체를 로드한다.
NUMA 환경 추가 설정
NUMA(Non-Uniform Memory Access) 시스템에서는 swappiness 외에 vm.zone_reclaim_mode도 함께 설정해야 한다. 기본값이 1이면 NUMA 노드 로컬 메모리가 부족할 때 원격 노드 메모리 대신 스왑을 먼저 사용한다.
# zone_reclaim_mode 현재값 확인
sysctl vm.zone_reclaim_modevm.zone_reclaim_mode = 0
# /etc/sysctl.d/99-db-tuning.conf
vm.swappiness = 1
vm.zone_reclaim_mode = 0 # 로컬 존 강제 회수 비활성화 → 버퍼 캐시 보호LinkedIn 엔지니어링 팀이 zone_reclaim_mode=1 환경에서 워킹 세트 데이터가 메모리에 있음에도 직접 페이지 스캔이 발생하는 문제를 발견했으며, 0으로 변경 후 에러율이 1/4로 감소했다.
스왑 사용량 모니터링
# 스왑 사용량 요약
free -h total used free shared buff/cache available
Mem: 15Gi 5.5Gi 4.7Gi 104Mi 5.7Gi 10Gi
Swap: 4.0Gi 1.2Gi 2.8Gi
# 스왑 파티션/파일별 상세
cat /proc/swapsFilename Type Size Used Priority
/dev/sdc partition 4194304 1293584 -2
# 프로세스별 스왑 사용량 (내림차순)
awk '/VmSwap/ && $2 > 0 {
split(FILENAME, a, "/"); pid = a[3]
cmd = "/proc/" pid "/comm"; getline name < cmd; close(cmd)
if (name == "") name = "?"
printf "%s (PID %s): %s kB\n", name, pid, $2
}' /proc/[0-9]*/status 2>/dev/null | sort -t: -k2 -rn | head -10ollama (PID 73955): 400512 kB
bun (PID 91480): 192128 kB
bun (PID 96852): 189696 kB
code-cli (PID 26523): 4992 kB
code-cli (PID 26062): 4864 kB