Criando um script systemd para o Sybase ASE

4

Estou tentando configurar nossa instalação do Sybase para ser executada no systemd.

Os comandos básicos são abordados aqui mas quando a controlamos manualmente, iniciamos com o seguinte comando (o startserver sai depois de executar os scripts RUN_SYBASE)

su - sybase
cd sqlserver/install
startserver -f RUN_SYBASE_localhost_back
startserver -f RUN_SYBASE_localhost

Podemos ver detalhes dos processos iniciados

[sybase@localhost install]$ showserver 
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
0 S sybase   14072 14068  7  80   0 - 157888 futex_ 18:41 ?       00:11:26 /opt/sap/ASE-16_0/bin/dataserver -d/opt/sap/data/master.dat -e/opt/sap/ASE-16_0/install/SYBASE_localhost.log -c/opt/sap/ASE-16_0/SYBASE_localhost.cfg -M/opt/sap/ASE-16_0 -N/opt/sap/ASE-16_0/sysam/SYBASE_localhost.properties -i/opt/sap -sSYBASE_localhost
0 S sybase   14066 14063  0  80   0 -  6521 poll_s 18:41 ?        00:00:00 /opt/sap/ASE-16_0/bin/backupserver -e/opt/sap/ASE-16_0/install/SYBASE_localhost_back.log -N25 -C20 -I/opt/sap/interfaces -M/opt/sap/ASE-16_0/bin/sybmultbuf -SSYBASE_localhost_back

E para desligar o sybase precisamos executar um comando no próprio sybase

[sybase@localhost ~]$  isql -Usa -Ppassword -SSYBASE_localhost << EOF_INPUT
shutdown SYB_BACKUP with nowait
go
shutdown
go
EOF_INPUT

Backup Server: 3.48.1.1: The Backup Server will go down immediately. 
Terminating sessions.
Server SHUTDOWN by request.
ASE is terminating this process.
CT-LIBRARY error:
        ct_results(): network packet layer: internal net library error: Net-Library operation terminated due to disconnect
[sybase@localhost ~]$ echo $?  # yes the error was expected
0

Isto é o que eu tenho para um script até agora, o su e source ~/SYBASE.sh é porque isso é usado pelo bashrc mas O systemd não roda o bashrc . O / opt / sap / stop_sybase_command é simplesmente a string de várias linhas digitada no sybase para desligar o servidor.

[Unit]
Description=Sybase ASE Server 16.0

[Service]
ExecStart=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost_back; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost"
ExecStop=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"
WorkingDirectory=/opt/sap/ASE-16_0/install/

[Install]
WantedBy=multi-user.target

Usando o systemctl start o sybase.service é executado corretamente e cria o servidor, mas acaba alegando que ele falhou, acredito que os comandos do startserver saiam após o início do sybase

Active: failed (Result: exit-code) since Tue 2015-08-25 21:52:43 EDT; 11s ago

Eu tentei usar Type=forking , mas isso fez com que ele falhasse até mais cedo.

[root@localhost ~]# systemctl start sybase.service 
Job for sybase.service failed. See 'systemctl status sybase.service' and 'journalctl -xn' for details.

Mas de qualquer forma ele inicia, mas parar não funciona, se eu tentar o comando stop como root ele funciona bem

[root@localhost ~]# /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"
Backup Server: 3.48.1.1: The Backup Server will go down immediately. 
Terminating sessions.
Server SHUTDOWN by request.
ASE is terminating this process.
CT-LIBRARY error:
        ct_results(): network packet layer: internal net library error: Net-Library operation terminated due to disconnect
[root@localhost ~]# 

Mas quando eu tento parar de usar systemctl, tudo o que vejo na parte de status do log é o comando aparentemente com falha

  Process: 20961 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)

E quanto ao log em si, a única coisa impressa em resposta ao comando stop é a seguinte

Aug 25 21:59:48 localhost.localdomain systemd[1]: Stopped Sybase ASE Server 16.0.

Estou tentando corrigir três problemas com esse script.

  1. Emita um comando de início sem o systemd pensar que ele falhou
  2. Emita um comando de parada que realmente pare o sybase
  3. O status fornece feedback sobre se os processos mostrados por showserver estão sendo executados

obrigado

