Какой лучший способ обновить только несколько таблиц в тестовой базе данных с производства?

12

У меня есть очень большая производственная база данных и очень большая база данных среды тестирования в SQL Server 2008R2. Обе базы данных имеют одинаковую структуру таблиц, но разные пользователи / логины / разрешения / роли.

Мне нужно обновлять только несколько таблиц в тестовой базе данных периодически с производства, примерно раз в месяц.

В настоящее время я планирую сделать это

  1. Используйте утилиту BCP для экспорта необходимых мне таблиц из Production.
  2. Скопируйте файл экспорта bcp на тестовый сервер
  3. Отключить индексы и ограничения для всех таблиц, которые я обновляю в тесте
  4. Усечь тестовые таблицы базы данных
  5. Загрузите данные обратно в таблицы тестовой базы данных, используя BCP.
  6. перестроить индексы и повторно включить ограничения в тесте

Все это кажется слишком сложным для такой маленькой задачи. Также кажется, что это вызовет много повторов (в t-log). Есть ли лучший способ сделать это?

Еще один способ, который я задумал сделать, - это восстановить резервную копию из производства в тестовой среде, но у меня есть проблема, что полная резервная копия будет довольно большой, и мне не нужно обновлять все таблицы, только несколько. - а также пользователи и безопасность в производственной базе данных отличаются от тестовых. Это будет перезаписано настройками безопасности в производственной базе данных, если я восстановлю всю базу данных.

Эрик Ларсон
источник
Этот подход также стоит изучить: sqlperformance.com/2012/08/t-sql-queries/… и sqlperformance.com/2013/04/t-sql-queries/…
Аарон Бертран

Ответы:

4

Есть 2 метода, которые подойдут вам:

(Примечание: если на таблицы ссылаются по внешнему ключу, вы не сможете их использовать TRUNCATE. Вы должны удалить куски . Кроме того, вы можете удалить все индексы + внешние ключи и загрузить данные, а затем воссоздать их).

  • BCP OUT и BULK INSERT INTO база данных назначения .

    • Убедитесь, что вы поместили тестовую базу данных в режим простого / массового восстановления.
    • Включить Trace Flag 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 - Мой предпочтительный метод в этом случае.

    • Постановка на диск не требуется. Вся обработка выполняется в памяти.
    • Вы можете запланировать пакет служб SSIS с помощью задания sql agent каждый месяц, чтобы автоматизировать обновление таблиц с PROD на сервер TEST.
    • Выберите опцию « БЫСТРАЯ НАГРУЗКА »
    • Удостоверьтесь, что вы выбрали хорошие строки для номера партии (если вы выберете слишком высокое значение, произойдет эскалация блокировки - удерживайте ее ниже 5K)

Ссылка: Руководство по производительности при загрузке данных и мой ответ для - Вставить в таблицу выберите * из таблицы против массовой вставки

Кин Шах
источник
1
SSIS - определенно способ пойти сюда. Накачка данных - это то, что было разработано.
Стив Мангиамели
3

Нет необходимости делать резервные копии и восстанавливать, или вызывать / координировать внешние процессы (например, BCP), или даже связываться с SSIS (очень мощный, очень крутой, но если я могу избежать этого, я, конечно, буду :). Вы можете справиться со всем этим, не выходя из T-SQL, с помощью хранимой процедуры, которую вы можете запланировать с помощью агента SQL, или с помощью сценария, который вы запускаете раз в месяц (хотя его использование в процедуре и планировании не требует длительной работы. бегать). Как? Используя SQLCLR для доступа к SqlBulkCopyклассу в .NET, так как это, по сути, BCP без суеты вызова BCP. Вы можете написать это самостоятельно: здесь нет супер сложной настройки или чего-то подобногоSqlBulkCopyкласс позаботится обо всем за вас (вы можете установить размер пакета, запускать триггеры и т. д.). Или, если вы не хотите возиться с компиляцией и развертыванием сборки, вы можете использовать готовую хранимую процедуру SQLCLR, такую ​​как DB_BulkCopy, которая является частью библиотеки SQL # SQLCLR (автором которой я являюсь, но она сохранена). процедура в бесплатной версии). Я опишу это более подробно, включая пример использования DB_BulkCopy , в следующем ответе:

Импорт данных из одной базы данных в другой скрипт

Если не ясно, где разместить это в вашем текущем плане, вы бы сделали следующее:

  • Удалите шаги 1 и 2 (уууууу!)
  • Заменить шаг 5 с EXECиз DB_BulkCopy или что вы называете это , если вы код это самостоятельно, который просто перемещает данные из точки А в точку Б.

Также следует отметить, что SqlBulkCopyи DB_BulkCopy :

  • может принять любой набор результатов: не имеет значения, является ли это SELECT или EXEC хранимой процедуры
  • очень легко обновлять, когда изменения схемы вносятся в любую из этих таблиц; просто измените запрос в вашей хранимой процедуре, который вызывает эту хранимую процедуру SQLCLR
  • разрешить переназначение полей, если это когда-либо понадобится

ОБНОВЛЕНИЕ относительно минимально зарегистрированных операций через SqlBulkCopy

Можно получить минимально зарегистрированные операции, но вы должны знать:

Соломон Руцкий
источник