MySQL이 systemd를 통해 시작되면 중단됩니다...

mysqld: 형님, 일어날 수가 없어요...

작성자: 프로젝트 요구 사항 및 유지 관리를 담당하는 ACOSEN R&D 센터 엔지니어 Ben Shaohua. 다른 정체성: 코기 삽질꾼.

Aikeson 오픈 소스 커뮤니티에서 제작되었습니다. 원본 콘텐츠는 승인 없이 사용할 수 없습니다. 편집자에게 연락하여 재인쇄할 출처를 명시해 주세요.

이 글은 약 2,100단어 분량으로, 읽는 데 7분 정도 소요될 것으로 예상됩니다.

소개

제목에서 알 수 있듯이 자동화된 테스트 시나리오에서는 systemd를 통해 MySQL을 시작할 수 없습니다 .

kill -9인스턴스 프로세스를 계속 종료하고 종료 후 mysqld가 올바르게 풀업되는지 확인합니다.

구체적인 정보는 다음과 같습니다.

  1. 호스트 정보: CentOS 8(Docker 컨테이너)
  2. systemd를 사용하여 mysqld 프로세스 관리
  3. systemd 서비스 의 작동 모드 는 다음과 같습니다 .
  4. 시작 명령은 다음과 같습니다.
# systemd 启动命令
sudo -S systemctl start mysqld_11690.service

# systemd service 内的 ExecStart 启动命令
/opt/mysql/base/8.0.34/bin/mysqld --defaults-file=/opt/mysql/etc/11690/my.cnf --daemonize --pid-file=/opt/mysql/data/11690/mysqld.pid --user=actiontech-mysql --socket=/opt/mysql/data/11690/mysqld.sock --port=11690

징후

여러 번 시도한 후에도 시작 명령이 성공하지 않고 반환되지 않고 계속 중단됩니다.

아래 그림은 재생 시나리오를 보여줍니다. 서비스 포트 번호가 일치하지 않으면 무시하십시오.

MySQL 오류 로그에는 정보가 없습니다. systemd 서비스 상태를 확인 하고 MAIN PID매개변수 부족으로 인해 시작 스크립트가 실행되지 않았는지 확인하세요 .

systemd 의 최종 정보 출력은 다음과 같습니다.New main PID 31036 does not exist or is a zombie

이유 요약

systemd가 mysqld를 시작 하면 먼저 서비스 템플릿 의 구성에 따라 실행 됩니다.

  1. ExecStart( mysqld 시작 )
  2. mysqld가pid 파일 생성을 시작합니다.
  3. ExecStartPost(일부 사용자 정의된 사후 스크립트: 권한 조정, cgrouppid 에 쓰기 등)

2-3단계 의 중간 상태 에서 , 즉 pid파일이 방금 생성되었을 때 호스트는 자동화된 테스트에서 실행된 명령을 받습니다 sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid).

pid파일과 pid프로세스가 존재하므로( kill명령어나 명령이 존재하지 않으면 cat오류가 보고됨) 자동화된 CASE는 kill작업이 성공적으로 종료된 것으로 간주합니다. 그러나 mysqld.pid이 파일은 MySQL 자체에서 유지 관리되므로 systemd 관점에서 보면 시작이 성공한 것으로 간주되기 전에 3단계가 완료될 때 까지 기다려야 합니다 .

systemd가 분기 모드를 사용하는 경우 PID하위 프로세스의 값을 기반으로 서비스가 성공적으로 시작되었는지 여부를 결정합니다.

하위 프로세스가 성공적으로 시작되고 예기치 않은 종료가 발생하지 않으면 systemd는 서비스가 시작된 것으로 간주하고 하위 프로세스의 PID값을 로 설정합니다 MAIN PID.

하위 프로세스가 시작되지 않거나 예기치 않게 종료되면 systemd는 서비스가 성공적으로 시작되지 못한 것으로 간주합니다.

결론적으로

ExecStartPost 실행 시 하위 프로세스 ID 31036이 삭제 되었기 때문에 kill후처리에 shell시작 매개변수가 부족하지만 ExecStart 단계가 완료되어 MAIN PID 31036이 systemd 에만 존재하는 좀비 프로세스 가 됩니다 .

문제 해결 프로세스

이 문제가 발생했을 때 저는 약간 혼란스러워서 단순히 메모리와 디스크의 기본 정보만 확인했습니다. 기대에 부응했고 자원도 부족하지 않았습니다.

먼저 MySQL의 오류 로그를 살펴보고 무엇을 발견했는지 살펴보겠습니다. 다음과 같이 결과를 봅니다.

