本番環境からテストデータベース内のいくつかのテーブルのみを更新する最良の方法は何ですか?


12

SQL Server 2008R2には、非常に大規模な運用データベースと非常に大規模なテスト環境データベースがあります。両方のデータベースのテーブル構造は似ていますが、ユーザー/ログイン/権限/ロールが異なります。

テストデータベース内のいくつかのテーブルだけを月に1回程度、実稼働から定期的に更新する必要があります。

私がこれを行うことを計画している現在の方法は

  1. BCPユーティリティを使用して、本番から必要なテーブルのエクスポートを取得します。
  2. bcpエクスポートファイルをテストサーバーにコピーします
  3. テストで更新しているすべてのテーブルのインデックスと制約を無効にします
  4. テストデータベーステーブルを切り捨てる
  5. BCPを使用して、テストデータベーステーブルにデータをロードし直します。
  6. テストでインデックスを再構築し、制約を再度有効にします

これはすべて、このような小さなタスクには少し複雑すぎるようです。また、多くのやり直しが生成されるようです(t-logで)これを行うより良い方法はありますか?

私がこれを行う別の方法は、実稼働環境からテスト環境にバックアップを復元することですが、私が抱えている問題は、完全バックアップが非常に大きくなり、すべてのテーブルを更新する必要がなく、数回だけ更新する必要があることです- -また、運用データベースのユーザーとセキュリティはテストとは異なります。データベース全体を復元すると、運用データベースのセキュリティ設定によって上書きされます。


回答:


4

ニーズに合った2つの方法があります。

(注:テーブルが外部キーによって参照されている場合、使用できませんTRUNCATEチャンク単位で削除する必要があります。または、すべてのインデックス+外部キーを削除してデータをロードし、再作成できます)。

  • BCP OUTおよびBULK INSERT INTO宛先データベース

    • テストデータベースを単純/一括ログ復旧モードに設定してください。
    • トレースフラグ610の有効化-インデックス付きテーブルへの挿入を最小限に記録します。

      /************************************************************************************************************************************************
      Author      :   KIN SHAH    *********************************************************************************************************************
      Purpose     :   Move data from one server to another*********************************************************************************************
      DATE        :   05-28-2013  *********************************************************************************************************************
      Version     :   1.0.0   *************************************************************************************************************************
      RDBMS       :   MS SQL Server 2008R2 and 2012   *************************************************************************************************
      *************************************************************************************************************************************************/
      
      -- save below output in a bat file by executing below in SSMS in TEXT mode
      -- clean up: create a bat file with this command --> del D:\BCP_OUT\*.dat 
      
      select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" '-- path to BCP.exe
              +  QUOTENAME(DB_NAME())+ '.'                                    -- Current Database
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
              +  QUOTENAME(name)  
              +  ' out D:\BCP_OUT\'                                           -- Path where BCP out files will be stored
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
              +  REPLACE(name,' ','') 
              + '.dat -T -E -SSERVERNAME\INSTANCE -n'                         -- ServerName, -E will take care of Identity, -n is for Native Format
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'                       -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'                     -- Optional to exclude any schema 
      order by schema_name(schema_id)                         
      
      
      
      --- Execute this on the destination server.database from SSMS.
      --- Make sure the change the @Destdbname and the bcp out path as per your environment.
      
      declare @Destdbname sysname
      set @Destdbname = 'destination_database_Name'               -- Destination Database Name where you want to Bulk Insert in
      select 'BULK INSERT '                                       -- Remember Tables **must** be present on destination Database
              +  QUOTENAME(@Destdbname)+ '.'
              +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.' 
              +  QUOTENAME(name) 
              + ' from ''D:\BCP_OUT\'                             -- Change here for bcp out path
              +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
              +  REPLACE(name,' ','') 
              +'.dat'' 
              with (
              KEEPIDENTITY,
              DATAFILETYPE = ''native'',  
              TABLOCK
              )'  + char(10) 
              + 'print ''Bulk insert for '+REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'+  REPLACE(name,' ','')+' is done... '''+ char(10)+'go' 
      from sys.tables
      where is_ms_shipped = 0 and name <> 'sysdiagrams'           -- sysdiagrams is classified my MS as UserTable and we dont want it
      and schema_name(schema_id) <> 'some_schema_exclude'         -- Optional to exclude any schema 
      order by schema_name(schema_id)
      

-

  • 方法2:SSIS-この場合の私の好みの方法。

    • ディスクへのステージングは​​必要ありません。すべての処理はメモリ内で行われます。
    • SQLエージェントジョブを使用して毎月SSISパッケージをスケジュールし、PRODからTESTサーバーへのテーブルの更新を自動化できます。
    • 高速ロード」オプションを選択します
    • バッチ番号ごとに適切な行を選択していることを確認してください(選択する値が大きすぎると、ロックのエスカレーションが発生します-5K未満に抑えてください)

参照:データロードパフォーマンスガイド、テーブルへの挿入の選択*テーブルからの挿入と一括挿入


1
SSISは間違いなくここに行く方法です。データポンピングは、そのために設計されたものです。
スティーブMangiameli

3

バックアップや復元を行ったり、外部プロセス(BCPなど)を呼び出したり調整したり、SSISを台無しにしたりする必要はありません(非常に強力で、非常にクールですが、回避できれば、間違いなく:)。T-SQLの快適さから、SQLエージェントを介してスケジュールできるストアドプロシージャ、または月に1回実行するスクリプトで、これらすべてを処理できます(ただし、procでスケジュールを設定すると、長時間の作業が少なくなります)実行)。どうやって?SQLCLRを使用SqlBulkCopyして.NET のクラスにアクセスします。これは、本質的にBCPであるため、BCP を呼び出す手間がかかりません。これを自分でコーディングすることができます。SqlBulkCopyクラスはほとんどすべてを処理します(トリガーを起動するかどうかなど、バッチサイズを設定できます)。または、アセンブリのコンパイルとデプロイを混乱させたくない場合は、SQL# SQLCLRライブラリの一部であるDB_BulkCopyなどの事前に構築されたSQLCLRストアドプロシージャを使用できます(これは著者ですが、手順は無料版です)。DB_BulkCopyの使用例を含めて、次の回答でこれをさらに詳しく説明します。

あるデータベースから別のスクリプトにデータをインポートする

現在の計画のどこにこれを配置するかが明確でない場合は、次のことを行います。

  • 手順1と2を削除します(woo hoo!)
  • ステップ5を交換EXECするDB_BulkCopyだけポイントBに点Aからデータを移動または何でもあなたはそれを自分でコーディングする場合は、あなたがそれを呼び出します、

また、それとDB_BulkCopyを指摘する必要がSqlBulkCopyあります

  • 任意の結果セットを受け入れることができます:ストアドプロシージャのSELECTかEXECかは関係ありません
  • これらのテーブルのいずれかにスキーマの変更が加えられた場合、非常に簡単に更新できます。このSQLCLRストアドプロシージャを呼び出すストアドプロシージャのクエリを変更するだけです。
  • 必要に応じて、フィールドの再マッピングが可能

SqlBulkCopyを介した最小ログ操作に関する更新

最小限のログ操作を取得することは可能ですが、次のことを知っておく必要があります。

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