MySQL Casual Talks vol.10 に参加してきました

https://mysql-casual.connpass.com/event/48473/

去る02/01（水）に開催された 「MySQL Casual Talks vol.10」に参加してきました。
面白いテーマが多く、非常に楽しい勉強会でした。その中でも、自分が気になった点を
備忘録がてら、いくつかメモしておこうと思います。

※ 基本的に個人の感想なので、誤解している点などがあってもご容赦ください…

### 1. MySQL Casual 運営についての話 （myfinderさん）

・ MySQL Casual のSlackに外国の方向けのチャンネルを作るという話
・ 現在のメンバーの中にも日本語圏以外の人が割といる

MySQLがインターナショナルなソフトウェアであることを再認識しました。
英語用チャンネルで早速MySQLのプロダクトマネージャーである Morgan氏が
反応してくれたのがすごい。MySQL8.0 への要望とかも受け付けてるらしいです。

### 2. MySQLの限界に挑戦する(?!) （meijikさん）

・ MySQLの様々な限界に挑戦する話
・ めちゃくちゃ長文なクエリを実行してみたり
・ MySQLの上限を規定するのは、max_allowed_packet だけではない！
・ Linux（MySQL）の構文解析と字句解析について

過度に長文なクエリを実行すると、クエリの字句解析のフェーズでメモリを使いきってしまい、
エラーになるのが新発見でした（こんなケースそうそうないですが…）。
「クエリの解析」の場合、字句解析は独自実装だが、構文解析はbison。
また、『BNF』というを理解すれば、クエリ整形ツールやRDBそのものを開発できるようになるそうです。

### 3. MySQLの文字コード事情 （tmtmsさん）

・ よく話題になるMySQLの文字コードについての話
・ utf8 や cp932 は「文字コード」ではなく、「エンコーディング」
・ 世界では 「utf8」 と言ったら、「utf8mb4」のことを指すが、MySQLは「utf8 = utf8mb3」
・ utf8mb3 と utf8mb4 を区別するソフトウェアはMySQLくらいではないか
・ 「寿司＝ビール問題」や、「ハハ＝パパ問題」を全て解決する utf8_japanese_ci が欲しい

「character-set = 文字集合 + エンコーディング」という考え方は、今後しっかり覚えておきたい。
とりあえず、基本的には「utf8mb4」を使っておけばいいと思います。
MySQL8.0 で日本語文字コードが抱える諸問題が一気に解決することに期待。

### 4. Group Replication 関連 の何か （mita2さん）

・ MySQL Group Replication （= マルチライター）の基礎的な話
・ MGRのいいところは、全く同じ構成でサービス用DBをリリースできること（＝金太郎飴のイメージ）
・ 運用するMySQLの台数が多くなると、従来のマスタ・スレーブ構成でもつらい
・ MGRを使う場合は、 Flow Control とか Split Brain などの機能・用語には注意すべき

MGRではSavePointがサポートされていないため、ノードに対して mysqldump --single-transaction を
実行できないのは注意したいポイントだと思いました。
「同じDB構成をリリース」というのは、いわゆるDB基盤システム的なイメージかな、と思います。
マイクロサービスで、色んなサービスをリリースしたいWeb企業とかにはフィットしそう。

### 5. MySQLアンチパターン （yoku0825さん）

・MySQLにおける「アンチパターン」（≒やってはいけないこと）の話
・ある程度DBの開発・運用を経験してからの方が、アンチパターンは身に染みる
　（若いころはアンチパターンと分かっていても回避できないこともある…）
・テーブルを一時変数格納用テーブルとして使ったり、JOINが遅いといって何も考えずに非正規化したり
・ER図は自動生成できるようにすると楽（＝FKをしっかり貼る）
・エラーコード（"0"）と、取得結果0件（"0"）が混在したり
・MySQLの特徴（得意、不得意）をしっかり理解しよう！

実体験？に基づいた話だったので、どれも覚えておかないといけないTipsだと感じました。
基本的にダメなクエリは非正規化してもダメなので、適切なクエリの書き方を学ぶことが
一番重要だと思います。
あとは、アンチパターンを「知らずに使用する」のと、「知ったうえであえて使用する」のでは
全く内容が異なるので、まずはアンチパターンを頭に入れておきましょう。
（≒ 『SQLアンチパターン』を読みましょう）

### 6. zabbix+maxscale+mysqlrouter+group replication （bringer1092さん）

・本番環境のZabbixのバックエンドをHA化（＋負荷分散？）する話
・当初はMaxScaleを検討していたが、使いたかったフィルタリング機能が仕様にマッチしていなかった
・代わりに採用したのがProxySQLで、フィルタが柔軟で助かる
・バックエンドのMySQLはGroup Replication（シングルプライマリモード）

