スナップショットアイソレーションの影響
SQL Anywhereデータベースにおいてスナップショットアイソレーションを可能にするには、次のようにallow_snapshot_isolation
オプションを設定します。
SET OPTION PUBLIC.allow_snapshot_isolation = 'On';
スナップショットアイソレーションを有効にすると、REFRESH MATERIALIZED VIEW
文のデフォルトの独立性レベル設定はWITH ISOLATION LEVEL SNAPSHOT
になります。そのため、このREFRESH
文を実行する接続は、対象マテリアライズドビューのベーステーブルを同時に変更しようとしている他の同時更新トランザクションによってブロックされることはありません。
これは利点ですが、トレードオフも存在します。トランザクションログには、どんな状態のバックアップに対してもこのログを使って正確にリカバリーできるように、データベースへの変更に関する十分に詳細な情報が含まれていなければなりません。REFRESH MATERIALIZED VIEW WITH ISOLATION LEVEL SNAPSHOT
文を使用した場合、この文は、基となるベーステーブルのローをスナップショットのセマンティクスに従って「見る」ことになります。言い換えると、このREFRESH
文は、REFRESH
文の開始後に行われたコミット済みトランザクションによって変更されたローを「見る」ことはできないということです。リカバリー時にこのREFRESH
文をトランザクションログから正しく再生するには、REFRESH
文がマテリアライズドビューの内容を正しく計算できるように、サーバが基となるすべてのベーステーブルのすべてのローの状態を保持している必要があります。
同様の現象は、REFRESH MATERIALIZED VIEW
文をSERIALIZABLE
、SHARE MODE、EXCLUSIVE MODE
以外の独立性レベルで実行したときにも起こりえます。必要なコンテキストのすべてをトランザクションログに提供しようとするよりも、REFRESH MATERIALIZED VIEW
文が比較的低い独立性レベルで実行されたときは、サーバは(REFRESH
文のみではなく)REFRESH
文とマテリアライズドビューに挿入された個々のローの両方をログに記録します。
この場合、DBTRANユーティリティによって生成されたSQL文を見ると、DBTRANの出力にはREFRESH MATERIALIZED VIEW
文しか含まれていないはずです。なぜなら、ログをSQLに変換して別のデータベースに適用する際にはREFRESH
文さえあれば十分だからです。しかしリカバリーの際には、サーバはこのREFRESH MATERIALIZED VIEW
文を無視して、ログ内の個々のINSERT
文を利用してマテリアライズドビューをリカバリーします。
現在、我々はDBTRANの機能強化を検討しており、このようなケースでログに記録されるINSERT
文をDBTRANの出力内にコメントとして出現させ、その存在を確認できるようにしようと考えています。