systemd를 사용하여 종료 시 Postgresql ExecStop 명령을 실행하고 싶습니다.

systemd를 사용하여 종료 시 Postgresql ExecStop 명령을 실행하고 싶습니다.

Postgresql시작 시 지속적으로 실행되는 스크립트 세트가 있습니다 . 데이터베이스가 닫히기 전에 특수 스크립트를 실행하여 이러한 스크립트를 중지하고 완료될 때까지 기다리도록 파일 ExecStop의 명령을 수정했습니다 . .service모두 작동합니다.

그러나 어제 IT 부서에서 서버를 종료하고 ExecStop명령이 실행되지 않았습니다. 스크립트에 혼란스러운 결과가 있고 특정 스크립트가 출력을 파일에 기록하는데 해당 파일이 어제 업데이트되지 않았기 때문에 이 사실을 알고 있습니다.

참고: 방금 루트 사용자의 기록을 확인했는데 IT가 도망친 것 같습니다.

shutdown -h now

이것은 systemctl 설정을 우회합니까?

.service시스템이 종료될 때 실행 되도록 파일에 무언가를 추가 할 수 있습니까 ExecStop? 아니면 특별한 종료 관련 서비스를 만들어야 합니까?

기존 Postgresql 서비스를 복제하는 특수 서비스를 생성하고 싶지 않기 때문에 이것이 "systemd를 사용하여 종료하기 전에 스크립트를 실행하는 방법"과 중복되지 않는다고 생각합니다.

내 특정 스크립트가 실행되는 동안 로그 파일에 추가되기 때문에 실행되고 있지 않다고 확신하며 해당 로그 파일은 "systemctl stop my-service-name"을 마지막으로 실행했을 때 약 일주일 전에 마지막으로 추가되었습니다. 제공하다' .

서비스 파일은 다음과 같습니다.

[Unit]
Description=PostgreSQL 9.3 main database server
After=syslog.target
After=network.target

[Service]
Type=forking

User=postgres
Group=postgres

# Location of database directory
Environment=PGDATA=/db_tier1/main/

ExecStartPre=/usr/pgsql-9.3/bin/postgresql93-check-db-dir ${PGDATA} ; /bin/rm -f /db_tier2/PGSERVICE-PROD-ABORT
ExecStart=/usr/pgsql-9.3/bin/pg_ctl start -D ${PGDATA} -s -w -t 300
ExecStop=/bin/sh /var/lib/pgsql/bin/PROD/run_db_pre_stop.sh ${PGDATA} ; /usr/pgsql-9.3/bin/pg_ctl stop -D ${PGDATA} -s -m fast
ExecReload=/usr/pgsql-9.3/bin/pg_ctl reload -D ${PGDATA} -s

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=600

[Install]
WantedBy=multi-user.target

답변1

systemd는 종료 중에 중지된 모든 서비스를 실행하므로 ExecStop=스크립트가처형되고 있습니다.

일반적인 문제는 서비스 단위(이 경우 postgresql.service)에 모든 종속성이 올바르게 설정되어 있지 않다는 것입니다. 이 경우 다른 종료 프로세스(예: 네트워크 종료 또는 파일 시스템 마운트 해제)가 스크립트와 동시에 발생할 수 있습니다.

ExecStop=스크립트가 완료될 때 까지 이러한 항목이 충분히 오래 지속되도록 하려면 After=서비스의 종속성에 이를 나열해야 합니다. (종료 순서는 시작 순서와 반대이므로 서비스가 중지됩니다.앞으로이러한 종속성의 중단. ) 예를 들어 After=network.target중지 스크립트에서 네트워킹을 설정해야 하는 경우 .

루트 디렉토리가 아닌 파일 시스템에 쓰려면 다음을 사용하십시오.RequiresMountsFor=수술 중에도 사용할 수 있도록 합니다.

로그가 있고 영구 저장소(가능하다고 생각함)가 있는 경우 해당 내용을 보고 ExecStop=스크립트가 언급되어 있는지 또는 스크립트를 실행하는 동안 발생한 일부 오류가 있는지 확인할 수 있습니다.

예를 들어 다음 명령은 다음과 같습니다.

$ journalctl -u postgresql -b -1

postgresql.service이는 머신의 마지막 부팅( 현재 부팅 전의 부팅을 의미)의 모든 로그를 나열합니다 -b -1(서비스 장치의 정확한 이름이라고 가정). 따라서 부팅 시 시작하고 종료 시 중지하는 것으로 표시되어야 합니다. 이것이 문제 해결에 도움이 되기를 바랍니다.

답변2

서비스 시작 시 systemd전용대조군( cgroup약어 ) 각 서비스에 대해. 비슷한 명령을 실행하면 ps ax -O cgroup:150 | grep system.slice각 서비스에 할당된 cgroup을 볼 수 있지만 목록은 상당히 광범위합니다.

postgresql를 사용하지 않고 중지했다가 다시 시작하면 systemctl(예: 을 사용하여 pg_ctl) 다시 시작된 프로세스는 더 이상 해당 서비스에 대해 생성된 제어 그룹의 구성원 postgresql이 아닙니다 . systemd이에 따라 systemd현재 서비스가 종료된 것으로 간주됩니다.

ExecStop=종료될 때 종료되는 것으로 알려진 서비스에 대해 작업을 실행하는 것은 쓸모가 없으므로 systemd건너뛸 것입니다.

systemctl명령을 배우고 싶지 않은 데이터베이스 관리자, postgresql필요할 때 전통적인 방식으로 중지하고 시작하는 별도의 관리 도구 또는 일부 데이터베이스 작업 반영의 일부로 숙련된 Pavlov가 있는 경우 postgresql.service단위를 다음으로 변경하는 것을 고려할 수 있습니다. :

Type=oneshot
RemainAfterExit=true

이렇게 하면 PostgreSQL 데이터베이스 엔진의 실제 상태 모니터링이 중지되지만 종료 시 작업 systemd에 영향을 주지 않고 기존 방식으로 데이터베이스 엔진을 중지하고 다시 시작할 수 있습니다 ExecStop=.

관련 정보