web-dev-qa-db-ja.com

SQL Serverの再起動時にID値がジャンプする

SQL Server 2008 R2からSQL Server 2012に切り替えました。ID列に問題があります。

SQL Serverを再起動すると、各ID列のシード値が1000ずつ増加します(int ID列の場合は1000、bigintの場合は10,000です)。たとえば、テーブルの次のint ID値が3の場合、SQL Serverを再起動すると1003になります。SQLServerを再起動すると、2003などになります。

Googleを検索したところ、SQL Server 2012の新機能(使用方法がわからない)であることがわかりました。古いIDの動作が必要な場合は、2つのソリューションしかありません。

  1. シーケンスオブジェクトを使用する

    これは私には不可能です:

    a)SQL Server 2008と2012で同じデータベースを使用しています。2008ではシーケンスを使用できません。

    b)シーケンスを使用する場合、各テーブルの保存手順を変更する必要があります。これは、私たちにとってかさばる作業です。

  2. トレースフラグ272を使用(-T272)

    アプリケーションに変更を加える必要がないため、このソリューションを使用できます。このSQL Server IDが以前のバージョンと同じように機能するようになった後、誰かが-T272を起動パラメータとして追加することを提案しました。私は同じことをしましたが、うまくいきません。

データベース構造に変更を加えたくありません。解決策を提案するか、-T272が機能しない理由を説明してください。

6

私はそれが新しい機能であることを発見しました(それの用途がわからない)

SQL Server 2012より前のバージョンでは、ID割り当ては常に個別にログに記録されていました(各値が使用されたため)。この行ごとのロギングアクティビティは、多くのID値が短時間で生成されるシナリオでスループットを制限する可能性があります。効率を向上させるために、SQL Server 2012以降では、ID値のbatchの割り当てのみがログに記録されます。割り当てられた範囲はキャッシュされ、値の新しいバッチが必要になるまでオンデマンドで発行されます。

アイデンティティオブジェクトを含むデータベースがシャットダウン時にチェックポイントされないままSQL Serverを再起動すると、キャッシュされた範囲内の残りの未使用の値は失われ、再起動時に値が急激に増加します。

残念ながら、SQL Server 2012をシャットダウンする一般的な方法では、現在データベースを自動的にチェックポイントしません(これはドキュメントに矛盾するため、将来的に修正する必要があります)。 SQL Server 2012で割り当てられたID値のジャンプのこの特定の原因を回避するには、alwaysT-SQLを使用してSQL ServerをシャットダウンしますコマンドSHUTDOWNNOWAITオプションなし)。

SHUTDOWNコマンドは、サーバーをシャットダウンする前にすべてのユーザーデータベースを正しくチェックポイントします。 Windowsサービスコントロールアプリケーション、SQL Server構成マネージャー、SQL Server Management Studio UI、またはその他の方法を使用しないでください

他の方法を使用してSQL Serverをシャットダウンする前に、すべてのデータベースを手動でCHECKPOINTすることもできますが、これには、チェックポイントの後、シャットダウンが完了する前に、データベースでID割り当てアクティビティが発生しないことを確認する必要があります。これを確実に達成することは容易ではないかもしれません。

詳細と背景 Lost Identity by Kalen Delaney.


トレースフラグ272が DBCC TRACEON-トレースフラグ(Transact-SQL) に記載されています。

サーバーが予期せず再起動したり、セカンダリサーバーにフェールオーバーしたりする場合に、IDの事前割り当てを無効にして、ID列の値のギャップを回避します。 IDキャッシングは、ID列を持つテーブルでのINSERTパフォーマンスを向上させるために使用されることに注意してください。

注:SQL Server 2017以降、データベースレベルでこれを行うには、 ALTER DATABASE SCOPED CONFIGURATION(Transact- SQL)

スコープ:グローバルのみ

12
Paul White 9