まっしろけっけ

めもてきなやーつ

最近喋ったことを書く

はじめに

最近(7月)社内で色々喋っていたのでそれについてざっくりまとめておこうという気持ちです。

1. プロダクトおはなし会

minne 事業部の PO,デザイナー,エンジニア(アプリ,web,インフラ) の代表が 3Q はこんなことやりますよって話す会

web チームとして話した内容は 1Q, 2Q 終えての課題だと思った。

障害時の対応
タスクを最後までやりきる

この 2 点をもう少し頑張ろうっていう話。

障害時の対応

これに関しては、障害の大きさ(事業への影響)を即座に判断し障害の根本原因解決
もしくは最低限ユーザに影響がない状態へ持っていく際の判断を出来るだけ間違わずに出来るようになろうという話。

例えば iOS のアプリをリリースしたんだけどバグがあり API のレスポンスを受け取ると高確率でクラッシュするという問題が発生した際

根本原因を解決するという部分を最優先にしてしまうと、
根本原因が解決するまでユーザはアプリを使うことが出来なくなるという問題が発生してしまい事業への影響は大きくなってしまう。

そうならないように原因を特定したら API のレスポンスを調整することでアプリで一部表示されないエリアが発生するが
アプリを使うことは可能という状態に持って行った方が影響は少なくて済む。

web チームの面々は根本原因を解決するという部分に目が行きがちな時が多々あったので
このような判断を即座に出来るようになり事業への影響が出来るだけ少なくなるようにしようというのが 1 点

もう 1 点が障害解決の為にもっと技術力つけていこうぜっていう話(障害解決の為にと書いているが結果的に障害解決以外の部分にも大いに役立つと思っている)

障害の原因を特定するにも技術力が必要だし、原因を解決するにも技術力が必要という話をした。

例えば障害の原因がインフラ関連のものだった場合にインフラだから解決できないというのは技術力がない(自分の専門とする技術以外の技術力がない)から解決できないと同義なんで技術力をつけよう。技術力というのは知識を持ち経験をすることで飛躍的に向上すると僕は思っているので、自分のサービスで使われている技術やインフラ環境の知識を得て、調査をすることで技術力をつけていこうっていう感じ。

なぜこんな話をしたかというと僕はチーフテクニカルリードという立場で確かに技術方針を決めたりするのでチームで一番技術力がないといけないと思っているけれど、それがチームとしての SPOF になってしまうのは出来るだけ避けたいという考えがあったからです。

僕がいつ死ぬかもわからん(この記事を公開した数秒後に死ぬことだってあり得る)ので、僕が死んでもチームのメンバーで変わりないクオリティでサービスを運用できれば最高だなと考えている為です。

タスクを最後までやりきる

これに関しては、 2Q にチームに特に期限も決めずに 1 つ仕事を投げて見たのだけれどこれの進捗があまり良くなかった。
というのと各スプリントでもスプリントで完了しなかったもしくは時間ができたらやります的なタスク。

原因は色々あると思うのだけれど、これに関しては特にこうやって解決していこうという案は出さずに
みんなで意見を出して解決して見てよって感じにした。

なぜか?
今のチームは 2 週間ごとのスプリントだと振り返りで KPT を出してしっかりと P に対して T を出し取り組めていて
セルフマネジメントがある程度できているチームだと思っているので
更に最高のチームを目指す為に 2 週間という枠ではなくもう少し大きな期間でのチームの課題も自分たちで気づき解決をして行って欲しいと思った。

今のチームであればそれは出来るであろうと僕は思っているので後はきっかけを与えるだけなのかな?と思ったので僕からは解決案を出さずに(悪く言えば)丸投げという形をとって見た。
これに関してはどうなるかは 3Q 終わってみてという感じかな

2. 新卒向けの minne の web チーム紹介

minne のマーケと CS に配属された新卒向けになんか喋って〜と言われたので web チームのことは僕がアプリチームのことは@hisaichi5518 が喋った。

これは非エンジニア向けだったのでそもそも web チームの人たちが何を開発しているのか?という点と普段 web チームが大事にしていることについて。
普段 web チームの人たちが大事にしていることは「アタリマエをアタリマに」 + 「アタリマエじゃないこともアタリマエに」なんだけれど、
サービスが成長するに当たってその時々で必要とされるアタリマエも変わってくるのでサービスが成長するのに合わせてチームも成長していこうっていうのを大事に web チームは開発をしているよっていう感じの紹介。

