K3s MySQL 시작 OOM 검색 을 한 번 기록 합 니 다.
재현
Kubectl 을 사용 하여 MySQL 을 직접 실행 하면 다시 실행 할 수 있 습 니 다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: root
resources:
limits:
memory: 4G
cpu: 500m
dmesg
mysqld 분배 가 3.7G 메모 리 를 초과 한 후에 죽 임 을 볼 수 있 습 니 다.[ 839.399262] Tasks state (memory values in pages):
[ 839.399263] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
...
[ 839.399278] [ 34888] 0 34888 4208240 974177 7962624 0 -998 mysqld
[ 839.399280] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=...,mems_allowed=0,oom_memcg=/kubepods/pod..,task_memcg=/kubepods/pod../56..,task=mysqld,pid=34888,uid=0
[ 839.399294] Memory cgroup out of memory: Killed process 34888 (mysqld) total-vm:16832960kB, anon-rss:3895388kB, file-rss:1320kB, shmem-rss:0kB
[ 839.496988] oom_reaper: reaped process 34888 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
조사 하 다
MySQL 설정 최적화
첫 번 째 반응 은 MySQL 설정 에 문제 가 있어 서 설정 을 수정 하여 각종 buffer 의 크기 를 줄 이 는 것 입 니 다.
[mysqld]
innodb_buffer_pool_size = 32M
innodb_buffer_pool_instances=1
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
key_buffer_size = 16k
myisam_sort_buffer_size = 16k
max_connections = 50
open_files_limit = 4096
max_allowed_packet = 1M
table_open_cache = 16
sort_buffer_size = 512k
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
thread_cache_size = 64
query_cache_size = 0
tmp_table_size = 12M
thread_stack=256K
그러나 문 제 는 여전히 많은 설정 을 바 꾸 었 지만 효과 가 없 었 다.추적 이나 디 버 깅 이 필요 한 것 같다.
bpftrace 로 메모리 할당
여기 서 strace 를 사용 하지 않 은 것 은 시작 하면 죽 기 때 문 입 니 다.미 러 시작 명령 을 수정 한 다음 용기 에 strace 를 설치 하고 실행 해 야 합 니 다.bpftrace 는 시스템 전역 추적 을 할 수 있 고 용기 밖에서 추적 을 완성 할 수 있어 서 더욱 편리 합 니 다.
메모리 분 배 는 주로 skb 와 mmap 시스템 을 통 해 호출 되 며,bpftrace 로 이 두 시스템 호출 을 추적 합 니 다.
#!/usr/bin/bpftrace
tracepoint:syscalls:sys_enter_mmap / comm == "mysqld" /
{
printf("%d %s addr=%ld len=%ld flags=%ld
", pid, probe, args->addr, args->len, args->flags);
/* printf("%s
", ustack(perf, 10)); */
}
tracepoint:syscalls:sys_enter_brk / comm == "mysqld" /
{
printf("%d %s brk %d
", pid, probe, args->brk);
}
sudo ./mysql-oom.bt
Attaching 2 probes...
57950 tracepoint:syscalls:sys_enter_brk brk 0
57950 tracepoint:syscalls:sys_enter_mmap addr=0 len=8740 flags=2
...
...
57950 tracepoint:syscalls:sys_enter_brk brk 1699086336
57950 tracepoint:syscalls:sys_enter_mmap addr=0 len=17179869184 flags=34
마지막 으로
mmap
한 번 에 16G 메모 리 를 분배 한 후에 죽 임 을 볼 수 있다.호출 스 택(ustack)을 가 져 오 려 고 시 도 했 지만 유용 한 정 보 를 가 져 오지 못 했 습 니 다.my sql 이 컴 파일 되 지 않 았 을 때 frame pointer 를 열지 않 았 을 수도 있 습 니 다.
97694 tracepoint:syscalls:sys_enter_mmap addr=0 len=12288 flags=34
7f84c662730a 0x7f84c662730a ([unknown])
97694 tracepoint:syscalls:sys_enter_mmap addr=0 len=17179869184 flags=34
7f84c4c4064a 0x7f84c4c4064a ([unknown])
스 택 을 가 져 올 수 없습니다.모든 시스템 호출 을 추적 해 보십시오.
#!/usr/bin/bpftrace
tracepoint:syscalls:sys_enter_* / comm == "mysqld" /
{
printf("%d %s
", pid, probe);
}
...
출력:
Attaching 331 probes...
...
115490 tracepoint:syscalls:sys_enter_close
115490 tracepoint:syscalls:sys_enter_brk
115490 tracepoint:syscalls:sys_enter_newstat
115490 tracepoint:syscalls:sys_enter_getrlimit
115490 tracepoint:syscalls:sys_enter_mmap addr=0 len=17179869184 flags=34
마지막
mmap
전에 호출 된getrlimit
을 볼 수 있 습 니 다.my sql 은 시스템 자원 제한 에 따라 메모 리 를 분배 할 것 으로 추 정 됩 니 다.MySQL 소스 코드 분석
MySQL 소스 코드 에서 직접 호출
getrlimit
하 는 곳 이 많 지 않 습 니 다.ndb,innodb 를 제외 합 니 다.memcached,libevent 이후 한 곳 만 직접 호출:static uint set_max_open_files(uint max_file_limit)
{
struct rlimit rlimit;
uint old_cur;
DBUG_ENTER("set_max_open_files");
DBUG_PRINT("enter",("files: %u", max_file_limit));
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
{
old_cur= (uint) rlimit.rlim_cur;
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
(uint) rlimit.rlim_cur,
(uint) rlimit.rlim_max));
if (rlimit.rlim_cur == (rlim_t) RLIM_INFINITY)
rlimit.rlim_cur = max_file_limit;
if (rlimit.rlim_cur >= max_file_limit)
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
if (setrlimit(RLIMIT_NOFILE, &rlimit))
max_file_limit= old_cur; /* Use original value */
else
{
rlimit.rlim_cur= 0; /* Safety if next call fails */
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
if (rlimit.rlim_cur) /* If call didn't fail */
max_file_limit= (uint) rlimit.rlim_cur;
}
}
DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
DBUG_RETURN(max_file_limit);
그 중에서 논 리 는 시스템 의 파일 열기 제한 이
RLIM_INFINITY
이거 나 설정 할max_file_limit
보다 크 면 시스템 의 제한 을 되 돌려 주 는 것 이다.이 함수 도 한 번 만 호출 됩 니 다:
uint my_set_max_open_files(uint files)
{
struct st_my_file_info *tmp;
DBUG_ENTER("my_set_max_open_files");
DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
files+= MY_FILE_MIN;
files= set_max_open_files(MY_MIN(files, OS_FILE_LIMIT)); //
if (files <= MY_NFILE)
DBUG_RETURN(files);
//
if (!(tmp= (struct st_my_file_info*) my_malloc(key_memory_my_file_info,
sizeof(*tmp) * files,
MYF(MY_WME))))
DBUG_RETURN(MY_NFILE);
//
/* Copy any initialized files */
memcpy((char*) tmp, (char*) my_file_info,
sizeof(*tmp) * MY_MIN(my_file_limit, files));
memset((tmp + my_file_limit), 0,
MY_MAX((int) (files - my_file_limit), 0) * sizeof(*tmp));
my_free_open_file_info(); /* Free if already allocated */
my_file_info= tmp;
my_file_limit= files;
DBUG_PRINT("exit",("files: %u", files));
DBUG_RETURN(files);
}
원래 MySQL 은 최대 열 수 있 는 파일 수 에 따라 미리 모든 파일 에 메모 리 를 할당 하고 초기 화 합 니 다.이 럴 때 너무 많은 메모 리 를 할당 하여 OOM 을 초래 할 수 있 습 니 다.
해결 하 다.
시작 전 ulimit 설정
K8s 는 현재 ulimit 설정 을 지원 하지 않 기 때문에 많은 Helm Chart 가 시작 하기 전에 ulimit 를 설정 합 니 다.
command: ["sh","-c", "ulimit -n 4096 && exec /usr/local/bin/docker-entrypoint.sh mysqld"]
K3s 설정 수정
K3s 는 systemd 를 통 해 시작 합 니 다.k3s.service 를 수정 하여 K3s 가 파일 을 여 는 수 를 제한 할 수 있 습 니 다.이 제한 은 containerd 에 전 달 됩 니 다.
LimitNOFILE=1048576
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.