...无关内容省略...
2024-02-05T05:08:42.538326+08:00 0 [Warning] [MY-010539] [Repl] Recovery from source pos 3943309 and file mysql-bin.000001 for channel ''. Previous relay log pos and relay log file had been set to 4, /opt/mysql/log/relaylog/11690/mysql-relay.000004 respectively.
2024-02-05T05:08:42.548513+08:00 0 [System] [MY-010931] [Server] /opt/mysql/base/8.0.34/bin/mysqld: ready for connections. Version: '8.0.34'  socket: '/opt/mysql/data/11690/mysqld.sock'  port: 11690  MySQL Community Server - GPL.
2024-02-05T05:08:42.548633+08:00 0 [System] [MY-013292] [Server] Admin interface ready for connections, address: '127.0.0.1'  port: 6114
2024-02-05T05:08:42.548620+08:00 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5

에러 로그를 관찰한 결과, 시작 시간 이후에는 로그 정보가 출력되지 않아 유용한 정보가 없음을 확인했습니다.

systemctl status를 확인하여 서비스의 현재 상태를 확인하세요.

아래 그림은 일반적인 상황에서의 상태 정보를 보여줍니다 .

비교 후 두 가지 유용한 정보가 수집되었습니다.

  1. shell매개변수 부족으로 인해 사후 실행이 실패했습니다 -p( -p매개변수는 MAIN PID, 즉 포크 하위 프로세스가 시작된 후입니다 PID).
  2. systemd를 얻을 수 없거나 PID 31036존재하지 않거나 좀비 프로세스입니다.

먼저 프로세스를 확인 ID하고 mysqld.pid다음을 살펴보겠습니다.

확인 단서:

  1. PID 31036존재하지 않는다
  2. mysqld.pid파일이 존재하며 파일 내용은 31036입니다.
  3. top좀비 프로세스가 없는지 확인하는 명령

원인을 확인하기 위해 더 많은 단서를 확보해야 합니다. journalctl -u내용을 확인하여 도움이 되는지 확인하세요.

sh-4.4# journalctl -u mysqld_11690.service
-- Logs begin at Mon 2024-02-05 04:00:35 CST, end at Mon 2024-02-05 17:08:01 CST. --
Feb 05 05:07:54 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:07:56 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:32 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:36 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:39 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:42 udp-11 u_set_iops.sh[31507]: /etc/systemd/system/mysqld_11690.service.d/u_set_iops.sh: option requires an argument -- p
Feb 05 05:08:42 udp-11 systemd[1]: mysqld_11690.service: New main PID 31036 does not exist or is a zombie.

여기의 내용은 journalctl -u현상에 대해서만 설명하고 구체적인 이유를 분석할 수는 없습니다. systemctl status 의 내용과 유사하며 별로 도움이 되지 않습니다.

/var/log/messages시스템 로그 내용을 봅니다 .

루프에서 일부 메모리 오류 정보를 보고한 것으로 나타났습니다. 검색 결과 해당 오류는 하드웨어 문제일 수 있는 것으로 나타났습니다. 자동화된 테스트에서 동료들에게 질문한 후 저는 다음과 같은 결론에 도달했습니다.

  1. 이 시나리오는 간헐적으로 발생하는 문제입니다. 유스케이스는 4번 실행되어 2번 성공하고 2번 실패했습니다.
  2. 각 실행은 동일한 호스트와 동일한 컨테이너 이미지에서 이루어집니다.
  3. 실패하면 Hang이 존재하는 컨테이너는 동일합니다.

성공적인 실행 결과가 있으므로 여기서는 하드웨어 문제를 무시합니다.

이제 컨테이너가 언급되었으므로 cgroup이 호스트에 매핑되는지 여부를 생각할 때 문제가 있습니까 ? 위에서 확인한 systemctl 상태 에서 cgroup 에 매핑된 호스트 디렉터리는 다음과 같습니다 .CGroup: /docker/3a72b2cdc7bd9beb1c7b2abec24763046604602a38f0fcb7406d17f5d33353d2/system.slice/mysqld_11690.service

상위 폴더의 읽기 및 쓰기 권한을 확인하여 system.slice이상이 없는지 확인하세요. 먼저, cgroup 매핑 문제를 일시적으로 제거합니다( 동일한 cgroup을 사용하는 호스트에서 systemd 가 인계받는 다른 서비스가 있기 때문입니다 ).

pstack 에서 systemctl start 에 대해 systemd가 구체적으로 중단되는 위치를 확인할 수 있는지 시도해 볼 계획입니다 .3048143pid

