最小のダウンタイムで大きなテーブルにrowversion列を追加するにはどうすればよいですか


21

SQL Server 2008以降を使用して、rowversion列を大きなテーブルに追加したいのですが、単純に

ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL

その後、更新のためにテーブルが長すぎます。

このダウンタイムを減らすためにどのような戦略を使用できますか?何でも検討します。もちろん、単純であればあるほど良いのですが、どのような戦略も検討します。

私の考えでは、最後の手段として、トリガーによって維持されるコピーステージングテーブルを維持してから、ステージングテーブルを元のテーブルにsp_renameできると考えています。しかし、私はもっとシンプルで簡単なものを望んでいます。

回答:


26

同じスキーマにrowversion列を加えた新しいテーブルを作成し、すべてを結合する両方のテーブルの上にビューを追加することを検討してください。ユーザーにビューを使用してもらい、基盤となるテーブルとビューに対して、代わりにトリガーを作成します。

挿入は新しいテーブルに送信し、更新は新しいテーブルにデータを移動し、削除は両方のテーブルに適用する必要があります。

次に、バックグラウンドでバッチ移動を行い、一度にできるだけ多くのレコードを新しいテーブルに移動します。これが行われている間は並行性の問題が発生する可能性があり、いくつかの非常に厳しい実行計画がありますが、移動中もオンラインを維持できます。

理想的には、エンドユーザーへの影響を最小限に抑えるために金曜日の午後にプロセスを開始し、月曜日の朝までに完了させようとします。配置が完了したら、ビューを変更して新しいテーブルのみを指すようにできます。これにより、非常に厳しい実行計画がなくなります。理想的には。

データがバッチで移行されるときにトリガーが起動しないようにするには、トリガーで削除/挿入されたテーブルの行数を調べ、バッチの行数に近い場合はアクティビティをスキップします。


最終的に、Michaelは、より安定した計画を得るために、ビューをスキップすることを決定しました(元のテーブルからは削除しません)。トレードオフは、基本的にテーブルの2つのコピーを保持していました。彼はそれを一連のブログ投稿に変えました。


7

前もって計画する時間があれば、もっと簡単な解決策があります...(通常)

長いロックは、ほとんどの場合、ストレージレイヤーでのページ分割が原因です。自分のスケジュールでそれらを強制します。

  1. datatypeのNULL可能な一時列を追加しますVARBINARY(8)
  2. データベースで利用可能な余裕時間を見つけて、既存のレコードのバッチをフィールドの有効な値で更新します。(0x0000000027F95A5B例)
  3. 更新により、必要なページ分割が強制され、テーブルにより多くのスペースが割り当てられます。
  4. 追いついたら、一時列をドロップし(割り当てられたストレージに触れない)、rowversion列を追加します。
  5. ページ分割はなく、値を設定するのに必要なだけのロックが必要です。

これを使用して、10分以内に1億5000万行の行テーブルにrowversion列を追加しました。

警告...大きなvarcharフィールドを持つテーブルがある場合(特にvarchar(max))、SQL Serverは新しく利用可能なスペースを再利用する代わりにテーブルを再構築することを決定します。まだその回避方法を見つけようとしています。


興味深いことに、質問では「長すぎる」の意味を指定しなかったと思います。30分を超えるとシナリオには長すぎ、10分は許容できる場合、このソリューションは機能します。私のシナリオでは、ダウンタイムをゼロにすること、または具体的には10秒未満を実現しようとしましたが、これはブレントの答えによって達成されました。
マイケルJスワット

1

TIMESTAMPを追加する場合NULLABLE

  1. VARBINARY(8)列を追加する
  2. データを入力します。

それが追加された後、背中合わせのSQLステートメントでDROPVARBINARY(8)追加して追加したTIMESTAMP NULL列を追加し、列を追加します。


TIMESTAMPを追加する場合NOT NULLABLE

  1. BINARY(8)列を追加する
  2. データを入力します。

連続してSQLステートメントを追加した後、追加して追加しDROPBINARY(8)列とADD THE TIMESTAMP NOT NULL列。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.