3. bigfoot 勉強会

最近勢いがある PO に勉強会やってもらえないっすか?と言われ、おっ!いいじゃんと思ったのでやりましょう!って話したのがきっかけ。
みんながどんな内容のことを知りたいのかわからなかったので、とりあえず知りたいことなんですか?という感じでいくつかの選択肢を用意してアンケートをとってみた。でその結果を元に喋った。

1. bigfoot とはどういうものか?
2. bigfoot でどんなことが出来るのか?
3. bigfoot のクエリの書き方(基本編)

という 3 点を喋った。
エンジニア相手なら三宅さんのこの資料見てで終わるのですが、非エンジニアに対してなのでもう少しわかりやすく。

どういう流れでログが TD に投げられるかや TD の PlazmaDB や datatank の違いに関して等を話した後に、実際にどんなログを送っていてその結果としてどういうことが集計できるのかという話をした。
で、最後に簡単なクエリの書き方を説明して終わり。

この話をした 1 週間後くらいに福岡の財津君が来たタイミングで、希望者を集めて今知りたいと思っている数値を実際にクエリ書いてとってみましょうという会を開いていたので参加した人にはわかりやすかったのではなかろうか?という気持ち。

参加した人たちも前より積極的にクエリを書いてくれている気配があるので一定の成果はあったのでは

4. ECTechMTG

下記の内容。主に bigfoot の宣伝をした。

shiro-16.hatenablog.com

最後に

最初の3つが一週間に詰まっていて発表練習は全くできてなかったので(という言い訳)、なんか話まとまってんのかよくわからん...個人的にはイマイチだなぁという感じになってしまったのはすまん...という気持ちです。

EC 事業部の TechMTG でなんか喋った

経緯

tech.pepabo.com


上記の第 2 回が終了した直後に けんちゃんくんさん (@kenchan) | Twitter に第 3 回のゲストトークどうですか?ってお願いされたのでじゃなんか喋りますって感じで喋ることになった。当日はスペシャルゲストという紹介のされ方だったのでマジか!という気持ちだった。

発表内容

資料は下記

www.slideshare.net


内容としてはペパボのログ解析基盤である bigfoot を活用したサービス改善事例の紹介(という名の bigfoot の宣伝)。
EC 事業部は PHP のサービスもあり bigfoot 周りの便利ツールは gem として提供しているものがほとんどなので、即導入とかはちょっとつらめかなと思いつつ...


ペパボのログ解析基盤と言いつつ minne 以外で有効に活用できているサービスは少ないという状況なのでこういうことできますよ〜っていうのの一部を紹介した。公開している資料は当日使ったものの中で、まだリリースしていない機能だったり具体的な数字を削除していたりするのでもう少し多めに事例を喋りました。


社内用の発表だったので煽りを入れつつ多少面白く話せたのでは?という気持ち

最後に

EC 事業部に(2 ヶ月だけ)いたので帰って来た感があった(嘘です)

発表直後から EC の人々が続々アカウント作ってくださいという issue が作られた( issue ベースでアカウント申請をしている )ので
話してよかったなという気持ちです。

Treasure Data の job の状態を監視する mackerel plugin 作った

経緯

ペパボのデータアナリストの @zaimy何らかの原因で job が詰まって割当リソースを使い果たすと、該当のクエリ以外の job も巻き込まれて error になることがあり困った と言っていて
mackerel とかで見れると嬉しいなと言ってたのでじゃなんかやっておきますねって感じが経緯です。

mackerel plugin を選んだ理由

mackerel 使う以外にも色々方法はあると思うのですが、mackerel 使ってるし mackerel plugin 作ったことないから面白そうだし作ってみるかなで決めました。

TD API 調査

TD の API のリファレンスはこちらこれで job の一覧が取得できる。
がしかし 20 件しか取得できないっぽい。ということがわかった。

また、パラメータとして ?status=running とか渡すとその status で絞り込めるっぽいというのを発見したけど
リファレンスに載ってないので使わんでおこうかなと思った。
TD の client は td-client-go 使った。
この client でも上記の API にパラメータ渡せない仕様だったので素直に使うことにした。

