ツナワタリマイライフスマートフォン用の表示で見るツナワタリマイライフ日常ネタから技術ネタ、音楽ネタまで何でも書きます。〜止まらぬ進化に乗り遅れないためのテクニカルガイド」を読んだはじめに読んだ。単行本(ソフトカバー)この商品を含むブログを見る表紙に「どれだけ詳しいの!?」ある通り、かなり詳しい。私はMySQL5.7を使っているわけではなく、普段はMariaDBの5.5/10系を使っている。MariaDBを学ぶためにも、ベースとなるMySQLを学ぶのが先(だし情報も多い)と思ったので本書を購入した。5.7の175の新機能はほとんど読み飛ばしている。これら新機能は内容でカテゴライズされており、さらに各章では新機能の単体説明に入る前に概要説明があり、これが非常に詳しい。この部分を読むだけでも非常に価値がある本である。それでは振り返っていこう。MySQLの概要その名前の通りMySQLの概要。無料のコミュニティ版と商用版の違いなど。MySQLサーバアーキテクチャが図になってるのは助かりますね。様々なアプリケーションクライアントが、mysqldプロセス内部のコネクションスレッドに接続し、SQLの解析と最適化(パーサ、オプティマイザ、エクゼキュータ、バイナリログ、レプリケーション、アクセス管理)を行う共通部分があり、そこからストレージエンジンAPIを通じて各ストレージエンジンにアクセスし、実際にデータが保存される。バージョンごとの歴史の変遷も記載されているので、MySQLの歴史を紐解きたいひとにはいいだろう。ある意味、この章でMySQLはここ数年でとてつもない進化を遂げてきたことがわかる。5.7に対してここまで詳細な説明が書かれているのは本書しかないだろう。著者の奥野さんが、DB関連で検索するとよくひっかかる「漢(オトコ)のコンピュータ道」を書いているが、そこでは5.8、、ならぬ8.0に対しても本書のようなものを書くかというと、書かないと言っていた。ちなみに8.0の新機能詳解の記事はこちら。レプリケーションレプリケーションがもっとも変更点が多く、インパクトが多いそうで2章にきている。ここで学べるのはMySQLのレプリケーションの基本原則だ。レプリケーションの構造概要(図2.1)が非常にわかりやすい。クライアントが接続するコネクションスレッドは、ストレージエンジンに対してPREPAREした後、バイナリログに書き込む。バイナリログに書き込んだあとはマスターのストレージにコミットする。そのあと、マスタースレッドはスレーブI/Oスレッドに対してバイナリログを送信し、スレーブ側のスレーブI/Oスレッドコミットあと、マスタースレッドはスレーブI/Oスレッドにバイナリログを送信し、リレーログに記録。スレーブSQLスレッドがそれをストレージエンジンに書き込む。マスターとスレーブのスレッドの名前があまり対称的でないからわかりづらい。いうと準同期レプリケーションだ。先日紹介した本でもあった。プラグインをいれれば準同期をサポートできるようで、それも本書に記載されています。各トランザクションにIDをふっている。オプティマイザ実行されたSQLに対して、そのSQL構文を解析し、実際にどのようにデータを取得、解析し求める答えを出すか、その"最適な答え"を出すのがオプティマイザだ。その用途で使われるEXPLAIN、実際に使ったことがないので本章は流したが、なぜか遅いクエリがある場合には重宝するだろう。今の仕事では、アプリそのものを作ってるわけではないので、クエリを変えるわけにはいかない。代わりに、同じクエリで結果がよくなるのであればオプティマイザのチューニングも価値があるだろうが、ちょっとまだ手が出せないですね。InnoDB待ってましたの章!「RDBMSをアスリートに例えると、オプティマイザが身体を動かす頭脳に相当するものだろう。実際に身体を動かす筋肉に相当するものは何かというと、ストレージエンジンだ。」と冒頭で語られる通り、MySQL(MariaDB)の活用に関してInnoDBの理解は避けて通れない。この章はかなり重要であり、詳しく書かれているので本当に重宝する。ここでInnoDBへどのように書き込みが行われるか整理しよう。クライアントからのリクエストがあると、まず「データベースキャッシュ」であるバッファプールに書き込みが走る。これはinnodbで最重要と言われるinnodb_buffer_pool_sizeが示す領域である。このあと、ログバッファへ書き込む。いずれも、メモリ上の領域である。このあと、いよいよストレージに書き込むため、ログバッファから「ステーブルログ」であるログファイルに書き込む。これは実際にはiblogfileのことだ。ここまで書き込んでようやくコミットし、クライアントに応答を返す。(トランザクション)ちなみに、ログバッファからログへの書き込みタイミングは(MariaDBのドキュメントを参照するが)innodb_flush_log_at_trx_commitによって、挙動が変わる。mariadb.comもちろん、各トランザクションごとに、毎回、ログバッファに書き込んだらログに書き込むのがACID特性を守るために必要であり、もっとも重要である。commitを模した3があるようだ。ログに書き込んだ時点では「ステーブルデータベース」であるテーブルスペース(実際にはibdata1、あるいは.ibd)に書き込まれていない。これをダーティページと呼ぶが、適宜書き込まれていく。テーブルスペースに書き込まれたログは不要である。ここで分離レベルについてもおさらいしておこう。Reads」の3種類の事象が存在する。Readsは、コミット前にログに書き込む最中に別のクライアントがアクセスした場合、実際のデータではなくバッファから読み込む。このとき、1つめのアクセスがロールバックした場合は偽の値を得ることになる事象のこと。Readsは、1度読み込んだあと、別のクライアントによって変更または削除によって、求める値が取得できなくなる事象のこと。Readsは逆に、1度読み込んだあと、結果は得られなかったが、別のクライアントの挿入によって突如として値が得られる事象のこと、と理解しました。いずれにしても、このような現象はトランザクションでは起こってほしくないので、これをどれだけ防げるか、を示したレベルが分離レベルです。以下から、下に行くほど強固になります。READ-COMMITTED読み取りと変更にロックがかかる。読み取り後はロック解除される。変更はトランザクション終わるまでロックされる。Readsは発生しない。Readsは起こりうる。REPEATABLE-READトランザクションの終わりまで読み書きにロックがかかるので、Non-Repeatableロックも発生しない。SERIALIZABLEトランザクションが終わるまですべての処理にロックがかかる。うーん、ちょっとイマイチまだ理解しきれてませんが、分離レベルがあがるほど、同時実行性能は下がってしまうということですね。ログまず、REDOログへ書き込まれる前に、バッファプールに乗った変更はログバッファに乗る。Transaction)という単位で書き込まれる。して積みかさなったログバッファから、COMMITなどのタイミングでこのREDOログに書き込まれる。REDOの名称は、クラッシュし、REDOログには記録があるが、ストレージスペースに記録がない場合のクラッシュリカバリをする際、「再書き込み」をREDOログから行うからだろうか?ダブルライトバッファログとテーブルスペースの時点でダブルライトじゃないかーと思ったんですが、それとは別に、データファイルの書き込みレベルで2回行うようです。"データファイルの連続した2MBの領域にデータを書き、その次に実際のデータページを書き込む"とあります。これによって"オールオアナッシング"を実現できます。Control)がある。一貫性の制御のために、テーブルにバージョンという概念をいれ、例えばロックをかけて変更する場合、そのトランザクション中は変更前の値(バージョン)を他の読み取りに対して見せる仕組み。readにロックをかけることなく、writeを行ってる間の一貫性維持が実現できる。過去の行は完全なコピーとして"UNDOログ"という領域に保存され、ここを見せている。トランザクションのロールバック時はこのUNDOログを次々とたどって復元するわけだ。増え続けるUNDOログをいつ消去するのか。トランザクションがコミットさえされれば使うことはないので削除可能である。コミットごとに削除するのではなく、パージスレッドという専用のスレッドが順次巡回して削除するようである。パフォーマススキーマとsysスキーマパフォーマンススキーマ性能情報を1つのデータベースとして記憶するパフォーマンススキーマ。使いこなせるといいなと思ってますが、いまいちよくわかっていません。パフォーマンススキーマそのものの有効/無効化、そして計器(計測項目)ごとのON/OFFもあるようだ。いえ、合計(実質)78個もあるパフォーマンススキーマ、どう活用していいか正直わからない。本当にこの機能を活用しないといけないときにまた見直したい。sysスキーマ「パフォーマンスキーマは、極めて豊富なデータを取得できるので、エキスパートにとっては便利なツールであるが、初心者や中級者にはややとっつきにくい面もある」そうそう!100個のビューと47個のストアドプログラムがあるとのこと。user_summaryビューアプリにアクセスするユーザが異なる場合、どのユーザが一番処理を食ってるのかがわかりそうinnodb_lock_waitsビューlockによる待ちが多発してる場合に役立ちそうビューがどうやって見れるのかわかってないが。JSONデータ型この章は今は興味がないのでスルーしました。NoSQLでJSONがサポートされている昨今で、RDBMSでの対抗手段なんでしょうかね。APIをサポートするWebアプリケーションは、bodyに含まれるJSONをそのままDBに保存できれば楽なような気も、直感的にはします。パーティショングこの章も概要だけ抑えて流し読みです。データアクセス高速化を目的に、テーブルを一定の法則で分割します。セキュリティユーザを含む権限テーブルの話。プロキシユーザや暗号化について。この章も流し読みです。クライアント&プロトコルクライアントとして、各言語のライブラリの紹介は有益ですね。あとはmysqldumpやmysqladimnなどのプログラムもクライアントの一種として紹介されていました。ちなみに各バージョンごとのmysql_upgradeの挙動が知りたい。バージョン間差異だろうからなぁ。その他の新機能そもそも新機能よりは概要説明だけさらうような読み方をしてるのでこの章も流し読みで終わりました。おわりにMySQLを以前のバージョンから5.7にupgradeし、運用するひとには必携の本であり、もちろんMySQL(あるいは私のようにMariaDB)初学者でも、各章の前半をおさえることでMySQLの全体像がつかめ、次のステップに進めることのできる良書です。正確には全部読んでない。