ATUALIZAÇÃO: Seguindo o conselho do meuh, eu usei o seguinte script que parece fazer o que eu preciso

[Unit]
Description=Sybase ASE Server 16.0

[Service]
# Systemd executes a single command with su -c which ignores the bashrc setting our environment, instead su to sybase and run the SYBASE.sh directly

# Could strictly be two services but we'll be lazy and just do one. After starting the backup and main server we find the pid of the main server and drop it into a PID file
ExecStart=/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost_back; /opt/sap/ASE-16_0/bin/startserver -f /opt/sap/sqlserver/install/RUN_SYBASE_localhost; showserver | sed '2q;d'| awk '{ print $4 }' > /opt/sap/sqlserver/install/sybase.pid"

# Shutting down we actually have to issue the command from inside sybase
ExecStop=/bin/sh -c '/bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Ppassword -SSYBASE_localhost < /opt/sap/stop_sybase_command"'

# The startserver commands exits so we need to track the fork, listed in sybase.pid
Type=forking
PIDFile=/opt/sap/sqlserver/install/sybase.pid
WorkingDirectory=/opt/sap/ASE-16_0/install/

[Install]
WantedBy=multi-user.target

Respondendo à pergunta de mueh, o processo parece estar incluído no grupo de controle, mas quando eu o mato manualmente, o processo é removido.

[root@localhost ~]# systemctl status sybase.service |head -7
sybase.service - Sybase ASE Server 16.0
   Loaded: loaded (/etc/systemd/system/sybase.service; enabled)
   Active: active (running) since Wed 2015-09-02 02:41:40 EDT; 23s ago
  Process: 23384 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Pscadacom -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)
 Main PID: 23431 (backupserver)
   CGroup: /system.slice/sybase.service
           ��� 23431 /opt/sap/ASE-16_0/bin/backupserver -e/opt/sap/ASE-16_0/install/SYBASE_localhost_back.log -N25 -C20 -I/opt/sap/interfaces -M/opt/sap/ASE-16_0/bin/sybmultbuf -SSYBASE_localhost_back
[root@localhost ~]# kill 23431
[root@localhost ~]# systemctl status sybase.service |head -7
sybase.service - Sybase ASE Server 16.0
   Loaded: loaded (/etc/systemd/system/sybase.service; enabled)
   Active: active (running) since Wed 2015-09-02 02:41:40 EDT; 1min 56s ago
  Process: 23384 ExecStop=/bin/sh -c /bin/su sybase -c "source ~/SYBASE.sh; /opt/sap/client/bin/isql -Usa -Pscadacom -SSYBASE_localhost < /opt/sap/stop_sybase_command" (code=exited, status=255)
 Main PID: 23431
   CGroup: /system.slice/sybase.service

[root@localhost ~]# 

Sim, e eu não tenho certeza de quais são os caracteres, é apenas uma coisa estranha que aparece em todo lugar quando eu estou ssh'd na VM (eu suponho que é uma coisa de codificação inofensiva )

    
por Aaron Luchko 26.08.2015 / 18:37

3 respostas

1

Tente adicionar à entrada [Service] a PIDFile= o nome de um arquivo no qual você deve colocar o ID do processo do seu servidor de dados. Edite sua linha ExecStart para obter este pid de alguma forma, por exemplo, do comando showserver . Tal arquivo já pode ser criado pela Sybase. Você provavelmente precisará usar Type=forking novamente.

Assegure-se de que o código de saída dos seus scripts Exec seja 0 se funcionarem, mas o systemd diz que não, por exemplo, adicionando exit 0 no final.

Talvez o seu processo esteja deixando o grupo de controle de alguma forma. Eu usei o seguinte como um serviço de teste: em /etc/systemd/system/myscript.service

[Unit]
Description=Try Forking using PIDFile
After=syslog.target
[Service]
Type=Forking
PIDFile=/tmp/mypid
ExecStart=/bin/bash -c '( (nohup sleep 99999 & echo $! >/tmp/mypid )& sleep 5 )'
ExecStop=/bin/bash -c 'kill -1 $(</tmp/mypid); >/tmp/mypid; exit 0'
[Install]
WantedBy=multi-user.target

Eu comecei isso com

