SQLシリーズ
データベース学習その1 データベース入門: https://blog.yexca.net/ja/archives/86
データベース学習その2 リレーションモデル: https://blog.yexca.net/ja/archives/87
データベース学習その3 SQL言語: https://blog.yexca.net/ja/archives/88
データベース学習その4 リレーショナルデータベース理論: https://blog.yexca.net/ja/archives/89
データベース学習その5 正規形: https://blog.yexca.net/ja/archives/90
データベース学習その6 データベース設計: https://blog.yexca.net/ja/archives/91
データベース学習その7 データベースの制御機能: この記事
トランザクション管理
トランザクションって、一連の操作のことで、「全部やるか、何もやらないか」っていうものなんだ。
トランザクションとプログラムは別物で、通常、一つのプログラムが複数のトランザクションを含んでることもあるよ。
SQL言語では、トランザクションを定義するステートメントは次の3つがあるんだ。
| |
トランザクションはACID特性っていうのを持ってて、原子性 (Atomicity)、一貫性 (Consistency)、独立性 (Isolation)、永続性 (Durability) があるんだ。
- 1 原子性
トランザクションはアトミックだから、全部やるか、何もやらないか、どっちかなんだ。
- 2 一貫性
トランザクションを実行した結果、データベースは必ず一貫性のある状態から別の、一貫性のある状態に変わるようにしないといけないよ。
だから、データベースに成功したトランザクションのコミット結果だけが含まれてるとき、データベースは一貫性のある状態だっていうんだ。
- 3 独立性
トランザクションは互いに独立してるんだ。
複数のトランザクションが同時に実行されるとき、あるトランザクションの更新操作は、それが正常にコミットされるまでの間、他のトランザクションからは見えないんだ。
- 4 永続性
トランザクションが一度成功してコミットされちゃえば、たとえデータベースがクラッシュしたとしても、そのデータベースへの更新操作はずっと有効だよ。
データベースのバックアップとリカバリ
データベースを運用していると、コンピューターシステムのソフトウェアやハードウェアの障害はどうしても避けられないよね。これらの障害はデータベースのデータの正確さに影響を与えたり、最悪データベースを破壊して、データの一部または全部を失わせることもあるんだ。だから、データベースの肝となる技術は、冗長データ、つまりバックアップデータを作ることだよ。システム障害が発生した後に、データベースを障害前の正しい状態に迅速に戻す方法、それがデータベースリカバリ技術なんだ。
障害の種類
データベースにおける4種類の障害
- 1 トランザクション内部障害
REDO(再実行)とUNDO(取り消し)技術を使うよ。
- 2 システム障害 (DBMS)
システムが突然停止しちゃって、再起動が必要になるケースだね。
- 3 メディア障害
ハードウェアの破損のこと。
- 4 コンピューターウイルス
バックアップ方法
リカバリの基本原理は「データ冗長性の構築」(重複保存)だよ。冗長データを作る方法としては、データダンプとログファイルの記録があるんだ。データダンプは、静的ダンプと動的ダンプ、全量ダンプと増分ダンプに分けられるし、ログファイルも重要だよ。
- 1 静的ダンプと動的ダンプ
静的ダンプは、ダンプ中にデータベースへのいかなるアクセスや変更操作も許さない方法だよ。
動的ダンプは、ダンプ中もデータベースへのアクセスや変更操作を許可する方法なんだ。
だから、ダンプとユーザーのトランザクションは並行して実行できるってことだね。
- 2 全量ダンプと増分ダンプ
全量ダンプは、毎回すべてのデータをダンプすることだよ。
増分ダンプは、前回ダンプされてから更新されたデータだけをダンプすることなんだ。
- 3 ログファイル
トランザクション処理の過程で、DBMS(データベース管理システム)は、トランザクションの開始、終了、そしてデータベースへの挿入、削除、変更といった一つ一つの操作をログファイルに書き込むんだ。もし障害が発生したら、DBMSのリカバリサブシステムはログファイルを使って、トランザクションによるデータベースの変更を取り消し、トランザクションの初期状態に戻すんだよ。だから、DBMSはログファイルを使ってトランザクション障害からのリカバリやシステム障害からのリカバリを行うし、バックアップコピーと連携してメディア障害からのリカバリも手助けできるんだ。
リカバリ
- トランザクションリカバリには次の3つのステップがあるよ。
- ファイルのログを逆方向にスキャンして(つまり、ログファイルを最後から前に向かってスキャンするってこと)、そのトランザクションの更新操作を探す。
- トランザクションの更新操作に対して逆操作を実行する。
- 引き続きログファイルを逆方向にスキャンして、そのトランザクションの他の更新操作を探し、同じ処理を行う。これをトランザクションの開始マークに到達するまで続けるんだ。
つまり、トランザクションが異常終了したら、それまでの操作を全部取り消すってことだね。
- システム障害からのリカバリ
まだ実行し終わってないトランザクションはUNDO、失われたトランザクションはREDOするんだ。
- メディア障害からのリカバリ
データベースを再ロードして、すでに完了したトランザクションを再実行するよ。
並行性制御
並行操作がもたらす問題
- 1 ロストアップデート(更新の消失)
僕が変更したものが反映されないんだ。例えば、ウェブサイトのロゴを変えたのに、元のままだったりとかね。
- 2 ファジーリード(再現不可能な読み取り)
一つのトランザクションの中で、連続して2回データを読んだのに、違うデータが返ってきちゃうこと。 例えば、最初に銀行の残高が10元だったとするよね。そのとき、会社から突然100元の給料が振り込まれたら、2回目に読んだときには110元になっちゃう、みたいな感じ。
- 3 ダーティリード(未コミット読み取り)
フィールドAとBを読み取りたいんだけど、読み取ろうとしたときに他のユーザーがそれらのフィールドを更新中だった場合。 もし、相手が更新の途中で(Aは更新済み、Bは更新中)僕が読み取っちゃったら、そのとき読み取ったデータはダーティデータって言われるんだ。
並行性制御技術
並行性制御の主な技術はロックだよ。基本的なロックのタイプには排他ロック(Xロックまたは書き込みロックって略す)と共有ロック(Sロックまたは読み取りロックって略す)があるんだ。
- 1 排他ロック
もしトランザクションTがデータオブジェクトAにXロックをかけたら、TだけがAを読み書きできて、他のトランザクションはTがAのロックを解放するまで、Aにどんな種類のロックもかけられなくなるんだ。
- 2 共有ロック
もしトランザクションTがデータオブジェクトAにSロックをかけたら、TだけがAを読み取れて、Aを変更することはできないんだ。他のトランザクションは、TがAのSロックを解放するまで、AにSロックをかけることしかできないよ。これで、他のトランザクションがAを読み取ることはできるけど、TがAのSロックを解放するまではAを何も変更できないことが保証されるんだね。
ロックプロトコル
- 一段ロックプロトコル(ロストアップデートを解決)
変更するときは、終了するまでXロックをかける必要があるよ。
- 二段ロックプロトコル(ダーティリードを解決)
読み取るときはSロックをかけて、使い終わったらすぐ解放する。
- 三段ロックプロトコル(ファジーリードを解決)
読み取るときはSロックをかけて、終了するまで解放しないんだ。
直列化可能性
色々な状況が考えられて、それから結果が得られると仮定するね。 もし並行実行の結果が、上の結果のどれか一つと同じであればOKなんだ。
トランザクションT1:Bを読み込み、A=B+1、Aを書き戻す トランザクションT2:Aを読み込み、B=A+1、Bを書き戻す
じゃあ、例えばT1が先に、次にT2が実行されたとすると、A=4、B=3になるね。 もしT2が先に、次にT1が実行されたとすると、A=3、B=4になるんだ。 この並行実行は直列化可能性を満たしてるよ。
分散データベース
- フラグメンテーション透過性
ユーザーやアプリケーションは、論理的にアクセスするテーブルが具体的にどうやって分割されて保存されてるかを知る必要がないんだ。
- レプリケーション透過性
レプリケーション技術を使った分散方法では、ユーザーはデータがどのノードに、どのように複製されてるかを知る必要がないよ。
- ロケーション透過性
ユーザーはデータが物理的にどこに保存されているかを知る必要がないんだ。
- 論理透過性
ユーザーやアプリケーションは、個々のサイトがどのデータモデルを使っているかを知る必要がないよ。
- 共有性
データが異なるノードに保存されていても、データを共有できること。
- 自律性
各ノードが自分のローカルデータを独立して管理できること。
- 可用性
あるサイトで障害が発生しても、システムは他のサイトにあるレプリカを使って、システム全体が停止することなく機能し続けられること。
- 分散性
データが異なるサイトに保存されていること。