最近MySQLをやめて別のRDBMSにしたときの話

※本エントリはMySQLをうまく使っている人やMySQLの運用したい人の考えや、ましてMySQLそのものを否定するものでもありません

こんにちは。まいんだーです。

# 最初に結論
マネージドRDBMSを求めるなら、セットアップやバックアップだけでなく、セキュリティ対策やクエリ分析やインデックスチューニングまでやってくれるものを検討したほうがいいときもあります。
あくまで、いいときもある、という程度です。

# 最近MySQLをやめたほうがいいと感じた瞬間
1. ORMを使っていて、せいぜい調査の時くらいしかSQLを書かない
2. VMに雑にインストールされたMySQLは特に設定変更もされていない吊るしの状態
3. = 実行計画も見ず、スロークエリのケアもしていない
4. Azure Database for MySQLは未だにPreviewだし何気にいい値段する
5. 仮にそれを使ったところで実行計画やスロークエリのケアは結局されそうにない
6. "まいんだーさんが面倒見てくれるんでしょ？"

最近かような状況に遭遇しまして、いわゆるマネージドサービスであってもMySQLを使うのをやめました。

# マネージドを名乗るDBaaSに求めていること
## 世の中の "マネージド" を名乗るサービスがやってくれること
世の中にはいろんなDBaaSがあるわけですが、これらは基本的にインスタンスの立ち上げやバックアップはやってくれ、スケールアップに関しては再起動すればOKというお手軽さがうれしいわけですね。最近だと弾力的なスケーリングもサポートされ始めてきたようです
## やってくれないけど開発者的には本来やってほしいこと
しかしそんなマネージドサービスを使ったとしても、まだ多くの課題が残っています。
例えばセキュリティチェック、クエリ分析、インデックスチューニングあたりですね。
この辺をサポートしてくれないと、結局そういうことは利用者の組織にいる詳しいっぽい人が対応することになって、実態あまりうれしくなかったりします。

# じゃあ何を選んだの？
Azure SQL Databaseを選びました。
## 何がいい点なの？
先ほど述べた通り、開発者的にやってほしいことをやってくれる機能がある点です。
詳しくは以下に書きます。
## セキュリティ
驚異の検出という機能があり、不審なDBアクセスパターンの検知や、典型的なSQLインジェクションを検知して通知を出してくれます。
OSSのDBインスタンスを立ててくれるだけのものだとこういうものの検知は自分でカバーする必要があるわけで、監査機能を有効にするだけでこういうのを監視して通知してくれる点は、"ちゃんとマネージドしてる" という感じがします。

## クエリパフォーマンス分析
普段からDBを運用している人からすると、どういうクエリがどのくらいの頻度で発行されていて、それはどのくらいリソースを使用しているかを監視したくなるのが人情だと思います。
人によってはバッチで情報収集してElasticsearch + Kibanaでダッシュボードを作っている人もいると思うのですが、そういうのがビルトインで提供されていて
![image.png](https://qiita-image-store.s3.amazonaws.com/0/6835/23af43d8-af5c-6721-bcd1-9a12ebedc4be.png)
クエリのパターンごとにグループ化して(クエリIDをつけて)、それらがどのくらいのリソース消費割合をしているか、とかクエリにどのくらい時間がかかっているか、というのをまとめて見せてくれる機能があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/6835/eb652f3f-a2a1-025b-64ff-7e274b6c87ab.png)
こういうのを自分でやろうとすると意外と良いソリューションがなかったりするので、とにかくサービス影響が出そうなものからまとめていってくれることは運用上大きなアドバンテージがあると思います。
MySQLでこういうことをやってくれるサービスをご存知の方、ぜひ教えてください。
## インデックスチューニング
で、クエリパフォーマンス分析ができると次にやらなければならないことは何かというとインデックスチューニングだったりするわけです。
重たいクエリがある場合、設計自体を見直すことも重要ですが、まずはチューニングで対応できるかを検討したいというのも、DB運用者の人情だと思います。
前項までの情報が出せる(クエリパターンを理解する + それらの負荷状況をまとめる)のであれば、この辺は自動化できるんじゃないか、とお気づきの方もいらっしゃりそうですが、もちろんこの点もカバーされていて、運用していくと
![image.png](https://qiita-image-store.s3.amazonaws.com/0/6835/1aea8087-bac9-f75c-7878-7af6bf895ae4.png)
こんな感じで "こうしてインデックス貼ったほうがええで" とサービス側から教えてくれます。
"適用" という項目があるので感のいい人はわかると思いますが、ぽちっとなでインデックス適用をやってくれます。逆もまたしかりで、使われていないインデックスがあったら削除することを推奨してくれます。

この機能には賛否ある(特にサイズや流量の大きいMySQLのDBを運用した経験のある人ほど否定的になりがち)と思いますが、それはケースバイケースで判断して手動対応するとかすればいいと思います。
## 動的データマスクと行レベルセキュリティ
セキュリティ周りでよくあるのが、気軽に個人情報やカード情報にアクセスさせたくない、というものです。
MySQLだと[この辺](https://qiita.com/murak/items/7add80e9624b1abf103a)とかが気軽に検索して出てきたり、あるいは hogehoge_masked みたいなカラムを作ってそこにマスク済みのデータを入れたりがカジュアルな解決策として考えられます。
が、前者にせよ後者にせよ、アプリが生データを取れてしまう状況は変わらず、うっかりするとポロリが発生してしまいます。
そこで動的データマスク機能を使うと、特権ユーザ以外はアプリケーション側に生データが渡らないようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/6835/4739263c-355a-dc14-ee0c-f9ad8794c093.png)
マスクルールも典型的なクレジットカードやemailはビルトインで存在していて、それ以外にはランダムに埋めるとか、n文字からm文字までとかそういう設定ができます。

行レベルセキュリティは、ユーザの設定状況に基づいてそもそも検索クエリにヒットしないようにするといったことをDB側で制御してくれる機能です。
マルチテナントのSaaSみたいな、A社のデータはB社に見えてはいけないといった要求があるときにいちいちプログラム側でケアしなくてよくなるのはいいことだと思います。

# それっていくつかはMySQL Enterpriseにもあるじゃん
MySQL Enterpriseを使っている方、実際どうなのか感想エントリを書いて是非教えてほしいです。
[Oracle Cloud](https://cloud.oracle.com/ja_JP/home)だと[MySQL Enterprise](https://cloud.oracle.com/ja_JP/mysql/features)でサポートされているEnterprise MonitorとかQuery Analyzerが使えるしセキュリティ周りもしっかりしているようなのですが、Oracle CloudユーザかつそこでMySQLを運用しているという方に出会ったことがなく、この辺の知見がシェアされてくるとMySQLでの選択肢がさらに広がるのかなという思いです。

# おわりに
世の中には結構な範囲をカバーしてくれるサービスが存在しているので、自分で運用することが割に合わなそうだと思ったら、別のRDBMSサービスを検討することもたまにはアリだと思います。
果たしてこの判断が良かったか悪かったかは、しばらく運用してみて振り返りをしようと思います。

MySQLをこのレベルでケアすることについての雇用があれば、上記のようなことに取り組みたい思いはあります。

それでは！

※本エントリはMySQLをうまく使っている人やMySQLの運用したい人の考えや、ましてMySQLそのものを否定するものではありません