последние пару недель я создавал общий скрипт, который может копировать базы данных. Цель состоит в том, чтобы иметь возможность указать любую базу данных на каком-либо сервере и скопировать ее в какое-то другое место, и она должна копировать только указанный контент. Точный контент, который нужно скопировать, указывается в файле конфигурации. Этот сценарий будет использоваться примерно в 10 различных базах данных и запускаться еженедельно. И в итоге мы копируем только 3–20% баз данных размером до 500 ГБ. Для этого я использовал сборки SMO. Я впервые работаю с SMO, и мне потребовалось время, чтобы создать общий способ копирования объектов схемы, файловых групп и т. Д. (На самом деле помогло найти несколько плохо сохраненных процедур).
В целом у меня есть рабочий сценарий, который не работает (а иногда и не работает), и я надеялся, что вы, ребята, сможете помочь. При выполнении команды WriteToServer для копирования большого количества данных (> 6 ГБ) мой тайм-аут достигает 1 часа. Вот основной код для копирования данных таблицы. Скрипт написан на PowerShell.
$query = ("SELECT * FROM $selectedTable " + $global:selectiveTables.Get_Item($selectedTable)).Trim()
Write-LogOutput "Copying $selectedTable : '$query'"
$cmd = New-Object Data.SqlClient.SqlCommand -argumentList $query, $source
$cmd.CommandTimeout = 120;
$bulkData = ([Data.SqlClient.SqlBulkCopy]$destination)
$bulkData.DestinationTableName = $selectedTable;
$bulkData.BulkCopyTimeout = $global:tableCopyDataTimeout # = 3600
$reader = $cmd.ExecuteReader();
$bulkData.WriteToServer($reader); # Takes forever here on large tables
Исходная и целевая базы данных расположены на разных серверах, поэтому я также отслеживал скорость сети. Загрузка сети никогда не превышала 1%, что меня очень удивило. Но когда я просто передаю несколько больших файлов между серверами, загрузка сети возрастает до 10%. Я попытался установить для $ bulkData.BatchSize значение 5000, но на самом деле ничего не изменилось. Увеличение BulkCopyTimeout до еще большего количества решит только тайм-аут. Мне очень хотелось бы знать, почему сеть не используется в полной мере.
У кого-нибудь еще была эта проблема? Мы будем благодарны за любые предложения по сети или массовому копированию. И, пожалуйста, дайте мне знать, если вам понадобится дополнительная информация.
Спасибо.
ОБНОВЛЕНИЕ
Я настроил несколько параметров, которые увеличивают производительность SqlBulkCopy, например, установил простое ведение журнала транзакций и предоставил блокировку таблицы для SqlBulkCopy вместо блокировки строк по умолчанию. Также некоторые таблицы лучше оптимизированы для определенных размеров партии. В целом продолжительность копии сократилась примерно на 15%. И что мы будем делать, так это выполнять копию каждой базы данных одновременно на разных серверах. Но у меня все еще возникает проблема с тайм-аутом при копировании одной из баз данных.
При копировании одной из более крупных баз данных есть таблица, для которой я постоянно получаю следующее исключение:
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Он выдается примерно через 16 минут после начала копирования таблицы, которой нет рядом с моим BulkCopyTimeout. Хотя у меня есть исключение, таблица полностью копируется в конце. Кроме того, если я усекаю эту таблицу и перезапускаю свой процесс только для этой таблицы, таблицы копируются без каких-либо проблем. Но копирование всей базы данных всегда терпит неудачу для этой единственной таблицы.
Я попытался выполнить весь процесс и сбросить соединение перед копированием этой ошибочной таблицы, но все равно возникла ошибка. Мои SqlBulkCopy и Reader закрываются после каждой таблицы. Любые предложения относительно того, что еще могло приводить к сбою сценария каждый раз?
CREATE TABLE [dbo].[badTable](
[someGUID] [uniqueidentifier] NOT NULL,
[xxx] [uniqueidentifier] NULL,
[xxx] [int] NULL,
[xxx] [tinyint] NOT NULL,
[xxx] [datetime] NOT NULL,
[xxx] [datetime] NOT NULL,
[xxx] [datetime] NOT NULL,
[xxx] [datetime] NULL,
[xxx] [uniqueidentifier] NOT NULL,
[xxx] [uniqueidentifier] NULL,
CONSTRAINT [PK_badTable] PRIMARY KEY NONCLUSTERED
(
[someGUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Для этой таблицы в целевой БД нет индексов.