#dbltokyo Database Lounge TOKYO #2 に参加してきたまとめ

公開日:  最終更新日:2016/09/13

Databaseの幅広い話題をお酒を飲みながらゆるく語るDatabase Lounge TOKYO #2に参加してきました。

その時のメモ、デッス!(最近流行りの司教風)

sponcer link

差分、増分、デルタ(って何?) バックアップあれやこれや

ホットバックアップのやり方あれこれ

  • mysqldump/mysqlpumpでInnoDBテーブルをとる
  • ロックを利用
    • mysqldump/mysqlpumpでMyISAMテーブルを取得
    • FirebirdのnBackup(しかし10年前の代物)
  • OSやハードウェアのスナップショットを利用
  • 独自の方法でバックアップを取得
  • MySQL Enterpirse Backupを利用

コールドバックアップのやり方

  • DBをとめてバックアップのファイルを取得するだけ

物理バックアップのやり方

  • OSファイルのコピー、MySQL Enterprise Backupで取得できる
  • 最小限のサイズで取得できるが、バージョン間で互換性がない可能性あり

論理バックアップのやり方

  • mysqldump / mysqlpumpで取得できる
  • 移植性が高いが、バックアップ・リストアに時間が掛かる

フルバックアップと差分増分バックアップ

  • フルバックアップは毎回全てをバックアップする
  • 差分バックアップはフルからとった後の差分のみを取得する
  • 増分バックアップはフルもしくは差分からの差分のみを取得する
  • IBM DB2では、一般的な増分バックアップをデルタ、一般的な差分バックアップを増分バックアップとよんでいる
  • MySQLでの差分増分はバイナリログを増分バックアップを用いる。Enterpriseを使うことで可能
  • ハードウェア・ソフトウェアと連携
    • 単純なファイルコピーならハードウェアの機能、もしくはソフトウェアにて超高速にバックアップできる場合がある
    • しかし、全体バックアップをとってみたら戻らなかったりすることもあるかもしれない(一貫性がない)
  • ログを代用した増分バックアップ
    • トランザクションログを保管して、直前のバックアップとを一貫性のあるものにしておくと増分バックアップとして適用することができる
    • 増分バックアップの時間をなくせるが、ロールフォワードの時間がとてもかかるので、注意
  • 差分バックアップの抽出方法として、順次操作して変更点を抽出する方法は規模に応じては時間がかかる

Postgresはグラフデータベースの夢を見るか?

Do postgres-dream-of-graph-database from Toshi Harada
  • グラフデータベースとは、データをノードと関連でつなぐ、NoSQLの一種
  • ポスグレの更新をNoe4jに反映してみた
  • ロジカルデコーディング:WALを任意形式に論理的に展開できる
    • JSONにできれば扱いやすい
    • wal2jsonというものを作ってる人がいた
  • Logideco4neo4jを作ってみた
    • LogicalDecodingを使ってneo4jにSQLを変換、発行する
  • demo: INSERTなどでデータを入れ、その後、リレーションをつなげると、グラフデータベースでグラフとして表現できていた
  • Foreign Data Wrapper
    • 以前作ったneo4j_fdwを使ってneo4jに検索クエリを投げる
    • demo: 3つのforeign tableを作成後、PostgreSQLからNeo4jのデータをSQLで検索できていた!

An intelligent storage?

An Intelligent Storage? from Kohei KaiGai
  • データはストレージにおいてあるが、それを処理するためにはCPUやRAMなどにロードしないといけないが、SSDからGPUにダイレクトに飛ばして処理させよう!
    • scanで90%くらいフィルタリングされるときに本体のRAMを使わなかったり、CPUが楽できたりする
  • nVIDIAからgpu RDMA Directというのが出ている
    • ディスクからとりだすときのDMAの宛先アドレスにできる
  • Linuxのカーネルドライバを書いてうまい具合にSSDから物理アドレスをマッピングできるよう作ってみました
    • それぐらいみんな書くでしょ? (!!!)
  • しかし、制限としてOSのキャッシュされてるファイルはCPUで転送しないといけないので遅い
  • パフォーマンス結果として、カタログスペック通りのI/Oが出ました
  • VFSのパフォーマンスも見たところ、VFSの制限で頭打ちになっている模様
  • 64Gのテーブルでレコード件数が7億をそれぞれのSQLでスキャンしてみた
    • CPUをバイパスしてGPUに送り込むことで、従来の性能限界を突破できた
  • CPUからみると、データをSSDが読みこみ後、計算はGPUが引き受けることで、あたかもストレージがSQLを理解して動作するかのように見える

