著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

このチュートリアルでは、systemdを使用して、再起動またはクラッシュ後に自動的に再起動するようにMySQLを構成します。

これは、2部構成のシリーズの後半です。 パート1は、initデーモンやランレベルなどの一般的なLinuxサービス管理の概念をカバーしています。 最後に、systemdでのサービス管理のデモンストレーションを行います。 ここでは、targetswantsrequires、およびunitファイルを調べます。 このパート、パート2は、MySQLデータベースを使用した実際の例を提供します。

注:systemctlを使用してsystemdサービスとユニットを制御するための非常に人気のあるチュートリアルを読むことも検討してください

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • CentOS 8を実行しているサーバーで、sudo権限を持つroot以外のユーザーが含まれます。 ファイアウォールを含め、これらすべてを設定するには、CentOS 8 を実行するDigitalOceanDropletを作成してから、初期サーバーセットアップガイドに従います。

  • MySQLがインストールされています。 詳細な手順については、チュートリアル CentOS8にMySQLをインストールする方法に従ってください。

systemdを使用して起動後に自動起動するようにMySQLを構成する

MySQLがインストールされている状態で、サービスのステータスを確認します。

  1. sudo systemctl status mysqld.service

出力には、サービスが実行中であることが示されているはずですが、デーモンは無効になっています。

Output
mysqld.service - MySQL 8.0 database server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2020-12-24 23:48:56 UTC; 1h 6min ago Process: 30423 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS) Process: 30294 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS) Process: 30270 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS) Main PID: 30378 (mysqld) Status: "Server is operational" Tasks: 40 (limit: 4763) ...

サービスが有効になっている場合は、無効にします。 変更を加える前に、まず無効な動作を調べたいと思います。

  1. sudo systemctl disable mysqld.service

次に、次のコマンドを実行して、MySQLがmulti-user.targetに必要かどうかを確認します。

  1. sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql

何も返されません。 次に、シンボリックリンクが存在するかどうかを確認します。

  1. sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*

シンボリックリンクファイルが存在しないことを示すメッセージが表示されます。

Output
ls: cannot access '/etc/systemd/system/multi-user.target.wants/mysql*': No such file or directory

ここで、必要に応じて、サーバーを再起動し、MySQLサービスを確認します。 実行されていない必要があります。

再起動したかどうかに関係なく、MySQLサービスを再度有効にします。

  1. sudo systemctl enable mysqld.service

今回は、システムは/etc/systemd/system/multi-user.target.wants/の下にシンボリックリンクを作成します。

Output
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.

lsコマンドを再度実行して、これを確認します。

  1. sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*

次のような出力が表示されます。

Output
lrwxrwxrwx 1 root root 38 Aug 1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service

systemdサービスを有効または無効にすると、デフォルトのターゲットのwantsディレクトリからシンボリックリンクが作成または削除されます。

必要に応じて、ドロップレットを再度再起動し、オンラインに戻ったら、ps -efコマンドを実行してサービスステータスを確認します。

  1. ps -ef | grep mysql

次のコマンドは、MySQLが実行されている場合、MySQLに関する情報を提供します。

[secondary_label Output]\
mysql        851       1  2 04:26 ?        00:00:02 /usr/libexec/mysqld --basedir=/usr

これで、再起動後に再起動するようにMySQLを構成できました。 次に、クラッシュについて説明します。

systemdを使用したクラッシュ後に自動起動するようにMySQLを構成する

最新のアプリケーションであるMySQLは、クラッシュ後に自動起動するように構成されています。 それを無効にする方法を見てみましょう。

MySQLサービスユニットファイルをエディタで開きます。

  1. sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service

ヘッダー情報の後、ファイルの内容は次のようになります。

/etc/systemd/system/multi-user.target.wants/mysqld.service

[Unit]

Description=MySQL 8.0 database server
After=syslog.target
After=network.target

[Service]

Type=notify
User=mysql
Group=mysql

ExecStartPre=/usr/libexec/mysql-check-socke
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
`# Note: we set --basedir to prevent probes that might trigger SELinux alarms,`
`# per bug #547485`
ExecStart=/usr/libexec/mysqld --basedir=/usr
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop

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

TimeoutSec=300

`# Place temp files in a secure directory, not /tmp`

