【入門・初心者向け】AnsibleでMariaDB(MySQL)をインストールして起動するところまで
こちらの続きです。
簡単なプレイブックを作成して、実行するところまでやってみました。
今回はもう少し実践寄りで、MariaDBをインストールして起動するところまでの最低限を、Ansibleを使ってやってみます。
ロール(Role)を利用する
前回は dev.yml
にタスクを記述していましたが、例えば今後、データベース、Webサーバー、OSの構成管理など様々なタスクが増えたときに、1つのファイルにすべてのタスクを記述すると、見通しが悪く、管理が煩雑になってしまいます。
そこでAnsibleのロールという仕組みを利用して、設定する内容別にプレイブックを分割します。
まず以下のようにディレクトリ・ファイルを作成します。
$ mkdir -p roles/mariadb/tasks $ touch roles/mariadb/tasks/main.yml
このように roles
ディレクトリの下に、それぞれの設定内容別にディレクトリを分け、さらにその下に必要なプレイブックを作成していくような形になります。
今回は roles/
の下に tasks/
しか作りませんが、設定する内容が増えてくると、 defaults/
や templates/
、 files/
などのディレクトリが増えていきます。
tasks/
にはタスクを記述したyamlファイルを置くことになり、 main.yml
が固定で読み込まれるようになっているため、必ず配置するようにしましょう。
ロールを作成したら、そのロールを利用するために dev.yml
に次のように記述します。
- hosts: dev become: true roles: - mariadb
roles
というディレクティブを使用して、作成した mariadb
ロールを参照しています。
これで roles/mariadb/tasks/main.yml
に記述したタスクが実行されるようになります。
なお、 become: true
とすることで、特権ユーザー(sudo)でタスク実行を行うようになります。
Become (Privilege Escalation) — Ansible Documentation
では、実際にタスクを記述していきましょう。
リポジトリの追加
まずは、MariaDB公式のリポジトリを追加します(Amazon Linux 2を想定)。
roles/mariadb/tasks/main.yml
に以下のように記述します。
--- - name: Add repository yum_repository: name: MariaDB description: MariaDB repo baseurl: http://yum.mariadb.org/10.3/rhel7-amd64 gpgkey: https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck: true
このタスクはyum_repositoryモジュールを使用して、/etc/yum.repos.d/
配下にリポジトリ定義ファイル MariaDB.repo
を追加するといったものになります。
このようにAnsibleでは、目的の設定を行うために、用意された数多くのモジュールを使用してタスクを記述していくことになります。
大抵のものはモジュールとして提供されていますので、Ansibleの公式ドキュメントを参照し、モジュールを適切に活用して、タスクを記述していきます。
さて、記述が終わったら実行すれば良いわけですが、その前にできるだけチェックを行うべきです。
チェックするコマンドは主に以下のようなものがあります。
# シンタックスチェック。構文エラーがあればその内容を出力する。 $ ansible-playbook -i inventory/dev --connection=local dev.yml --syntax-check # タスク一覧チェック。実行予定のタスク一覧を表示する。 $ ansible-playbook -i inventory/dev --connection=local dev.yml --list-tasks # 実行時変更点チェック。実行したときの変更点を表示する。いわゆるDry Run。--check忘れに注意。 $ ansible-playbook -i inventory/dev --connection=local dev.yml --diff --check
特に三番目の --diff --check
を使った実行時変更点のチェックは行った方が良いでしょう。
ただ、注意して欲しいのは --check
をつけ忘れるとタスク実行になってしまうということです。
--diff
は変更内容の差分を表示するためだけのオプションのため、Dry Runにはなりません。
--diff --check
を実行すると、以下のように差分が表示されます。
(省略)... TASK [mariadb : Add repository] --- before: /etc/yum.repos.d/MariaDB.repo +++ after: /etc/yum.repos.d/MariaDB.repo @@ -0,0 +1,6 @@ +[MariaDB] +baseurl = http://yum.mariadb.org/10.3/rhel7-amd64 +gpgcheck = 1 +gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB +name = MariaDB repo + ...(省略)
変更点が事前に確認できたら実行します。
$ ansible-playbook -i inventory/dev --connection=local dev.yml --diff
うまくいけば /etc/yum.repos.d/MariaDB.repo
が作成されているはずです。
$ cat /etc/yum.repos.d/MariaDB.repo [MariaDB] baseurl = http://yum.mariadb.org/10.3/rhel7-amd64 gpgcheck = 1 gpgkey = https://yum.mariadb.org/RPM-GPG-KEY-MariaDB name = MariaDB repo
MariaDBのインストールから起動まで
まだリポジトリを追加しただけです。
MariaDBのインストールから起動までのタスクを記述してしまいます。
--- - name: Add repository yum_repository: name: MariaDB description: MariaDB repo baseurl: http://yum.mariadb.org/10.3/rhel7-amd64 gpgkey: https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck: true # MariaDBのインストール - name: Install MariaDB server yum: name: MariaDB-server state: present # 起動および自動起動設定 - name: Start MariaDB service systemd: name: mariadb state: started enabled: yes
インストールはyumモジュール、起動は systemdモジュールを使用しています。
記述できたら、実行前チェックで差分を確認し、実行します。
$ ansible-playbook -i inventory/dev --connection=local dev.yml --diff --check $ ansible-playbook -i inventory/dev --connection=local dev.yml --diff
完了すると systemctl status mysql
でactiveになっていることが確認でき、 mysql -uroot
でログインもできるかと思います。
無事、MariaDBを起動するところまでできましたが、実際に利用するにはこれではまだ不十分です。
rootはデフォルトのままですし、ユーザーの作成もしていなければ、設定ファイルも準備できていません。
次はこの辺りのタスクを記述する必要がありそうです。
POSTリクエストを飛ばすとXML形式のレスポンスを返してくれるAPIダミーサーバーをNginxで立てる
こんなケースがあるかどうかわかりませんが、たまたま必要になったので構築ログを書いておきます。
EC2(Amazon Linux 2)を使います。
Nginxのインストールから起動まで
# amazon-linux-extras install nginx1.12 -y # systemctl start nginx # systemctl enable nginx
インスタンスのIPにアクセスすればNginxのウェルカムページが表示されます。
セキュリティグループでポートを開いているか注意しましょう。
レスポンス用のXMLファイルを作成する
# cd /usr/share/nginx/html/ # touch foo.xml
foo.xml
の中身を適当に作ります。
<?xml version="1.0" encoding="UTF-8" ?> <foo> Dummy Foo. </foo>
ブラウザから http://xxx.xxx.xxx.xxx/foo.xml
にアクセスするか、curl叩いてレスポンスを確かめます。
$ curl -X GET 'http://xxx.xxx.xxx.xxx/foo.xml'
XMLファイルの中身が返ってきたらOKです。
POSTリクエストでもレスポンスが返るようにする
さて、今回はGETではなくPOSTリクエストでレスポンスが返ってくるようにしたいわけです。
ところが、このままだとステータス405が返ってきてしまいます。
$ curl -X POST 'http://xxx.xxx.xxx.xxx/foo.xml' <html> <head><title>405 Not Allowed</title></head> <body bgcolor="white"> <center><h1>405 Not Allowed</h1></center> <hr><center>nginx/1.12.2</center> </body> </html>
Nginxは静的コンテンツに対するPOSTリクエストを許可していないのですね。
さて、どうするか。
結論から書くと、今回は以下のような対応をしました。
# /etc/nginx/nginx.conf # ... server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # 以下の1行を追加 error_page 405 =200 $uri; } # ...
405を問答無用で200にしてしまうって感じですね。
ちゃんとやろうと思うとこの対応はよろしくないです。
本当は405として処理したいはずのエラーもすべて200になってしまうからです。
ですが、今回はちょっとした動作確認のために取り急ぎ用意したかっただけだったので、このような対応で大丈夫と判断しました。
ということで、Nginxを再起動して、もう一度POSTリクエストを送ってみましょう。
ちゃんとXML形式のレスポンスが返ってきたら完了です。
【MySQL入門】mysqldumpをほんの少し理解する
本記事はMySQL5.6を想定しており、他のバージョンの場合ではオプション使用時の動作が異なる可能性があります。
MySQLのバックアップ方法としてよく目にするのがmysqldumpを使ったバックアップです。
例えば全データベースのバックアップを取りたい場合は、以下のようになります。
$ mysqldump -uroot --all-databases > dump.sql
確かにこれでもバックアップを取ることは可能です。ですが、いくつかの問題も抱えています。
mysqldumpのメリットとデメリットを踏まえた上で、それらの問題を回避できるよう利用することが大切です。
mysqldumpのメリットとデメリット
mysqldumpによるバックアップは「論理バックアップ」です。
mysqldumpの出力はCREATEやINSERTなどのSQLが記述されたテキストデータになります。
そのため、内容の判別が可能で、sedコマンドなどを用いて修正することもできます。
反面、リストア時のINSERTの実行に時間がかかるというデメリットがあります。
また、MySQLサーバーを停止する必要がない(「オンラインバックアップ」や「ホットバックアップ」と呼ばれます)ことは大きなメリットですが、それはつまりmysqldump実行中もデータベースを更新されてしまう可能性があるということです。
このことを考慮しなければ、整合性の崩れたダンプファイルとなってしまうかもしれません。
整合性を保ったバックアップを取るために
整合性を保ったバックアップを取るためには、テーブルをロックして更新されることを防ぐ必要があります。
実はmysqldumpはデフォルトで --lock-tables
オプションが有効になっており、各データベースに対して個別にテーブルをロックするようになっています。
正確には --opt
という、いくつかのオプションをまとめたオプションがデフォルトで有効になっており、そのまとめられたオプションの中の1つに --lock-tables
が含まれている形です。
では、それで十分かというとそうではありません。
--lock-tables
は複数のデータベース内にあるテーブルを同時にロックできないため、データベースが異なるテーブルのダンプは整合性が崩れる場合があります。
これに対し、 --lock-all-tables
オプションを使うことで、MySQLサーバー全体にロックをかけられるため、複数のデータベース内にあるテーブルでも整合性を保つことができます。
ロックの問題点と対応策
ロックをかければ整合性を保つことはできますが、別の問題が出てきます。
それは、mysqldump実行中に更新処理ができなくなってしまうということです。
これは、サービスによっては、mysqldump実行中のサービス利用が不可能になることを意味します。
この問題への対応策の1つは --single-transaction
というオプションを使うことです。
ダンプ開始時のスナップショットをとり、そこからデータを取得するため、ロックをかけずにダンプを実行できます。
ただし、このオプションが使用できるのはストレージエンジンがInnoDBの場合です。
MyISAMを使用している場合はこのオプションは無効であるため --lock-all-tables
によるロックが必要になります。
基本的にはデフォルトでInnoDBが有効になっていると思います。
テーブルごとにどのストレージエンジンが使われているかを確認する方法は以下を参照してください。
MySQLストレージエンジンの確認方法 - Tomcky's blog
"リストア"だけでなく"リカバリ"も意識したバックアップ
さて、ダンプしたファイルを使えば以下のようにしてリストアすることが可能です。
$ mysql -uroot < dump.sql
しかしこれでは、バックアップを取得した時点までしかデータを戻すことができません。
バックアップを取得してから障害が発生するまでの間のデータを復旧するには、リストアするだけでは不十分です。
このような場合、一般的にはバイナリログをリストア後に適用して障害発生直前の状態までリカバリします(ロールフォワードリカバリと言います)。
ただし、バイナリログには全ての更新情報が記録されているため、バックアップ時点のバイナリログの位置がわからなければ、どこからの更新情報を適用すれば良いか判断ができません。
そこで、 --master-data=2
というオプションを付与することで、mysqldump実行時のバイナリログ位置情報をダンプファイルに含めます。
本来はスレーブサーバー設定時に使用するダンプファイルを作成するときに付与するオプションになります。
ここではリカバリ方法は説明しませんが、このオプションを付与しておけば、いざリカバリしようと思ったときにバイナリログの正確な適用ができずに困った、という状況は避けられるはずです。
また、 --flush-logs
オプションを使用するのも有効です。
このオプションを付与することでダンプ実行時にバイナリログのローテーションが行われ、適用すべき開始位置が新しいログファイルの先頭からになるため、ロールフォワードリカバリの作業が単純になります。
--flush-logs
使用時に気をつけないといけないのは、複数のデータベースをダンプする場合、データベースの数と同じ回数だけローテーションが行われてしまうことです。
これを回避するには、 --lock-all-tables
か --master-data
、または --single-transaction
を、一緒に利用します。
まとめ
ここまでの内容を踏まえたmysqldumpが以下になります。
InnoDBの場合
$ mysqldump -uroot --all-databases --single-transaction --flush-logs --master-data=2 > dump.sql
MyISAMの場合
$ mysqldump -uroot --all-databases --lock-all-tables --flush-logs --master-data=2 > dump.sql
これで、最初のコマンドよりはしっかりとバックアップを取れるようになったはずです。
なお、MySQL5.1.8以降だと --events
オプションを付与しないとWarningが表示されます。
$ mysqldump -uroot --all-databases --single-transaction --flush-logs --master-data=2 --events > dump.sql
これでバッチリですね(長かった。。。)
エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド
- 作者: 奥野幹也
- 出版社/メーカー: 技術評論社
- 発売日: 2010/06/12
- メディア: 大型本
- 購入: 16人 クリック: 204回
- この商品を含むブログ (35件) を見る
Webエンジニアのための データベース技術[実践]入門 (Software Design plus)
- 作者: 松信嘉範
- 出版社/メーカー: 技術評論社
- 発売日: 2012/03/09
- メディア: 単行本(ソフトカバー)
- 購入: 20人 クリック: 486回
- この商品を含むブログを見る