- 投稿日:2020-08-03T23:57:18+09:00
『失敗から学ぶRDBの正しい歩き方』を読んでいく(後編)
前編は こちら
概要
11. 見られないエラーログ
アンチパターン
- エラーログの軽視と無知。
- 大きな問題を未然に防ぐチャンスを自ら潰している。
- エラーログの運用設計をシステムの設計時に行っていない。
- エラーログの吐き出し過ぎ。
- 担当者が見なくなる大きな要因の一つ。
エラーログ出力の設計
運用ログとして欲しい情報。
- いつ(タイムスタンプ)
- だれが(ユーザー)
- どこに(データベース)
監査ログとして欲しい情報。
- どこから(クライアントのIPなど)
- 何をしたか(実行されたSQLコマンド)
- どうなったか(エラーコード、エラーメッセージ)
エラーログの監視
PostgreSQLの場合
- 重要な通知を知るべきすべての人に素早く・正しく・漏れなく通知できること
- Slackへの通知にはサーバ監視サービスのMackerelやサーバ監視ツールのZabbixなどを使い、「PANIC」などの文字列が出力された場合にアラートとして扱う仕組みが一般的。
深刻度 本番環境でのロギング 通知 DEBUG1~DEBUG5 場合による(デバッグで必要などの理由がなければ本番では行わず、ステージングのみで行う) しない INFO 場合による(統計情報で取得できない場合など他で代替できないときのみ) しない NOTICE する しない WARNING する しない ERROR する Slackの、エラー対応のためのチャンネル(errorチャンネルなど)に通知 FATAL する Slackの主要チャンネル(generalなど)に通知( @channel
付き)PANIC する Slackの主要チャンネル(generalなど)に通知( @channel
付き)まとめ
- エラーログの種類について知り、適切な設計・運用を行う。
ログを見やすくする工夫
Elastic Stackを活用する
- ログの集計結果をHTMLやCLI上でわかりやすく表示してくれるため、私達を大いに助けてくれるツール。
- Logstashでログを集約、Elasticsearchで集計、Kibanaで可視化。
PostgreSQLの場合
- PANICになってからでは、障害が発生しているため対応しとしては出遅れているので、ログレベルLOGのエラーログを集計して事前に問題を検知し、より早い初動で対応する。
MySQLの場合
- Error, Waring, Note のうち、 Note 以外を監視する。
- Elastic Stackの活用やホワイトリスト形式の文字列監視も良いプラクティス。
12. 監視されないデータベース
アンチパターン
- RDBMS、ミドルウェアの監視(モニタリング)をする文化が存在しない。
ミドルウェアの監視の種類
1. サービス(プロセス)の死活監視
- 「いち早く障害発生を確認できるようにする」ために必要な監視。
2. 特定条件のチェック監視
- 「特定の条件を設けて、障害を未然に防いだり、復旧にいち早く取り掛かれたりするようにする」ために必要な監視。
- 例)ディスク容量が90%になるとアラートが飛ぶ。
3. 時系列データをもとにしたメトリックス監視
- 「状況の変化を時系列で管理することで、キャパシティプランニングや障害の予兆の把握に役立てる」ために必要な監視。
モニタリングの対象と実践
- メトリックを見て、シナリオを考えることが大切。
OS側
- ディスクI/O
- ネットワークトラフィック
- CPU利用率
- メモリ利用率
RDBMS側
- SELECT/INSERT/UPDATE/DELETEなどのSQLの実行量
- 実際に読み込まれているレコードの量
- インデックスヒット率
- デッドロックの可否
- テンポラリファイルの作成の有無
- ロックの量と時間
MySQLのモニタリングツール
PMP
- ZabbixやCactiのプラグインとして公開されており、手軽に使うことができる。
- MySQLの項目をかなり細かく取ることができる。
PostgreSQLのモニタリングツール
pg_monz
- Zabbixのプラグインとして使うことができる。
まとめ
- モニタリングを続け、育てることが大切。
- モニタリングはインフラの見える化。
- プログラミングに対するテストコードと同じ。
- パフォーマンスのモニタリングを、インフラエンジニアとアプリケーションエンジニアが一緒に、1~2週間に1回は行うようにする。
- モニタリング後のチューニングが大事
- プログラミングに対するリファクタリングと同じ。
12-2. ミドルウェアの監視の種類
コラム 可視化と改善は両輪
13. 知らないロック
アンチパターン
- 意図せずロックがかかり問題が発生する。
- ロックの粒度や性質を知らない。
- DBの負荷同様にロックをモニタリングの対象にしていない。
ロックの基本
デッドロック
- 「複数のトランザクションが、もう一方の処理が終わるのをお互い待って身動きが取れなくなっている状態」
- デッドロックが発生しないように、ロックでは取得の順番が大切。
MySQLのギャップロック
- 対象が存在しなくてもロックを取る
- 「INDEX値を持つ行」と「INDEX値を持つ行」の間にあるギャップ
- 先頭の「INDEX値を持つ行」の前に存在するギャップ
- 末尾の「INDEX値を持つ行」の後に存在するギャップ
MySQLのネクストキーロック
- 対象よりも1つ先の行までロックを取る。
明示的ロック
- 自ら宣言して取得するロック。
- 例)外部キー制約を利用した状態で子テーブルに対する更新を行った場合は親テーブルがわに共有ロックを取得する。
まとめ
- RDBMSごとのロックの振る舞いを知っておく。
- 時にはクリティカルなバグをうみ、最悪サービスが停止することもある。
- ロックの振る舞いについてはドキュメントを読み、手を実際に動かし、正しい知識を身につける。
14. ロックの功罪
トランザクション分離レベル
15. 簡単過ぎる不整合
15.2 非正規化の誘惑
コラム 非正規化と履歴データの違い
16. キャッシュ中毒
キャッシュについて知る
17. 複雑なクエリ
17-2. 複雑なクエリの発端
18. ノーチェンジ・コンフィグ
18-2. コンフィグを知る
19. 塩漬けのバージョン
19-2. なぜバージョンアップは重要なのか
20. フレームワーク依存症
20-2. フレームワークが生むメリットとデメリット
- 投稿日:2020-08-03T20:20:12+09:00
【Laravel】MySQL設定メモ
- 投稿日:2020-08-03T18:48:26+09:00
FuelPHPにおいてtimestampで範囲を指定して取得するとき注意点
概要
created_at
やupdated_at
などに使われるtimestamp
型は非常に便利で、不等号で簡単に比較ができるのですが、気を付けないとうまく動いてくれません。すごく基本的なことですが、場合によっては適当に書いても正常に動いてしまうことがあるので意外と気づきにくい部分だと思います。本題
デフォルトの
unixtime
で扱っている場合
e.g.)1596447140
など
はそのまま使えて、unixtime.php$query = \DB::select() ->from('table_name') ->where('created_at', '>', strtotime('-1 week')) ->execute();のように書くだけで比較ができます。この場合は1週間前よりあとに作られたレコードだけ取得します。
一方、違うフォーマットで扱っている場合
e.g.)2020-08-03 18:32:20
など
は注意が必要で、フォーマットも合わせてあげる必要があります。例の場合は、anyformat.php$query = \DB::select() ->from('table_name') ->where('created_at', '>', date('Y-m-d h:i:s', strtotime('-1 week'))) ->execute();と書くと同様の動きをしてくれます。
まとめ
しっかり使えば非常に便利なtimestamp。一つのサービスで使うtimestampのフォーマットは合わせた方が良いですね。
余談ですが、'Y-m-d h:i:s'
と書くべきところを'Y-m-s h:i:s'
と書いていて、更新するたびに取得されるレコードが違うということになったりもしました。さすがに気づきましたけど(30分ほど苦戦して上司に聞いて)。
- 投稿日:2020-08-03T13:24:34+09:00
AmazonRDSで外部接続できるMysql環境構築
AmasonRDSにMysql環境を構築(無料利用枠)してみました。
あと、はまった内容も載せています。こんな人にはいいかも?
・自分のパソコンにインストールしたくない。
・パソコンが壊れた場合、リカバリ作業をしたくない。
・別のパソコンと共有したい。
・お金を使いたくない。
・大容量じゃなくても大丈夫。
・一時的(1年以内)な利用で大丈夫。忙しい方は、以下の項をどうぞ。
・3.セキュリティグループの作成
・7.パラメータグループの作成
・9.再度データベースの作成参考
手順
1.データベースの作成
「Amazon RDS」→「データベース」→「データベースの作成」
2.データベースの作成
「ステータス」が「利用可能」になるまで待ちます・・。5~10分位だった気がします。3.セキュリティグループの作成
「amazon EC2」→「セキュリティグループ」
「セキュリティグループの作成」を選択
「セキュリティグループ名」「説明」を入力。(何でもよい)
「インバウンドルール」に「ルールを追加」で、ポートを「3306」、アクセス許可するIPアドレスを指定します。
4.セキュリティグループの適用
対象のデータベースを選択して、「変更」
5.接続確認
・「ホスト名」は、エンドポイント
・ユーザID、パスワードは「1.データベースの作成」より。エンドポイント
「amazonRDS」→「データベース」→作成したデータベースのリンクをクリック
パスワードを忘れた場合
上記の「4.セキュリティグループの適用」の手順を行い、
「セキュリティグループ」ではなく、「新しいマスターパスワード」を設定してください。
接続できなければ、再度、1~4の手順をやり直してみてください。。6.Mysqlの設定(大文字・小文字区別)
テーブルを作成して、クエリを実行してみる。
select COUNT(*) from USER_MSTこんなエラーが表示される。。
#42S02Table 'xxxxxx.USER_MST' doesn't exist「USER_MST」というテーブルが無い・・・?
A5SQLを見てもあるんだけど・・。
テーブル名を小文字にすると、問題無し。。
select COUNT(*) from user_mst
原因は、「大文字・小文字」の区別が有効になっているからの模様。
以下、公式より。
9.2.2 識別子の大文字と小文字の区別7.パラメータグループの作成
通常であれば「my.cnf (linux) / my.ini (windows) 」の値を書き換えればよいのですが、
amazonRDSの場合は、「パラメータグループ」の書き換えになります。
「パラメータグループの作成」
「パラメータグループファミリー」→「mysql8.0」
「グループ名」「説明」に入力(なんでもよい)最後に「作成」
「lower_case_table_names」で絞り込んで、パラメータの値を「1」にする。
最後の「変更の保存」8.DBパラメータグループの適用
上記「4.セキュリティグループの適用」の手順を行い、
「セキュリティグループ」ではなく、「DBパラメータグループ」を作成した内容に変更。
で、ここではまる。。。
「すぐに適用」、「DBインスタンスの変更」をしようとすると・・・The parameter value for lower_case_table_names can't be changed for MySQL 8.0 DB instancesググってヒットした記事↓
Amazon RDS における MySQL の既知の問題と制限「Amazon RDS DB インスタンスに使用する MySQL のパラメータの例外」の項を読んでも問題なさそうだけど・・。
再起動してみよう!
変更を破棄して、「停止」→「再起動」
Can only reboot db instances with state in: available, storage-optimization, incompatible-credentials, incompatible-parameters. Instance database has state: stopping「停止」後、起動できなくなる。。。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-incompatible-parameters/
https://qiita.com/matsumoto_sp/items/4808576159c92f8916f5「リセット」かサポート問い合わせ・・?
めんどくさそう。。9.再度データベースの作成
データベースを最初から作りました。
※Mysqlのバージョンがたまたま悪かったのかと思い、「8.0.20」にしています。
赤枠がデフォルトからの変更点です。※「3.セキュリティグループの作成」「7.パラメータグループの作成 」で
既に「セキュリティグループ」と「パラメータグループ」を作成済みなので、他に操作は必要ありません。10.再度クエリの実行
うまくいった!
- 投稿日:2020-08-03T01:07:47+09:00
dockerでMySQLのサンプルデータベースのSakilaを使用した環境をすぐ使用できるように設定してみた
私はdocker初心者です。間違いやもっと良い方法があれば教えていただけるとありがたいです。
SakilaとはMySQLが公式で用意しているサンプルデータベースです。
https://dev.mysql.com/doc/sakila/en/
こちらからダウンロードできます
https://dev.mysql.com/doc/index-other.html
DVDレンタル情報が保存されているデータベースで、個人的にはMySQLのデータを使って試したいときに使うというのが便利だと思います。
それをdockerでちょちょっと環境が作成できるようにやってみました。
参考
Dockerfile
作成mysqlの公式イメージを使って
Dockerfile
を設定してみましたDockerfileFROM mysql:8 ENV MYSQL_ROOT_PASSWORD=root RUN apt-get update \ && apt-get install -y wget unzip \ && wget http://downloads.mysql.com/docs/sakila-db.zip \ && unzip sakila-db.zip \ # docker-entrypoint-initdb.d/ の .sql ファイルが自動でアルファベット順に実行されるので、リネームしつつ移動 && mv sakila-db/sakila-schema.sql /docker-entrypoint-initdb.d/01_sakila-schema.sql \ && mv sakila-db/sakila-data.sql /docker-entrypoint-initdb.d/02_sakila-data.sql
Dockerfile
をビルドしてコンテナ作成$ docker build -t sample . (省略) $ docker run --name sakila -d sample (省略) $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a599ee328437 sample "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp sakilamysqlに接続し
show tables;
を実行$ docker container exec -it sakila mysql -uroot -proot -Dsakila mysql: [Warning] Using a password on the command line interface can be insecure. Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 8.0.21 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show tables; +----------------------------+ | Tables_in_sakila | +----------------------------+ | actor | | actor_info | | address | | category | | city | | country | | customer | | customer_list | | film | | film_actor | | film_category | | film_list | | film_text | | inventory | | language | | nicer_but_slower_film_list | | payment | | rental | | sales_by_film_category | | sales_by_store | | staff | | staff_list | | store | +----------------------------+ 23 rows in set (0.00 sec) mysql>Sakilaのサンプルのdbが作成されていることを確認できました
phpmyadminでも見れるようにしてみた
先ほどの
Dockerfile
と同じディレクトリにdocker-compose.yml
を作成docker-compose.ymlversion: "3" services: db: build: . container_name: mysql phpmyadmin: container_name: phpmyadmin image: phpmyadmin/phpmyadmin environment: - PMA_ARBITRARY=1 - PMA_HOST=mysql - PMA_USER=root - PMA_PASSWORD=root ports: - 8080:80$ docker-compose up -d以上です。