ポスグレのバックアップでやらかした話(˚இ˚)

  • バックアップにまつわるバッドノウハウの紹介

Case1

  • PostgreSQLでは、バックアップとアーカイブファイル、walファイルを用いて障害発生の直前まで戻せます
  • あるサービスで使用しているスクリプトのお話
    • 仕様としては、バックアップモードにして、OSコマンドやストレージのスナップショットなどでバックアップしたあとにバックアップモードをやめる
    • バックアップを取得したらさらにバックアップサーバに転送し、終わったらローカルのファイルを削除していた
    • 実は別に論理バックアップも一緒にとっていました
  • ある日、お客様から電話がありアクセス出来ないとの連絡があった
    • 調べてみると、アーカイブ領域が溢れてポスグレが止まってしまった
    • リモートサーバの領域が不足していてバックアップの削除ができていなかった
  • アーカイブ領域がはけなくなると、walファイルをなるだけ循環させないでwalファイルを出来るだけ残し続ける。walが出力できなくなるとDBが止まる
  • アーカイブ領域の圧迫に気をつけましょう!

Case2

  • 論理バックアップをpd_dumpで取得後、vacuum fullとvacuumをやっていた
    • そもそもなんでバックアップでvacuumしてんだ・・・?!
    • 論理バックアップをとった後に物理バックアップをとっていた
  • vacuumをコメントアウトしてみた!
    • すると5分で帰ってきたサービスが2時間たって帰ってこずブラウザのタイムアウトをしてしまうという障害になった
    • →実はvacuumdb -zで実行していたのでANALYZEでした
  • 処理内容はちゃんと見ましょう!

バックアップと障害復旧から考えるOracle Database, MySQL, PostgreSQLの違い(仮)

バックアップと障害復旧から考えるOracle Database, MySQL, PostgreSQLの違い – Database Lounge Tokyo #2 from Ryota Watabe

一般的なRDBMSのバックアップと復旧の特徴について

  • リストア後にリカバリという2つのアクションをすることで障害直前に戻せます
  • リカバリがないとバックアップを取得した時点にしか戻せません

バックアップ周辺のアーキテクチャ

  • データを更新すると一旦キャッシュしています。更新記録はトランザクションログファイルに書き込まれます。
  • Oracleは、オンラインREDOログファイルを循環させてトランザクションを記録していきます
    • 循環して上書きされる前にアーカイブREDOログを出力して上書きできるようにしています
  • PostgreSQLの場合は、WALログファイルというものに書き込んでいるが、このWALファイルはどんどん順次書き込んでいる
  • MySQLはトランザクションログファイルはInnoDBログファイルとバイナリログファイルの2種類がある
    • バイナリログファイルはメディアリカバリに使われる。中身はSQLが書かれている。
    • 実は2層コミットでそれぞれ書き込んでいるだけです(@yoku0825様)

Oracleのバックアップとリストア

  • 更新処理を再実行するだけでなく、一貫性を回復するという側面がある
    • 一貫性も回復しないとオープンできます
  • 起動中のバックアップは一貫性が取れていないので一貫性をとれるようにしましょう

