从生产中仅刷新测试数据库中的几个表的最佳方法是什么?

Eri*_*son 12 sql-server-2008 sql-server

我在 SQL Server 2008R2 中有一个非常大的生产数据库和一个非常大的测试环境数据库。两个数据库具有相似的表结构,但不同的用户/登录名/权限/角色。

我只需要定期从生产中刷新测试数据库中的几个表,大约每月一次。

我目前计划这样做的方式是

  1. 使用 BCP 实用程序从生产中导出我需要的表。
  2. 将 bcp 导出文件复制到测试服务器上
  3. 禁用我在测试中刷新的所有表的索引和约束
  4. 截断测试数据库表
  5. 使用 BCP 将数据加载回测试数据库表。
  6. 在测试中重建索引并重新启用约束

对于这么小的任务来说,这一切似乎有点太复杂了。它似乎也会产生很多重做(在 t-log 中)有没有更好的方法来做到这一点?

我想到的另一种方法是将备份从生产恢复到测试环境 - 但我遇到的问题是完整备份会非常大,我不需要刷新所有表,只需要刷新几个 - - 而且生产数据库中的用户和安全性与测试不同。如果我恢复整个数据库,这将被生产数据库中的安全设置覆盖。

Kin*_*hah 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)
      
      Run Code Online (Sandbox Code Playgroud)

--

  • 方法 2:SSIS - 在这种情况下我的首选方法。

    • 无需暂存到磁盘。所有处理都在内存中完成。
    • 您可以每月使用 sql 代理作业安排 SSIS 包,以自动将表从 PROD 刷新到 TEST 服务器。
    • 选择“快速加载”选项
    • 确保你为每个批次选择了一个好的行数(如果你选择太高,将会出现锁升级 - 保持它低于 5K)

参考:数据加载性能指南我的答案 - Insert into table select * from table vsbulk insert