PrivateTmp=true

Restart=on-failure

RestartPreventExitStatus=1

`# Sets open_files_limit`

LimitNOFILE = 10000

`# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.`

Environment=MYSQLD_PARENT_PID=1

[Install]

WantedBy=multi-user.target

ご覧のとおり、Restartパラメーターの値はon-failureに設定されています。 これは、MySQLサービスがクリーンでない終了コードまたはタイムアウトのために再起動することを意味します。

systemd servicemanページには、再起動パラメータの次の表が表示されます。

設定を再開/原因を終了 いいえ いつも 成功 失敗時 オン-異常 中絶 オンウォッチドッグ
終了コードまたはシグナルをクリーンアップします X X
汚れた終了コード X X
汚れた信号 X X X X
タイムアウト X X X
ウォッチドッグ X X X X

systemdサービスユニットファイルでは、RestartRestartSecの2つのパラメーターがクラッシュ動作を制御します。 最初のパラメーターはサービスをいつ再起動するかを指定し、2番目のパラメーターはサービスを再起動するまでの待機時間を定義します。

クラッシュ動作をテストするには、kill-9シグナルでMySQLプロセスを停止します。 この場合、メインPIDは851です。 PIDを独自のものに置き換えます。

ps -ef | grep mysql

  1. sudo kill -9 851

数秒待ってから、ステータスを確認します。

  1. sudo systemctl status mysqld.service

出力には、MySQLが新しいPID(この場合は新しいプロセスIDは1513)で再起動したことが示されます。

Output
mysqld.service - MySQL 8.0 database server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2020-12-25 04:47:48 UTC; 55s ago Process: 1420 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS) Process: 1559 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS) Process: 1476 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)Process: 1451 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS) Main PID: 1513 (mysqld) Status: "Server is operational" ...

次に、ユニットファイルを再度開きます。

  1. sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service

MySQLデーモンのユニットファイルでRestartディレクティブをコメントアウトして保存します。 これにより、再起動動作が無効になります。

/etc/systemd/system/multi-user.target.wants/mysqld.service

`# Restart=on-failure`

この後、systemdデーモンをリロードしてから、mysqldサービスを再起動します。

  1. sudo systemctl daemon-reload
  2. sudo systemctl restart mysqld.service

次のコマンドを実行すると、サービスのメインPIDを見つけることができます。

  1. sudo systemctl status mysqld.service
Output
. . . Main PID: 1895 (mysqld)

kill -9コマンドを使用して、ご使用の環境でMySQL PIDのメインPIDを強制終了します(テスト環境でPIDを使用しています)。

sudo kill -9 1895

MySQLのステータスを確認します。

  1. sudo systemctl status mysqld.service

サービスが失敗したことが表示されます。

Output
mysqld.service - MySQL 8.0 database server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled) Active: **failed** (Result: signal) since Fri 2020-12-25 05:07:22 UTC; 1min 14s ago Process: 1976 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS) Process: 1940 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS) Process: 1895 ExecStart=/usr/libexec/mysqld --basedir=/usr (code=killed, signal=KILL) Process: 1858 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS Process: 1833 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS) Main PID: 1895 (code=**killed**, signal=KILL) ...

サービスステータスを数回見つけてみてください。 サービスがfailedと表示されるたび。

そのため、サービスが停止して戻ってこないクラッシュをエミュレートしました。 これは、汚れた停止後にサービスを再起動しないようにsystemdに指示したためです。 mysqld.serviceユニットファイルを編集してRestartパラメータのコメントを解除し、それを保存し、systemctlデーモンをリロードし、最後にサービスを再起動すると、通常の機能が復元されます。

これは、クラッシュ後に自動開始するようにネイティブsystemdサービスを構成する方法です。 サービスユニットファイルの[Service]セクションの下に、Restart(およびオプションでRestartSec)のディレクティブを追加するだけです。

結論

この2部構成のシリーズでは、Linuxエコシステム全体で使用されるサービス管理デーモンについて学習しました。 次に、systemdの基本を調べ、それらの基本を実際の例に適用しました。再起動またはクラッシュ後に再起動するようにデータベースを構成します。 systemdについて詳しく知りたい場合は、systemctlの使用に関する包括的なチュートリアルを検討してください。