MySQLのバックアップとリストア

  • mysqldumpを取得する際には一貫性をもつバックアップを取得するようにする
    • –single-transactionなどのオプションを指定しないととれません
    • MySQL Enterprise BackupやPerconaのextrabackupを使えばOracleみたいなかたちでバックアップをとれる
    • InnoDBの場合は開始時点のスナップショットを使ってうまくとっていて、MyISAMの場合はロックをかけている
  • mysqldumpで戻した後はバイナリログファイルを使って戻す
    • リストアリカバリが終わったところがmysqldumpでやっている。
  • MySQLには一貫性を回復する機能がない
    • バイナリログファイルにはSQLが書かれているだけなので、SQLでできる範囲のことしかできない
  • –single-transactionオプションをつけると一貫性をもつバックアップをとれるが、そのあと、バイナリログを用いたリカバリではバイナリログファイルのポジションなどを用いて戻す。
    • GTIDがないと同じSQLが二度実行されてしまいます(@yoku0825様)
  • InnoDBログファイルの用途としてはプロセス障害などで障害が発生した時に、一貫性がないので、その時のクラッシュリカバリに使われます
    • 起動時にファイルの一貫性をチェックしていて自動的に復旧します
    • クラッシュしたらスレーブからコピーして使ったほうが安全

PostgreSQLのバックアップとリストア

  • バックアップモード設定中にOSコピーコマンドでバックアップを取得します
    • リカバリ処理ができるバックアップをベースバックアップと呼ばれる
  • WALファイルを用いて一貫性を回復できる

分離ブロック

  • 1つのブロックが一貫性をもっているかどうかのお話
  • 分離ブロックはブロックのIOとOSのIOで分かれてコピーしていることで発生する
  • PostgreSQLではWALファイルに更新のブロックを出力されるようになる。リカバリ時の分離ブロック修正に使用する
    • pg_startbackupを実行すると一時的にIOが増える
    • チェックポイントが発生するとブロック全体がwalファイルに書き込まれる(フルページライト)
  • Oracleの場合、rmanを用いればOracle専用のプロセスが立ち上がってコピーするので、分離ブロックの問題が発生しない。

パネルディスカッション

@wrcsus4様@yoku0825様@kasa_zip様@kumagi様によるパネルディスカッションです。

バックアップ方式は何が主流?フル、差分、増分バックアップはどうやってやる?それぞれのスパンは?

  • Oracleは物理バックアップが多い
    • 障害発生直前まで戻せない
  • MySQLはmysqldumpでやっていくが、リストアが追いつかなくなったら物理バックアップにいくが、最終的にインデックスのデータ量が大きい問題でmysqldumpに戻ってくるらしい
    • 大きさによって使うものが変わる
  • PostgresSQLは小さいとdumpだが、大きいとまた変わる
    • 大体最新まで戻したいので、直前まで戻す設計をすることが多い
    • サイズが小さくてもオンラインバックアップをしたいお客が多い
    • データが大きいとストレージスナップショットで終わらせることがある
    • スナップショットは重くないか?
      • 一瞬で終わるが性能は確かに遅くなる
    • RMANはストレージスナップショットに対応していない
  • 増分更新のバックアップ
  • バックアップの保存先はローカルに入れてからとあったが、ローカルに取るのが主流なのか?それともマウントした先にとるのが主流したなのか?
    • →設計の問題になると思われる。最新のものは手元に置くのが鉄板かと思われる

バックアップはどこからとるのが主流?種系?待機系?

  • OracleはPostgreSQLと同じなのでどちらも同じ
    • 主系のほうが最新のデータがあるのでそちらの方がいいとは思う
  • MySQLだと切断面で考えるのであまり遅れる時間は考えない
  • PostgreSQLだと主系・待機系ができたのが最近(5年位前)なのだが、しばらく待機系からとるのは難しかったので、主系からとるのが常套手段として定着していた。最近では待機系からもとれるので段々と待機系からとっていくのが増えていくのではないか
    • 待機系でsnapshotつかえるんでしたっけ?
      • 正当な手段としてはないが、裏技を使えばとれる
    • テープに書き込むのが最近早いので流行ってきている

