なからなLife

geekに憧れと敬意を抱きながら、SE、ITコンサル、商品企画、事業企画、管理会計、総務・情シス、再び受託でDB屋さんと流浪する人のブログです。

MySQLをAWS RDSで使うときに注意すること

MySQL Casual Advent Calendar 2018 - Qiita 14日目の記事です。

MySQLネタで書くと、Casualといいつつ、わりとCasualじゃない話になりがちなので、Casualレベルのお話を。
いや、あんまり優しくない制限の話なんだけど。。。


AWS Relatioal Database Service(以降、AWS RDS)でのMySQLのお話。

OS層に触れない

AWS RDSの基本中の基本。DB as a Serviceということもあり、SSHでサーバOSにログインできません。
MySQLプロトコルをおしゃべりできるクライアントでMySQLユーザーとして接続してください。

NWの疎通確認用にtelnetやvcコマンドでの接続は一応許されてます。


OS層に触れないので、この辺も必然的に使えません。

  • トランスポータブル表領域
  • 標準提供以外のプラグインの組み込み
  • SELECT ... INTO OUTFILE / LOAD DATA [LOCALオプションなし] INFILE


また、SHOW FULL PROCESSLISTとかSHOW ENGINE INNODB STATUSなんかを定点監視出力するスクリプトとか、別途サーバー立てて動かす必要がありますね。
Percona Tool Kitなんかも、DBサーバーに同居してないと使えないものなど出てきます。


正確なibdファイルサイズの確認もできませんので、ファイルの断片化による膨張のチェックも厳しいです。
ググると出てくる「断片化状況を調べるSQL」って、正確じゃないよね、あれ。


テーブルデータをCSVファイルで欲しい場合に、SELECT ... INTO OUTFILE(MySQLが可動しているサーバー上にファイル出力する)が使えないだけでなく、「CSVストレージエンジンに変換して引っこ抜く」というテクニックも使えません。
シェルで投げた結果をsedで加工するとか、mysqldump使うか、MySQL WorkbenchのCSV保存機能を使うか、となってきます。

「SELECT ... INTO OUTFILE / LOAD DATA [LOCALオプションなし] INFILE ... 」は、FILE権限でアクセス可能なディレクトリを固定して、そこだけファイルアクセス提供とかにしてくれると、かなりハードルさがるんだけどなあ。。。


General Log、Slowquery Logも、ファイルを直接参照できません。
じゃあどうするか。

  • 「TABLE」モードにする
  • FILEモードにする場合、
    • CLISDKなどでダウンロードする
    • ManagementConsoleから表示させる(ダウンロードも可)
    • CloudWatchLogsに転送設定して、CloudwatchLogsの画面から参照する(ダウンロードするためには、S3への転送を挟むか、CLIで。)


Binlogは、mysqlbinlogで取り出すことができますが、デフォルトだと5分程度と割と早いタイミングでどんどん消されていってしまうので要注意です。


データ暗号化はインスタンス単位のみ

テーブルスペース暗号化は使えません。
本当に暗号化しなきゃいけないところだけ暗号化して、そうじゃないところは非暗号化することで性能影響を最小限に抑えたいところですが、そうはいきません。
性能検証推奨。

Federatedストレージエンジン使えません

特にOracleからの乗り換え組からの問い合わせの筆頭格に「Database Link的なもの使えるの?」がありますが、RDSでは使えません!
要望多そうなんだけどなあ。。。

ていうか、RDSは基本的にInnodbしかまともにサポートしません

binlogをバックアップ&リカバリシステムに利用してるので、MyISAMその他の復元には限界があるよ)」って話。


SUPER権限が使えません

SUPER権限を行使できるのは、AWS RDSが内部的に利用する「rdsadmin」ユーザーのみ。
利用者に提供されるスーパーユーザー(インスタンス生成時に作成)および、そこからCREATE USERで作れるユーザーに「SUPER」をGRANTすることはできません。

SUPERが必要な操作で、他のコマンドで代替できない操作は、基本的にAWSの提供する機能を通じて行います。
たとえば、グローバルのサーバー変数(my.cnf設定)は、「パラメータグループ」からのみ、変更が可能です。


また、セッションをKillする場合は、ネイティブのKillコマンドが使えない代わりに、AWSが提供するプロシージャ「rds.kill()」を使います。
こんな感じで独自提供されているプロシージャの一覧はこちらにあります。
docs.aws.amazon.com


バージョンによって、使える機能の制限が異なる

GTIDは、現時点で「MySQL 5.7.23 以降の MySQL 5.7 」に制限されています。8.0でも使えない!
こういう「特定バージョンの、特定マイナーバージョン以降」「メジャーバージョンが新しい方でも非サポート」というものは多いです。


RDS Performance InsightsというPerformaneSchemaの一部情報を時系列にグラフィカル表示してくれるツールが組み込まれているのですが、

  • Amazon RDS MySQL version 5.7.22 and higher 5.7 versions
  • Amazon RDS MySQL version 5.6.41 and higher 5.6 versions

という制限付きです。やっぱり8.0で使えない。。。

なお、RDS Performance Insightsは、インスタンスタイプによっても使える/使えないがあります。(t2系では使えない)


個別の機能について書いたらキリがないですが、以下のページを、検討段階やふと気になったときに、常にチェックするようにしましょう。
(できれば、最新情報が早い英語版で読むことを推奨)
docs.aws.amazon.com




ストレージのクセに注意

ていうか、AWS RDSの中身はEC2+EBSです。で、EBSは「ネットワークストレージ」「タイプによって特性が違う」という点に注意が必要です。

ネットワークストレージなので、Disk I/Oの都度、ネットワークレイテンシがオンプレより大きめに発生します。