20 件しか取得できないっぽいということなのでその 20 件の job の status しか見れないが、20 件の各 job の status を分類できるだけでも困っていることは解決できそうだったのでそれで良いかなということにした。

plugin 作成

plugin の作成はここら辺の公式のヘルプをみたり、大量にある plugin のコード読めばわかったのでそこまで問題はなかった。

一点だけハマったのが結果を出力するときに出力する値の型が制限されているのに気づかずに int で値を渡していて結果が出力されない...なぜだ...となりハマった。さっさとコードを読めば解決する案件だった

できたもの

github.com

できたものがこちら。
下記みたいになる。0 件の場合も出力しておいた方がグラフ途切れたりしないので良いなって思ったので追々やる予定

$ mackerel-plugin-treasure-data-job-count -treasure-data-api-key="your API KEY"
treasure-data-job-count.error	1	1493270870
treasure-data-job-count.success	19	1493270870


あとは monitoring を行う server に plugin の設定入れて mackerel 側で監視の設定入れておしまい。

最後に

面白かったので満足

Rubyエンジニアが語る、2016年の振り返りとこれからに登壇して来たよ

株式会社 Speee さんと自分が勤めるペパボが共同で開催した下記のイベントに登壇して来ました。

speee.connpass.com

経緯

経緯としては、CTL になったし喋らない?って声をかけられたからなのですが、
個人的に昨年のアウトプットが圧倒的に少ないこと、
その反面インプットは大量にあり話せることはいっぱいあるぜ!って感じだった即答で喋りますって言った記憶がある。

発表内容

当日の資料は下記
最初作って練習してみたら 30 分超えの大作になってしまったのでだいぶ削った。

www.slideshare.net

内容としては 2016 年に行った minne の API の改善の一部を紹介
問題だと思ったことを 1 つずつ改善しましたって話なのですが、
この問題に対して技術的負債と言う人もいると思いますが、
自分は特に負債とは思っていなくて minne の急成長には必要なものだったと思っていて、
管理のしやすさとかよりも、急成長する為にスピードを優先した結果なので必要なものだったと捉えています。
成長の機会を逃し、サービスが終了しては本末転倒なので...

また、ペパボでは今後を見据えてこういうことの改善をしたいですと言えば、
非エンジニアの人も納得してくれる環境があるのでいいバランスが出来ているのではないかと思っています。

発表後の質問や懇親会でも質問を幾つか頂いたのでそれなりにみんな興味のある内容だったのかなという感じでよかった。

イベント全体

Speee さんのオシャレなオフィスのカフェで開催され、
PHP から Ruby への移行の話を聞きながら 3 年くらい前に自分もやったな...って思ったり、
縦に長すぎるコントローラやばいな...と言う話、独自言語辛いという話など面白い内容が多かったのではという感じ。

懇親会でも質問を幾つか頂いたり Speee さんの若者に色々お話を伺ったり楽しかった。

最後に

最初の方に CTL になったとさらっと書いたのですが、それについては別で記事を書く予定です。

昨年のアウトプットが圧倒的に少なかったので今年は 2 ヶ月に 1 回くらいのペースでなんか喋りたいなという気持ちでいます。
昨年は API 改善,検索改善,開発基盤改善とかやりつつ普通の機能追加などの開発やってたりしたのでそこら辺の話とか
昨年から今年 1 月に Rails 5 対応してるのでそこら辺とかネタはあるのでまぁ大丈夫だろうという気持ち。

2016 年振り返り

はじめに

約 4 ヶ月ぶりのブログ...
今回は 2016 年の振り返りをしてみようと思います。

お仕事

シニアエンジニアになったり、テクニカルリードになったりした。
ペパボに入社した時から 1 年以内にシニアになると決めてたのでなれてよかったね。

技術的な話だと前半は Elasticsearch 使って検索周りで色々やってた。
後半は API のテクニカルリードとして検索や他になんかやってたら Apple Pay の対応やることになったのでそればっかりやってた。
Apple Pay は色々な意味で辛かったりしたけど、Apple公式サイトに minne が載ったり新 MBP の CM に使って貰ったりしたので報われたなという感じ。
Apple Pay 終わった後は Rails 5 の対応とかやってる(現在進行形)