実際の本番環境に Group Replication に加えて ProxySQL まで入れるとは、
かなりアグレッシブだと思いました。
MaxScale と ProxySQL は機能的には大して変わらないと思っていましたが、
細かな部分で差があるようなので、これは要検証ですね。

### 7. Webサービスが成長するとロックで苦労する話 （soudai1025さん）

・実体験のようなフィクションに基づいた過去の苦労話
・「闇の深いリファクタリング」や「潤沢なサーバリソースから低すぎる使用率」など、
　実際の現場で起こり得る事例が多かったです
・ロックに関する情報を見るなら、Performance_Schema便利。有効にしておきましょう

リアリティのある障害（ロック）対応の話で、勉強になりました。
ロックの情報は「現在」のものしか取らない、ということを知らない人も多いので、
情報は常に収集するようにしましょう。

### 8. MySQL/MariaDB用NoSQLプラグイン Transactd （bizstationcorpさん）

・ MySQLの内部処理の基本である「ISAM」と、それを独自に発展させた「Trandactd」の紹介
・ ISAM = "Indexed Sequential Access Method" （≠ MyISAMだけど、語源ではある）
　　　　= インデックス順にアクセスする方式 
・ レコードをフェッチする時のカーソルの挙動は7つだけ。これだけで全て完結する
　First（最初）、Last（最後）、Next（次）、Prev（前）、Equal（=）、Lessthan（=<）、Greater（=<）
・ ISAMが分かると、クエリの挙動が分かる ＝ パフォーマンス、ロック範囲が分かる
・ Transactd は全てのSQLの実行を内部的（プラグイン）にISAM方式に変換して実行している
　　→ そのため超高速
・ 最新のチュートリアルはかなり力を入れたので、是非Transactdを一度試してもらいたい

ISAMの説明が非常に分かりやすく、知らなかった知識もしっかりと理解することが出来ました。
いわゆるMySQLのHandlerレイヤーの仕組みが分かったので、それをさらに掘り下げれば、
遅いクエリ、速いクエリの見分けがつくようになるかと思います。
公開されたパワポ資料には、口頭で話した内容も書かれているので、是非ご一読することを推奨します。

### 9. Test::mysqldの話 （songmuさん）

・ MySQLのテスト用ツールであるTest::mysqldの話
・ 元々kazuhoさんが開発したものを継承し、現在も開発は続けている（Go版作りました）
・ 各レイヤーごとにテストするよりは、アプリからDBまで一気通貫でテストしたい
・ 想定通りのデータが実際に参照されること、また更新が反映されることを確認
・ モックを頑張りすぎても意味はない

「Test::mysqld」ならテスト用サンプルデータを.sqlファイルにまとめて、
毎回自動的にインポートとかもできるみたいです。Dockerとの相性がよさそう。
実際にどんな挙動をするのか、後で時間を見つけてテストしたいと思います。

### 10. Advent Calendarの補足的な話 （i_rethiさん）

・ 以下の2016年MySQLアドベントカレンダーの投稿の補足
　http://d.hatena.ne.jp/hiroi10/20161222/1482333709
・ ib_logfile のサイズを大、小の2パターンでベンチマーク
・ 並列性もテスト
・ ベンチマーク結果の分析にはdimSTATを使用

詳しいテスト内容やスコアは記録してなかったので、資料の公開を待ちます。
dimSTAT、そろそろ使ってみないとなーと思いました。

### 11. かみぽ枠 （kamipoさん）

・ Rails のプルリク（バグ修正）をたくさんやる中で実際にあった失敗談
・ ZEROFILLの存在を意識せずにコードを直したら、unsigned判定でエラーが起こるようになった
・ ZEROFILLに対応できるように追加で修正をした
・ sql_modeまわりを改修したら、ANSI_QUOTESが有効になっている環境だと
　 クオートが " に変換されてしまい、SHOW CREATE TABLEで情報を取っていた部分が
　 正常に動かなくなった
・ information_schema(referential_constraints)から情報を取得するよう修正
・ ↑ の修正の後、外部キーの取得がすごく遅くなった（さらにMySQL5.0だと動かなくなった）
・ information_schema ではインデックスが特定の条件下じゃないと使われない
・ インデックスを使うよう修正、MySQL5.0のサポートは諦めた（依頼主には5.6に上げてもらった）

大多数の人にとっては「嬉しい」修正でも、一部の人（想定しづらい設定を使っている等）には
困った事態になることもあるみたいです。MySQLはオプションが豊富なので、もしかしたら
「まさかそんな設定を！？」という方は意外と多いのかもしれません。

先入観を持ってしまうのはいけないな、と思いました。

=========================

※ yoku0825 さんがまとめてくれた以下のTogetterも参考になります
　 https://togetter.com/li/1077019