ストレージは通常gp2というSSDを使いますが、これ、確保したサイズに比例してベースラインとなるRead/Writeの性能が決まります。
1GBあたり3IOPS、Max16,000 IOPS(2018/11に10,000から引き上げられた)です。

なお、ベースラインが3,000 IOPS以下(1,000 GB 以下)のものについては、別途「バースト」と呼ばれる機能があり、暇な時間にクレジットが蓄えられ、忙しくなったらクレジットを消費しながら最大3,000 IOPSまで自動で引き上げてくれる機能がついています。

詳しくはこのへんで。図解もあります。
(日本語ページはベースライン最大10,000時代の図だったので、英語の方のURLで)
docs.aws.amazon.com



また、ストレージサイズは小さいママで、IO性能は高くしたい場合に、io1タイプ=Provisioned IOPSがあり、サイズ比例とは別に有償でIOPS値を指定できます。


EC2上にインストールした時との違いとしては、ストレージを複数アタッチできない、という点です。

EC2では複数ストレージをアタッチして、ファイルの配置先を変えて負荷分散をする(ついでに、EC2+EBSとしてはIOPS上限がEBS1つのときより引き上げられる)ことができるのですが、これはRDSではできません。

古くからのOracle屋さんならお馴染みの「redoとデータファイルは別々のドライブに」の構成がRDSではできない、ということです。


スレーブはリードレプリカではない

高可用性を目的として、Multi-AZという、物理的に離れた場所にスレーブを立て、障害時に自動フェイルオーバーが行われる機能(DNSベースで切り替え)が提供されていますが、この時のスレーブは「リードレプリカではない、独自の同期処理で動くサーバー」です。

なお、「同期」なので、非同期なリードレプリカと異なり、マスターのスループットに影響します。


それだけではなく、このスレーブサーバーは「スタンバイ」機です。通常時、アクセスできないため、Readの負荷分散には使えませんが、インスタンスとしては常時起動しており、マスターと同じ課金が発生します。


Read負荷分散のためには、別途リードレプリカを立てる必要があるので、さらに課金が発生します。
リードレプリカをマスターに昇格させる機能は提供されていますが、障害を検知して自動フェイルオーバー、ってのはないです。

とはいえ、めっちゃ便利です!

いやもうまじでラク

サーバー立てるのも数クリック、レプリカ立てるのも数クリック、HA構成組むのも数クリック、フェイルオーバーは自動(シングルでも自動で再起動)、バックアップは自動、リカバリも数クリックで、Point In Time Recoveryも可。

ログファイルの膨張によるストレージ圧迫対応も勝手にやってくれるし。
各種のメトリクスは標準でグラフ見られるから、別途KibanaやらDatadogやら要らないし(他の環境と統合管理したいときは逆にひと手間必要)

めっちゃラクですやん!


まじでCasualにMySQLが使える環境です。無料枠もあるし。
わりとしっかりドキュメントが用意されているので、使いながら読み込みましょう。


一部独自拡張(SUPER権限制限に伴うストアドプロシージャ追加)とかあるものの、MySQL Community Editionで動いてますので、基本はソースレベル互換です。
なので、同時処理要求数を上げすぎてSHOW ENGINE INNODB STATUSにセマフォの情報が大量出力してしまっても、そこに書かれたソースと行番号で、手元にソース持ってきて正しく追いかけることができますよ!


勢いで書いたので、まだ後で思い出すものもあるかもしれませんが、とりあえずこのへんで。

これからMySQLを触る人は、こういった本でMySQLの運用管理でどんな作業があるかを学びつつ、それがどうラクになるのか、対比してもらうと良いと思います。

やさしく学べるMySQL運用・管理入門【5.7対応】

やさしく学べるMySQL運用・管理入門【5.7対応】

追記(2018/12/17)AWS RDSで提供されるMySQLのバージョンについて

大事なことを忘れていました。

AWS RDSはDBaaSということもあり、提供されるバージョン(マイナーバージョン含め)が限定されています。

大体、メジャーバージョンは本家提供開始から半年くらい、マイナーバージョンはもう少し短い間隔でやってきますが、問題は廃止の方です。

これは明文化されていて、以下のようになっています。

Q: Amazon RDS では、現在サポートされているバージョンのデータベースエンジンの廃止についてガイドラインが提供されていますか?

  • メジャーバージョンリリース (MySQL 5.6、PostgreSQL 9.6 など) に対しては、Amazon RDS によるサポートが開始されてから、少なくとも 3 年間のサポートを予定しています。
  • マイナーバージョンリリース (MySQL 5.6.37、PostgreSQL 9.6.1 など) に対しては、Amazon RDS によるサポートが開始されてから、少なくとも 1 年間のサポートを予定しています。

よくある質問 - Amazon RDS | AWS


1年2年使っていると、その時点で最も古いマイナーバージョンは廃止通知を受け、アップグレードを行う必要に迫られるかと思います。
事前に、提供停止にともなうバージョンアップの通知が来ますので、それに従ってバージョンアップのタイミングを図ることになります。


マイナーバージョンアップもメジャーバージョンアップも、作業自体は数クリックで完了しますし、スナップショット(バックアップ)に対してアップグレードを適用することもできますので、操作自体はオンプレに比べて圧倒的にラクです。


しかし、逆に、バージョンを固定して永久に使い続ける、ということはできません。


マイナーバージョンアップは、セキュリティ対応やバグ対応の要素が強いため、なるべく新しいものを使うのがよいと思いますが、一方で稼働中のアプリケーションへの影響を考えて、なるべく固定化したいという事情もあるかと思います。


そういった事情を踏まえた上で、AWS RDS自体の選択、および、バージョンの選択を行いつつ、運用保守の計画にバージョンアップ対応を組み込んでください。