2017 年から僕自身の minne 内で求められる役割が変わるという話を 11 月頭に聞いて、
人生で初めて 11 月から次の年のことを真剣に考えてた。

API のテクニカルリードとしてもっと API 関連のあれこれやれればよかったというのが心残り

アウトプット

OSS

何個か gem 作ったり、バグ見つけて PR 出したりとかしてた。
ここら辺は別で記事を書きたい気持ち。

ブログ

...あまり書けてない...ただのメモのつもりで書いているブログなのでもっとメモを残していこうというお気持ち。

執筆

WEB+DB PRESS Vol.92 の Web 開発新人研修の web アプリケーションのパートを担当した。
今読み返すとまだまだな部分が多いなと感じるが本当に良い経験になった。

発表

社外で何か発表したということはなかった気がする。
社内では幾つか発表してた。

今年は社内、社外含めて幾つか声を掛けて貰ったりしてるので頑張っていく気持ち。

その他

お見合い

面白年賀状をもらった


読書

技術書 20 冊
ビジネス書(?) 5 冊
数学関連 2 冊

記憶にあるのだけでこんなもん。
本は実物を持っていたい + 実物をさらっと眺めて買いたいという謎のこだわりがあるので
Amazon とかに購入履歴があまり残ってないので把握できないのが辛いところ

あと、本読む速度が遅いので速読スキルが欲しい...

旅行

30 手前で初の一人旅をした。
行き先は京都だったのだが同僚が京都の便利情報を次々教えてくれて便利だった。
歩き疲れたけどめっちゃ楽しかったので、また旅したい。

ちなみにこの旅の為にカメラ買った。

運動

ほぼ毎週スポーツをしているし、ジムにも週 2,3 行っているが今年は週 2, 3 いけない週が結構あったなぁという記憶
忙しかろうが強い意志で週 2 は行きたい。

健康

5 月頭、8 月中旬、 11 月末と 3 ヶ月 + 1 週間くらいの周期で急性腸炎になってて辛い感じ...
真剣に健康について考えていこうという気持ちになった。

ペパボに転職して 1 年経ってた

はじめに

転職から 1 年経っていたのでペパボに入って何してたとか、
思ったことを書いていく。

転職した経緯は下の記事に書いてあります。

shiro-16.hatenablog.com

なにしてたの?

  • EC で 2 ヶ月だけカートの開発してた
  • minne で API 開発することになった
  • 検索のあれこれをやることになった
  • 本に記事を書いた
  • お見合いした
  • API チームのテクニカルリードになった
  • シニアエンジニアになった

ざっくりという感じ(他にもあるけど)

EC で 2 ヶ月だけカートの開発してた

EC 事業の求人に応募して採用されたので、EC 事業で働き始めた。
なぜ 2 ヶ月だけかというと社内で minne というサービスの API 開発者を募集していたので応募して通ったから。

2 ヶ月で応募するということで、悩みはしたのですよ。
EC 事業の求人に応募して採用されたので申し訳ないなとか、入社 2 ヶ月で異動ってとかその他いろいろ
申し訳ないなというのは本当に思っている

でも、単純に面白そうだなって思ったので面白そうだと思ったらとりあえず一回やってみるという考えで生きてるのと
アプリに関わる開発から離れてみてやっぱりそっちが自分には合ってるのかなという考えから。(別に EC の仕事がつまらなかったとかでは全然ない)

minne で API 開発することになった

ということで minne の API 開発することになり、minne チームは当時はフロアが違ったり、福岡と一緒に開発を行っているということもあり独特な雰囲気があったという気がしている。

  • hsbt さんと仕事で絡む機会が大幅に増えた
  • class 設計の知識が大幅に向上した(気がしている)
  • web アプリケーション開発以外の面白いと思えるものが見つかった
  • 目標にするべき人と仕事が出来ている

他にも多々あるが上記の理由から結果的に minne に来て正解だったなと思った。

hsbt さんと仕事で絡む機会が大幅に増えた

これは説明する必要もないのだが、自分自身がペパボに転職した理由の 1 つだったので単純に嬉しいという感じ

class 設計の知識が大幅に向上した(気がしている)

