为 Sybase ASE 创建 systemd 脚本

为 Sybase ASE 创建 systemd 脚本

我一直在尝试将 Sybase 安装设置为在 systemd 下运行。

这里涵盖了基本命令但是当我们手动控制它时,我们使用以下命令启动它(startserver 在运行 RUN_SYBASE 脚本后退出)

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

我们可以看到启动进程的详细信息

[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

要关闭 sybase,我们需要在 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

这就是我到目前为止的脚本, su ,source ~/SYBASE.sh是因为它被 bashrc 使用,但是systemd 不运行 bashrc。 /opt/sap/stop_sybase_command 只是输入到 sybase 中以关闭服务器的多行字符串。

[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

使用 systemctl start sybase.service 执行正常并创建服务器,但最终声称它失败,我相信是因为 startserver 命令在启动 sybase 后退出

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

我尝试使用Type=forking相反的方法,但这使它认为它更早失败了。

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

但无论哪种方式,它都会启动但停止根本不起作用,如果我以 root 身份尝试停止命令,它会正常工作

[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 ~]# 

但是当我尝试停止使用 systemctl 时,我在日志的状态部分中看到的只是该命令显然失败了

  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)

至于日志本身,响应停止命令打印的唯一内容如下

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

我正在尝试解决此脚本的三个问题。

  1. 发出启动命令,systemd 不会认为它失败
  2. 发出实际停止 sybase 的 stop 命令
  3. 让状态提供关于显示的进程是否showserver正在运行的反馈

谢谢

更新:按照 meuh 的建议,我使用了以下脚本,它似乎可以满足我的需要

[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

回答 mueh 的问题,该进程似乎包含在对照组中,但当我手动终止它时,该进程就被删除了。

[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 ~]# 

是的,我不确定 ��� 字符来自什么,当我通过 ssh 进入虚拟机时,它只是到处弹出一些奇怪的东西(我认为这是一种无害的编码)

答案1

这就是我所做的。不需要 fork 或 pid 文件,并且可以作为 sybase 用户运行。如果您对使用 Kill 命令停止数据服务器感到满意,则不需要 ExecStop。

单元文件... /etc/systemd/system/sybase-srvnane

为每个 sybase 服务器添加单独的单元文件。

[单元]
描述=Sybase 数据服务器

[服务]
用户=sybase
ExecStart=/home/sybase/bin/run-dataserver SRVNAME
ExecStop=/home/sybase/bin/stop-dataserver SRVNAME

[安装]
WantedBy=多用户.target

启动脚本... /home/sybase/bin/run-dataserver

#!/bin/sh

[ $# -ne 1 ] && echo "用法:$0 <SYB_SERVER>" && 退出 1
_服务器=${1}
。 /opt/sybase/SYBASE.sh
_run_file=${SYBROOT}/${SYBASE_ASE}/install/RUN_${_server}
如果 [ -x ${_run_file} ]
然后
        echo "正在启动Sybase服务器...${_server}"
        。 ${_run_file}
别的
        echo "找不到运行文件 ${_run_server}"
        1号出口

停止脚本... /home/sybase/bin/stop-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "用法:$0 <SYB_SERVER>" && 退出 1
_服务器=${1}
。 /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
如果 [ -x ${_isql} ]
然后
        echo“正在停止 Sybase 服务器...${_server}”
        ${_isql} -U sa -S ${_server} << EOF
$( 猫 /home/sybase/.sa_password )
关闭
EOF

为了完整起见,我还停止了备份服务器... /home/sybase/bin/start-backup-dataserver

#!/bin/bash

[ $# -ne 1 ] && echo "用法:$0 <SYB_SERVER>" && 退出 1
_服务器=${1}
。 /opt/sybase/SYBASE.sh
_isql=${SYBROOT}/${SYBASE_OCS}/bin/isql
如果 [ -x ${_isql} ]
然后
        echo "正在停止 Sybase 备份服务器...${_server}"
        ${_isql} -U sa -S ${_server} << EOF
$( 猫 /home/sybase/.sa_password )
关闭 SYB_BACKUP
EOF

我有一个用户只读文件 /home/sybase/.sa_password 作为密码。

sudo systemctl daemon-reload你就完成了。

答案2

尝试添加一个带有文件名的条目,您应该在其中放置数据服务器的进程 ID [Service]PIDFile=编辑你的ExecStart行以某种方式获取这个 pid,例如从showserver命令中。 Sybase 可能已创建此类文件。您可能需要Type=forking再次使用。

确保 Exec 脚本的退出代码为 0(如果它们可以工作但 systemd 说它们不可以),例如通过exit 0在末尾添加。


也许你的进程以某种方式离开了对照组。我使用以下作为测试服务:/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

我开始这个

$ 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

5 秒后,状态仅显示睡眠运行。它的 pid 位于/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

停止工作,如状态所示:

$ 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

重新启动并手动终止睡眠使 systemd 立即注意到进程死亡,并运行 ExecStop 并删除文件,/tmp/mypid而无需停止:

$ 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 $?

答案3

su您可以使用User=密钥在单元文件中设置用户,而不是用于用户

答案4

许多感谢那些年前为此工作的人们。我将您的最佳建议与我自己的一些工作融合在一起,并在以下方面取得了成功。

[Unit]
Description=Sybase ASE Server 16.0
After=network.target

[Service]
Environment=PW=sapassword DS=SERVERNAME
WorkingDirectory=/opt/sap/ASE-16_0/install/
Type=forking

ExecStart=/sbin/runuser sybase -c ". ../../SYBASE.sh; startserver -f RUN_${DS} -f RUN_${DS}_back"
ExecStop= /sbin/runuser sybase -c ". ../../SYBASE.sh; printf 'shutdown\ngo' | isql -Usa -P$PW -S$DS"
    
[Install]
WantedBy=multi-user.target

我喜欢将所有内容都放在一个文件中的简单性,并且它解决了一些问题。

  • 使用/sbin/runuser而不是使用/bin/su将所有进程保留在单个控制组中。这使得该服务的行为与其他服务一样。也就是说,systemctl status sybase.service表明服务正在运行,当您发出 时systemctl stop sybase.service,除了运行我们的正常关闭之外,它还会向 backupserver 发送一个 TERM。 runuser可能只对那些使用 SELinux 的人来说是必要的,但它对我来说意义重大。显然 runuser 就是为了这种情况而创建的,即 root 切换到较低特权的用户。
  • 只需编辑一行Environment=即可使该文件在我们的任何服务器上运行。
  • 将密码放入环境中可以防止有人运行时显示密码systemctl status sybase.server。实际文件只能由 root 读取。
  • After=network.target确保备份服务器在启动时启动
  • systemd 没有对 PIDfile 做任何有用的事情,所以我很乐意将其省略。

相关内容