$ sudo systemctl daemon-reload
$ sudo systemctl enable myscript
$ sudo systemctl start myscript
$ sudo systemctl status myscript;echo $?
   Loaded: loaded (/etc/systemd/system/myscript.service; enabled)
   Active: active (running) since  09:01:33 CEST; 2s ago
 Main PID: 25485 (bash)
   CGroup: /system.slice/myscript.service
       |-25485 /bin/bash -c ( (nohup sleep 99999 & echo $! >/tmp/mypid )&...
       |-25486 /bin/bash -c ( (nohup sleep 99999 & echo $! >/tmp/mypid )&...
       |-25488 sleep 5
       '-25489 sleep 99999

Após 5 segundos, o status mostra apenas a suspensão em andamento. Seu pid está em /tmp/mypid .

$ sudo systemctl status myscript;echo $?
   Active: active (running) since  09:01:33 CEST; 11s ago
 Main PID: 25489 (sleep)
   CGroup: /system.slice/myscript.service
       '-25489 sleep 99999

Uma parada funciona, como mostra o status:

$ sudo systemctl stop myscript;echo $?
0
$ sudo systemctl status myscript;echo $?
   Active: inactive (dead) since  09:01:55 CEST; 4s ago
  Process: 25504 ExecStop=/bin/bash -c kill ...
  Process: 25489 ExecStart=/bin/bash -c ( (nohup sleep ...
 Main PID: 25489 (code=killed, signal=TERM)
3

Começar de novo e matar o sono com a mão faz aviso prévio a morte do processo imediatamente e ele executa o ExecStop e remove o arquivo /tmp/mypid sem precisar parar:

$ sudo systemctl start myscript
$ sudo kill -15 $(</tmp/mypid) # pid 25529
$ ps -p $(</tmp/mypid)
   bash: /tmp/mypid: No such file or directory
$ sudo systemctl status myscript;echo $?
   Active: inactive (dead) since  09:03:53 CEST; 9s ago
  Process: 25568 ExecStop=/bin/bash -c kill
  Process: 25529 ExecStart=/bin/bash -c ( (nohup sleep
 Main PID: 25529 (code=killed, signal=TERM)
   09:02:38 systemd[1]: Started Try Forking using PIDFile.
   09:03:53 bash[25568]: /bin/bash: line 0: kill: (25529) - No suc...ss
3
$ sudo systemctl disable myscript;echo $?
    
por 29.08.2015 / 13:35
2

Isso é o que eu fiz. Nenhum arquivo de bifurcação ou pid é necessário e pode ser executado como usuário do sybase. O ExecStop não é necessário se você estiver satisfeito com o dataserver parado com um comando kill.

arquivo da unidade ... / etc / systemd / system / sybase-srvnane

Adicione um arquivo de unidade separado para cada servidor sybase.

[Unit]
Description=Sybase dataserver

[Service]
User=sybase
ExecStart=/home/sybase/bin/run-dataserver SRVNAME
ExecStop=/home/sybase/bin/stop-dataserver SRVNAME

[Install]
WantedBy=multi-user.target

script de início ... / home / sybase / bin / run-dataserver

#!/bin/sh

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_run_file=${SYBROOT}/${SYBASE_ASE}/install/RUN_${_server}
if [ -x ${_run_file} ]
then
        echo "Starting Sybase server ... ${_server}"
        . ${_run_file}
else
        echo "Cannot find run file ${_run_server}"
        exit 1
fi

interrompe o script ... / home / sybase / bin / stop-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
then
        echo "Stopping Sybase server .... ${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$( cat /home/sybase/.sa_password )
shutdown
go
EOF

fi

Para completar, também paro para um servidor de backup ... / home / sybase / bin / start-backup-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "Usage: $0 <SYB_SERVER>" && exit 1
_server=${1}
. /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
if [ -x ${_isql} ]
then
        echo "Stopping Sybase backup server .... ${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$( cat /home/sybase/.sa_password )
shutdown SYB_BACKUP
go
EOF

fi

Eu tenho um arquivo somente para leitura /home/sybase/.sa_password para a senha.

sudo systemctl daemon-reload e está pronto.

    
por 03.11.2016 / 00:24
0

Em vez de usar su para usuário, você pode usar a tecla User= para definir o usuário no arquivo de unidade

    
por 01.09.2015 / 18:45

Tags