Apa metode terbaik untuk me-refresh hanya beberapa tabel dalam database uji dari produksi?

12

Saya memiliki database produksi yang sangat besar dan database lingkungan pengujian yang sangat besar di SQL Server 2008R2. Kedua database memiliki struktur tabel yang sama tetapi berbeda pengguna / login / izin / peran.

Saya perlu menyegarkan hanya beberapa tabel dalam database pengujian secara berkala dari produksi, sekitar sebulan sekali.

Cara saat ini saya berencana melakukan ini

  1. Gunakan utilitas BCP untuk mengambil ekspor tabel yang saya butuhkan dari Produksi.
  2. Salin file ekspor bcp ke server uji
  3. Nonaktifkan indeks dan batasan pada semua tabel yang saya refresh dalam Tes
  4. Pangkas tabel database Test
  5. Muat data kembali ke tabel database Test menggunakan BCP.
  6. membangun kembali indeks dan mengaktifkan kembali kendala dalam Tes

Ini semua tampaknya agak terlalu rumit untuk tugas sekecil itu. Sepertinya juga akan menghasilkan banyak pengulangan (di t-log) Apakah ada cara yang lebih baik untuk melakukan ini?

Cara lain yang saya pikirkan untuk melakukan ini adalah mengembalikan cadangan dari Produksi ke lingkungan pengujian - tetapi masalah yang saya miliki adalah bahwa cadangan penuh akan cukup besar dan saya tidak perlu semua tabel di-refresh, hanya beberapa- -dan juga pengguna dan keamanan dalam database produksi berbeda dari pengujian. Itu akan ditimpa oleh pengaturan keamanan di database produksi jika saya mengembalikan seluruh database.

Eric Larson
sumber
Pendekatan ini mungkin juga layak diselidiki: sqlperformance.com/2012/08/t-sql-queries/… dan sqlperformance.com/2013/04/t-sql-queries/…
Aaron Bertrand

Jawaban:

4

Ada 2 metode yang sesuai dengan kebutuhan Anda:

(Catatan: Jika tabel direferensikan oleh kunci asing, maka Anda tidak akan dapat menggunakan TRUNCATE. Anda harus menghapus dalam potongan . Atau, Anda dapat menjatuhkan semua indeks + kunci asing dan memuat data dan kemudian menciptakan kembali).

  • BCP OUT dan BULK INSERT INTO database tujuan .

    • Pastikan Anda meletakkan basis data pengujian dalam mode pemulihan sederhana / bulk-log.
    • Aktifkan Bendera Jejak 610 - sisipan yang masuk secara minimal ke dalam tabel yang diindeks.

      /************************************************************************************************************************************************
      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)

-

  • Metode 2: SSIS - Metode pilihan saya dalam kasus ini.

    • Tidak diperlukan staging ke disk. Semua pemrosesan dilakukan dalam memori.
    • Anda dapat menjadwalkan paket SSIS menggunakan pekerjaan agen sql setiap bulan untuk mengotomatiskan refresh tabel dari server PROD ke TEST.
    • Pilih opsi " FAST LOAD "
    • Pastikan Anda memilih baris yang baik per nomor batch (Jika Anda memilih terlalu tinggi, akan ada eskalasi kunci - jaga agar lebih rendah dari 5K)

Referensi: Panduan Kinerja Pemuatan Data dan jawaban saya untuk - Sisipkan ke dalam tabel pilih * dari tabel vs masukkan massal

Kin Shah
sumber
1
SSIS jelas merupakan cara untuk pergi ke sini. Pemompaan data adalah apa yang dirancang untuk dilakukan.
Steve Mangiameli
3

Tidak perlu melakukan backup dan restore, atau memanggil / mengoordinasikan proses eksternal (yaitu BCP), atau bahkan mengacaukan SSIS (sangat kuat, sangat keren, tetapi jika saya bisa menghindarinya, saya pasti akan :). Anda dapat menangani semua ini dari kenyamanan T-SQL, dalam prosedur tersimpan yang dapat Anda jadwalkan melalui SQL Agent, atau skrip yang Anda jalankan sebulan sekali (meskipun memilikinya dalam proc dan penjadwalan adalah pekerjaan yang kurang dalam jangka panjang Lari). Bagaimana? Dengan menggunakan SQLCLR untuk mengakses SqlBulkCopyKelas di. NET karena pada dasarnya BCP tanpa semua kerepotan memanggil BCP. Anda dapat mengkodekannya sendiri: tidak ada pengaturan super rumit atau apa pun sebagaiSqlBulkCopykelas menangani hampir segalanya untuk Anda (Anda dapat mengatur ukuran bets, apakah akan memicu pemicu, dll). Atau, jika Anda tidak ingin mengacaukan dengan menyusun dan menggunakan Majelis, Anda dapat menggunakan prosedur tersimpan SQLCLR pra-dibangun seperti DB_BulkCopy yang merupakan bagian dari perpustakaan SQL # SQLCLR (yang saya penulis, tetapi ini disimpan prosedur dalam versi Gratis). Saya menjelaskan hal ini secara lebih rinci, termasuk contoh menggunakan DB_BulkCopy , dalam jawaban berikut:

Impor data dari satu Database ke skrip lain

Jika tidak jelas di mana menempatkan ini dalam rencana Anda saat ini, Anda akan melakukan hal berikut:

  • Hapus langkah 1 dan 2 (woo hoo!)
  • Ganti langkah 5 dengan EXECdari DB_BulkCopy atau apa pun yang Anda menyebutnya jika Anda kode itu sendiri, yang hanya bergerak data dari Point A ke titik B.

Juga, harus ditunjukkan itu SqlBulkCopydan DB_BulkCopy :

  • dapat menerima set hasil apa pun: tidak masalah apakah itu SELECT atau EXEC dari prosedur tersimpan
  • sangat mudah untuk diperbarui ketika perubahan skema dibuat ke salah satu tabel ini; ALTER saja kueri dalam Prosedur Tersimpan Anda yang menyebut Prosedur Tersimpan SQLCLR ini
  • memungkinkan untuk memetakan ulang bidang, jika itu pernah diperlukan

UPDATE Mengenai Operasi yang Dicatat Minimal melalui SqlBulkCopy

Dimungkinkan untuk mendapatkan operasi yang tercatat minimal, tetapi Anda harus tahu:

  • Anda perlu menggunakan opsi Salinan TableLock Massal
  • Melakukan ini akan, untuk tabel dengan Indeks Clustered, pertama memuat data ke dalam [tempdb]dan kemudian melakukan memasukkan memerintahkan ke tujuan. Oleh karena itu, ada beberapa beban tambahan yang timbul, baik dalam hal I / O fisik untuk tempdb (data dan file log) maupun operasi sortir (karena ORDER BYyang diperlukan untuk mendapatkan operasi log minimal)
  • Beberapa hasil pengujian di sini: Whitepaper: kinerja SqlBulkCopy
  • Beberapa hasil pengujian di sini: Pemecahan masalah SqlBulkCopy tidak melakukan logging minimal
Solomon Rutzky
sumber