レビュー等を通して class 設計だったり綺麗なコードのとは?とか、それに対して妥協しない姿勢というものを身につけることができた。
今までも出来ていたつもりでいたが、ワンランク上のステージでそういうのを考えられるようになった気がする。

既にペパボを退職してしまった人だが、その方にそういうことに関して感心させられることが多々ありその人みたいになりたいと思ったこと。
その人が退職するということを知った日から出来る限り盗めるところは盗もうと思い行動する(コードを書く)ようになった。
あわせて年末にリファクタリングの本を読みながらコード書いてたのもよかった点かなと思う。

※あくまで個人の感想です。

web アプリケーション開発以外の面白いと思えるものが見つかった

これは後述する、検索のこととか画像のこととか
web アプリケーションの一部といえば一部なのだが…

目標にするべき人と仕事が出来ている

class 設計の知識が...で書いた方の他にも、今目標にしている人がいるのだが
自分の場合目標にする人が近くにいる方がやる気が出るっぽい。

目標にするというか、開発が好きだから負けたくない人、勝ちたい人といった方が良いのかもしれない。

検索のあれこれをやることになった

minne の検索をいい感じにするみたいな話になった時に、面白そうだなって思ったのでやってみたいと手を挙げたのが始まり。
ペパボは手を挙げればやらせて貰える環境なのでとても良い。
日本語って難しいなとか思いながら、いい感じの検索とは?みたいなのを日々やっていて凄く難しいと思う反面凄く楽しいなと思いながら開発している。

その一環で画像を解析して物体を抽出してその色を判別するみたいなことをやって色検索をリリースすることが出来た。
画像を解析するのも楽しいなと思い始めた。

ここら辺は結構ネタを持っているので、どこかで発表したいと思っている。

本に記事を書いた

shiro-16.hatenablog.com

上記参照

今年の目標の一つ言語化を頑張るという自分が苦手としていることに挑戦するいい機会だと思った。
自分の頭の中で理解している技術的なことを他人が理解出来る言語にするのはとても難しいというかとても苦手なので、
出来るだけがんばっていこうというのを目標の一つにしていて日々の業務で作成している PR や issue 等でも言語化することに気をつけて日本語を書くようにしている。
そういう意味でも記事を書けたことはとても勉強になることが多かったし、みんなこんな感じで記事をかいてるのかぁなるほどとなれたのはよかった。

お見合いした

haken.inte.co.jp

面白そうだと思ったのでやった(強制されたとかは無い)

API チームのテクニカルリードになった

API の開発を行う人が増えてテクニカルリードというものをやることになった。
テクニカルリードはこちらの記事が参考になりそう。
とりあえず頑張っているという気持ち

シニアエンジニアになった

ペパボの職位制度に関してはここらへん
シニアになって思うのはペパボのいるだけで成長できる環境というのはその通りだと中の人として思うのだが、
シニア以上になる人はそれだけでは満足せずに自分から成長する為の何かを取りに行くことが出来る人なのかなと思う。

自分の場合は検索周りのこととか上に書いてないことも面白そうだからやってみるかという思いから取りにいって、
一定の成果を出し、終わってみたら成長を感じられたということが多く結果としてシニアになれたのでシニアになる為にとかではないのだが…

※あくまで個人の感想です。

でこれがシニアエンジニアになった際の抱負(?)
シニアの面談のフィードバックであんちぽさんに頂いたノリが良いっていうのは個人的にとても気に入っている。

やっておきますというのはタイポとかではなく、今までだと「いい感じによろしく」と言われてからの「やります!」という返事だったのを、
これからは「いい感じによろしく」と言われた際に「やっておきました!」と言える機会を増やすという意味での(言われる前に先に)やっておきますという意味です。

ということで頑張ります。

さいごに

ということで約 1 年何やってたかというのとペパボで働いて感じたことを書いてみた。
優秀な人が多くて毎日楽しく開発出来るという環境なので最高かという気持ち


最後に自戒の念を込めて貼っておきます…

MySQL の binlog について調べたメモ

MySQL の binlog について

実際に実行された更新系クエリの情報が記述されていてなんらかの理由によりデータが壊れた際の
データ復旧とかにも役にたつ。

binlog の format には以下の 3 種類ある