PITRのリカバリポイント

  • PostgreSQLは最新版開発も含めると4つあって、時間を指定するのと、XIDを指定するのと、リストアポイントを指定するのと、LSNを指定するので4つある
    • XIDで指定した場合はトランザクションがコミットしたタイミングか?
      • そこを含むか含まないかの指定ができる
    • コミットされていないデータもダーティデータとして出力されるが、コミットされていなかったら不要とされる
  • MySQLはログポジションを指定して戻します
    • バイナリログに全て指定されているのでdropしたテーブルなどはそこを指定すれば戻せます
  • Oracleの場合はSCNとリストアポイント、名前などで戻せます
  • 戻した時にどこまで戻したかというのはわかるのか?
    • PostgresSQLは整合性があるところまで戻した後はベストエフォートで戻せるところまで戻すので、時間などはわからない
  • Oracleでリストアリカバリじゃなくてフラッシュバック機能で戻すことはあるか?
    • →夜間の例だとあまり使われることがないので基本的にはバックアップから戻します

1つのテーブルだけ戻したい時にどうするか

  • Oracleだとフラッシュバックドロップで戻せます。
    • 12cからだと表単位のリカバリで戻せます
  • MySQLは基本的に全部リストアする
  • PostgreSQLはないです
    • 手パッチ(ユーザーがINSERTなどを入力していく)でいくとはやいかも

テーブルがブロック破損した時はどうなる?そもそも検知できる仕組みはある?

  • OracleはRMANの機能でブロックメディアという機能で戻せます
    • ただし、EEのみです
  • MySQLはcheck tableをかけるとアサートせずになにか出してくれます
    • ただ全てなめるので時間はかかる
    • MySQL5.7からアサートせず警告だけ流す機能があったかもしれない
    • 復旧の仕組みはないです
    • MySQLには無理やりブロックをスキップして読み込む方法はある
  • PostgreSQLはテーブルがうまく壊れるとエラーでよめないと言われる
    • ブロックを無視するオプションがあるのでその他の部分をサルベージするのは可能
    • indexが論理的に大丈夫かと確認するツールはあるか?
      • checksumで検知するのは可能
      • pgstatなどのブロックを総なめするツールで気づけるかもしれない
    • 開発のものだとブロックレベルでできるものを作っている最中ではある
  • 学術界では、2013年にDBのクラッシュはユーザの都合で壊れるのと、OSレベルで壊れる、メディアレベルで壊れると3通りあったが、最近だとシングルページなどの問題が新たに増えている
    • MySQLではページ情報を持ってないからおそらくできない
  • ブロック破損はリードの時に発生すると思うが、ストレージスナップショットを使うとブロック破損を検知するタイミングがない、ブロック破損をしたものをずっととり続けてしまうと思われるが、それってどうなのか?
    • PostgreSQLはWALログはCRCで守られていて、破損したページは絆創膏みたいにはって救ってくれる
    • お客からスナップショットでとりたいといわれたが、ブロック破損に来づけるように、1周間に1回はDBの機能をつかって取るようにしています(質問者)
  • ログの二重化しているが、壊れるのか?
    • PostgreSQLで壊れるシーンはあまり見たことがない。
      • 9.5からリモートにもWALを出力できるようになった
      • しかしどっちかかけないと待ってしまう
    • 普通に考えたらリモートではなく、ローカルに書くのが常套だとは思われる

@mogmetの所感

ゆるくと銘打ってありましたが、発表の内容はガチのものばっかりで「ゆるく」の「ゆ」の字がかろうじて見えるくらいのゆるさでした。(もはやゆるくない)

また、@wrcsus4さんの発表からもう既にパネルディスカッションっぽくなっていて、中々スライドが進まないという感じのかつてないほど白熱した熱いソウルのぶつかり合いな勉強会でした。

個人的に印象に残った意見については以下が残りました。

次回はトランザクションについて開催されるらしいので、LT等応募されたい方は@ooyamams様、もしくは@sawada_masahiko様までご連絡するといいと思います!

  • このエントリーをはてなブックマークに追加
  • Pocket
PAGE TOP ↑