sh-4.4# pstack 3048143
#0  0x00007fdfaef33ade in ppoll () from /lib64/libc.so.6
#1  0x00007fdfaf7768ee in bus_poll () from /usr/lib/systemd/libsystemd-shared-239.so
#2  0x00007fdfaf6a8f3d in bus_wait_for_jobs () from /usr/lib/systemd/libsystemd-shared-239.so
#3  0x000055b4c2d59b2e in start_unit ()
#4  0x00007fdfaf7457e3 in dispatch_verb () from /usr/lib/systemd/libsystemd-shared-239.so
#5  0x000055b4c2d4c2b4 in main ()

관찰 결과 start_unit 이 의심스러운 것으로 나타났습니다. 이 함수는 시스템 장치를start_unit() 시작하는 데 사용되지만 이는 도움이 되지 않습니다.

기존 단서를 바탕으로 다음과 같이 추측할 수 있습니다.

  1. mysqld.pid파일이 존재한다면 이전에 시작된 프로세스 번호를 가진 mysqld 프로세스가 실제로 존재했다는 의미입니다 .31036
  2. 프로세스가 시작된 후에는 자동화된 사용 사례 kill -9에 의해 종료됩니다 .
  3. systemd는 이미 종료되었으며 MAIN PID사후 실행이 실패했으며 포크 프로세스가 실패했습니다.

시스템 시작 프로세스의 단계를 분류함으로써 가능성을 추측할 수 있습니다. MySQL 인스턴스는 mysqld가 성공적으로 시작된 후에만 파일을 생성하므로 mysqld.pid후속 단계에서 kill -9실수로 종료되어 발생할 수 있습니다.

재생산 방법

다른 단서나 단서가 없기 때문에 추론된 결론을 바탕으로 재현해 볼 예정이다.

4.1 systemd mysql 서비스 템플릿 조정

mysqld가 시작된 지 몇 초 /etc/systemd/system/mysqld_11690.service후에 템플릿 파일을 편집하여 이 기간 내에 인스턴스 프로세스를 종료하는 시나리오를 시뮬레이션할 수 있습니다.sleep10

4.2 구성 다시 로드

실행 systemctl daemon-reload명령이 변경되어 적용됩니다.

4.3 장면 재현

  1. [ssh 세션 A] 먼저 새 컨테이너를 준비하고 관련 구성을 수행한 후 실행하여 mysqldsudo -S systemctl start mysqld_11690.service 프로세스를 시작합니다 . 이때 여러 가지 이유로 인해 세션이 중단됩니다.sleep
  2. [ssh 세션 B] 다른 세션 창에서 start명령어 hang이 살아있는 동안 mysqld.pid파일을 확인하고, 파일이 생성되면 바로 실행해 보세요 sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid).
  3. 이때 systemctl 상태를 관찰하면 성능은 예상과 일치합니다.

해결책

먼저 kill정지된 systemctl start 명령을 제거하고 실행하십시오 systemctl stop mysqld_11690.service. 이렇게 하면 systemd가 좀비 프로세스를 적극적으로 종료 stop할 수 있지만 이는 오류에 영향을 미치지 않습니다.

stop실행이 완료될 때 까지 기다린 후 start명령을 사용하여 다시 시작하고 정상으로 돌아갑니다.

더 많은 기술 기사를 보려면 https://opensource.actionsky.com/을 방문하세요.

SQLE 소개

SQLE는 개발부터 프로덕션 환경까지 SQL 감사 및 관리를 포괄하는 포괄적인 SQL 품질 관리 플랫폼입니다. 주류 오픈소스, 상용 및 국내 데이터베이스를 지원하고 개발, 운영 및 유지 관리를 위한 프로세스 자동화 기능을 제공하고 온라인 효율성을 향상시키며 데이터 품질을 향상시킵니다.

SQLE 가져오기

유형 주소
저장소 https://github.com/actiontech/sqle
문서 https://actiontech.github.io/sqle-docs/
출시 소식 https://github.com/actiontech/sqle/releases
데이터 감사 플러그인 개발 문서 https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
고등학생들이 성인식으로 자신만의 오픈소스 프로그래밍 언어를 만든다 - 네티즌들의 날카로운 논평: 애플은 방어에 의존해 만연한 사기로 인해 국내 서비스가 중단됐다 . 앞으로는 윈도 플랫폼 타오바오(taobao.com)에서 독립 게임을 제작할 계획이다. 웹 버전 최적화 작업을 다시 시작해 프로그래머들의 종착지, 비주얼 스튜디오 코드 1.89에서 가장 많이 쓰이는 자바 LTS 버전인 자바 17이 출시되고, 윈도 10에는 시장 점유율 70%, Windows 11은 계속해서 하락
{{o.이름}}
{{이름}}

추천

출처my.oschina.net/actiontechoss/blog/11105637