フォーマットの種類 設定値(文字列) 設定値(数字) 備考
ステートメントベース STATEMENT 1 実際に実行された SQL を記録
行ベース ROW 2 実際に変更された行のデータの情報を記録
ミックス MIXED 0 基本的にはステートメントベースと同じで非決定性のクエリの際は行ベースと同じ形式のログを出力する

ここら辺は DB server を構築する際にレプリケーションとかを考えると思うので
基本的には理解している内容だと思われます。

今回は binlog の中身を除いて実際にどうなってるの?というところを調べた。

実際にログを出力させて比べる

環境
my.cnf

my.cnf を変更して binlog を出力するようにする

[mysqld]
log_bin
binlog_format = 1 # ステートメントベースのログを出力する
table

今回は下記の table を使用する

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
使用する SQL
INSERT INTO users SET name = UUID(), created_at = NOW(), updated_at = NOW(); # 非決定性のクエリ
INSERT INTO users SET name = "test", created_at = NOW(), updated_at = NOW();

ステートメントベース

$ mysqlbin mysql-bin.000001
# 一部抜粋
BEGIN
/*!*/;
# at 247
# at 279
#160612 14:56:46 server id 1  end_log_pos 279 CRC32 0xc624c39f 	Intvar
SET INSERT_ID=20/*!*/;
#160612 14:56:46 server id 1  end_log_pos 476 CRC32 0x6a52b700 	Query	thread_id=1	exec_time=0	error_code=0
use `db`/*!*/;
SET TIMESTAMP=1465711006/*!*/;
INSERT INTO users SET name = UUID(), created_at = NOW(), updated_at = NOW()
/*!*/;
# at 476
#160612 14:56:46 server id 1  end_log_pos 507 CRC32 0xf803a15e 	Xid = 21
COMMIT/*!*/;
# at 507
#160612 14:56:53 server id 1  end_log_pos 634 CRC32 0xd617f39d 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711013/*!*/;
BEGIN
/*!*/;
# at 634
# at 666
#160612 14:56:53 server id 1  end_log_pos 666 CRC32 0xe6f7f9d2 	Intvar
SET INSERT_ID=21/*!*/;
#160612 14:56:53 server id 1  end_log_pos 863 CRC32 0x765b9f4d 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711013/*!*/;
INSERT INTO users SET name = "test", created_at = NOW(), updated_at = NOW()
/*!*/;
# at 863
#160612 14:56:53 server id 1  end_log_pos 894 CRC32 0x828b94cf 	Xid = 22
COMMIT/*!*/;

確かに発行された SQL がそのまま出力されている

行ベース

$ mysqlbin mysql-bin.000002
# 一部抜粋
BEGIN
/*!*/;
# at 220
#160612 14:58:55 server id 1  end_log_pos 295 CRC32 0xa71dbfff 	Table_map: `db`.`users` mapped to number 83
# at 295
#160612 14:58:55 server id 1  end_log_pos 383 CRC32 0xb2425e19 	Write_rows: table id 83 flags: STMT_END_F

BINLOG '
H/pcVxMBAAAASwAAACcBAAAAAFMAAAAAAAEAGGJsb2dfc2FtcGxlc19kZXZlbG9wbWVudAAFdXNl
cnMABAMPEhIE/QIAAAL/vx2n
H/pcVx4BAAAAWAAAAH8BAAAAAFMAAAAAAAEAAgAE//AWAAAAJABiZjYwNTc0MC0zMDYyLTExZTYt
OGQ2Zi0yZjg2MTFjNWE2ZjGZmZjut5mZmO63GV5Csg==
'/*!*/;
# at 383
#160612 14:58:55 server id 1  end_log_pos 414 CRC32 0xf290e6c8 	Xid = 21
COMMIT/*!*/;
# at 414
#160612 14:58:57 server id 1  end_log_pos 514 CRC32 0xc1908135 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711137/*!*/;
BEGIN
/*!*/;
# at 514
#160612 14:58:57 server id 1  end_log_pos 589 CRC32 0x96559f32 	Table_map: `db`.`users` mapped to number 83
# at 589
#160612 14:58:57 server id 1  end_log_pos 645 CRC32 0x56be64d2 	Write_rows: table id 83 flags: STMT_END_F

BINLOG '
IfpcVxMBAAAASwAAAE0CAAAAAFMAAAAAAAEAGGJsb2dfc2FtcGxlc19kZXZlbG9wbWVudAAFdXNl
cnMABAMPEhIE/QIAAAIyn1WW
IfpcVx4BAAAAOAAAAIUCAAAAAFMAAAAAAAEAAgAE//AXAAAABAB0ZXN0mZmY7rmZmZjuudJkvlY=
'/*!*/;
# at 645
#160612 14:58:57 server id 1  end_log_pos 676 CRC32 0x24726578 	Xid = 22
COMMIT/*!*/;

な、なるほどわからん
もっと詳しく見れるようにオプションを追加する

$ mysqlbinlog -vvv --base64-output=DECODE-ROWS mysql-bin.000002
# 一部抜粋
BEGIN
/*!*/;
# at 220
#160612 14:58:55 server id 1  end_log_pos 295 CRC32 0xa71dbfff 	Table_map: `db`.`users` mapped to number 83
# at 295
#160612 14:58:55 server id 1  end_log_pos 383 CRC32 0xb2425e19 	Write_rows: table id 83 flags: STMT_END_F
### INSERT INTO `db`.`users`
### SET
###   @1=22 /* INT meta=0 nullable=0 is_null=0 */
###   @2='bf605740-3062-11e6-8d6f-2f8611c5a6f1' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @3='2016-06-12 14:58:55' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
###   @4='2016-06-12 14:58:55' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 383
#160612 14:58:55 server id 1  end_log_pos 414 CRC32 0xf290e6c8 	Xid = 21
COMMIT/*!*/;
# at 414
#160612 14:58:57 server id 1  end_log_pos 514 CRC32 0xc1908135 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711137/*!*/;
BEGIN
/*!*/;
# at 514
#160612 14:58:57 server id 1  end_log_pos 589 CRC32 0x96559f32 	Table_map: `db`.`users` mapped to number 83
# at 589
#160612 14:58:57 server id 1  end_log_pos 645 CRC32 0x56be64d2 	Write_rows: table id 83 flags: STMT_END_F
### INSERT INTO `db`.`users`
### SET
###   @1=23 /* INT meta=0 nullable=0 is_null=0 */
###   @2='test' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @3='2016-06-12 14:58:57' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
###   @4='2016-06-12 14:58:57' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 645
#160612 14:58:57 server id 1  end_log_pos 676 CRC32 0x24726578 	Xid = 22
COMMIT/*!*/;

column 名が書かれているわけではなく @1 とか書かれてあるのだなぁ。
定義した table の column の順番通り @1 = id, @2 = name, @3 = created_at, @4 = updated_at という順番っぽい
UUID() も展開後の文字列が入っているのがわかる。

ミックス

$ mysqlbin mysql-bin.000003
# 一部抜粋
BEGIN
/*!*/;
# at 220
#160612 15:05:14 server id 1  end_log_pos 295 CRC32 0x3b4cb14b 	Table_map: `db`.`users` mapped to number 83
# at 295
#160612 15:05:14 server id 1  end_log_pos 383 CRC32 0x9905bb6a 	Write_rows: table id 83 flags: STMT_END_F

BINLOG '
mvtcVxMBAAAASwAAACcBAAAAAFMAAAAAAAEAGGJsb2dfc2FtcGxlc19kZXZlbG9wbWVudAAFdXNl
cnMABAMPEhIE/QIAAAJLsUw7
mvtcVx4BAAAAWAAAAH8BAAAAAFMAAAAAAAEAAgAE//AYAAAAJABhMTY1OWFmNi0zMDYzLTExZTYt
OTc1Yi1hZjExNDczMDFkMDGZmZjxTpmZmPFOarsFmQ==
'/*!*/;
# at 383
#160612 15:05:14 server id 1  end_log_pos 414 CRC32 0x84766030 	Xid = 21
COMMIT/*!*/;
# at 414
#160612 15:05:16 server id 1  end_log_pos 541 CRC32 0xe4c9b7a8 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711516/*!*/;
BEGIN
/*!*/;
# at 541
# at 573
#160612 15:05:16 server id 1  end_log_pos 573 CRC32 0x10f97ca5 	Intvar
SET INSERT_ID=25/*!*/;
#160612 15:05:16 server id 1  end_log_pos 770 CRC32 0xd9adc7e3 	Query	thread_id=1	exec_time=0	error_code=0
use `db`/*!*/;
SET TIMESTAMP=1465711516/*!*/;
INSERT INTO users SET name = "test", created_at = NOW(), updated_at = NOW()
/*!*/;
# at 770
#160612 15:05:16 server id 1  end_log_pos 801 CRC32 0xa8cd90ff 	Xid = 22
COMMIT/*!*/;

本当にミックスされている
もっと詳しく見てみる

$ mysqlbinlog -vvv --base64-output=DECODE-ROWS mac-no-MacBook-Pro-bin.000003
# 一部抜粋
BEGIN
/*!*/;
# at 220
#160612 15:05:14 server id 1  end_log_pos 295 CRC32 0x3b4cb14b 	Table_map: `db`.`users` mapped to number 83
# at 295
#160612 15:05:14 server id 1  end_log_pos 383 CRC32 0x9905bb6a 	Write_rows: table id 83 flags: STMT_END_F
### INSERT INTO `db`.`users`
### SET
###   @1=24 /* INT meta=0 nullable=0 is_null=0 */
###   @2='a1659af6-3063-11e6-975b-af1147301d01' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @3='2016-06-12 15:05:14' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
###   @4='2016-06-12 15:05:14' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 383
#160612 15:05:14 server id 1  end_log_pos 414 CRC32 0x84766030 	Xid = 21
COMMIT/*!*/;
# at 414
#160612 15:05:16 server id 1  end_log_pos 541 CRC32 0xe4c9b7a8 	Query	thread_id=1	exec_time=0	error_code=0
SET TIMESTAMP=1465711516/*!*/;
BEGIN
/*!*/;
# at 541
# at 573
#160612 15:05:16 server id 1  end_log_pos 573 CRC32 0x10f97ca5 	Intvar
SET INSERT_ID=25/*!*/;
#160612 15:05:16 server id 1  end_log_pos 770 CRC32 0xd9adc7e3 	Query	thread_id=1	exec_time=0	error_code=0
use `db`/*!*/;
SET TIMESTAMP=1465711516/*!*/;
INSERT INTO users SET name = "test", created_at = NOW(), updated_at = NOW()
/*!*/;
# at 770
#160612 15:05:16 server id 1  end_log_pos 801 CRC32 0xa8cd90ff 	Xid = 22
COMMIT/*!*/;

非決定性のクエリの際は行ベースと同じ形式のログを出力することがわかった。

mysqlbinlog コマンドのオプション + SQL

よく使いそうなオプションをまとめる

$ mysqlbinlog -h host --read-from-remote-server mysql-bin.000001 # リモートサーバの binlog を見ることができる
$ mysqlbinlog --start-datetime="2016-01-01 00:00:00" --stop-datetime="2016-01-01 12:00:00" mysql-bin.000001 # 日時を指定して binlog を見ることができる

binlog 情報を出力してくれる SQL をまとめる

mysql> SHOW GLOBAL VARIABLES LIKE 'binlog_format'; # binlog format を表示
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+

mysql> SHOW BINARY LOGS; # server の binlog 一覧を表示
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       531 |
| mysql-bin.000002 |       437 |
| mysql-bin.000003 |       933 |
+------------------+-----------+

mysql> SHOW BINLOG EVENTS; # binlog 内のイベントを表示
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                                                                   |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------+
| mysql-bin.000001 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.27-log, Binlog ver: 4                                                  |
| mysql-bin.000001 | 120 | Query       |         1 |         247 | BEGIN                                                                                  |
| mysql-bin.000001 | 247 | Intvar      |         1 |         279 | INSERT_ID=16                                                                           |
| mysql-bin.000001 | 279 | Query       |         1 |         477 | use `db`; insert into users  set name = UUID(), created_at = NOW(), updated_at = NOW() |
| mysql-bin.000001 | 477 | Xid         |         1 |         508 | COMMIT /* xid=24 */                                                                    |
| mysql-bin.000001 | 508 | Stop        |         1 |         531 |                                                                                        |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------+

最後に

ということで今回は MySQL の binlog についての format による違いを確認してみました。
binlog にどのような情報が記述されているか最低限覚えておくと
ここぞという時に役に立つかと思います