Назад | Перейти на главную страницу

Импорт файла BACPAC с 25000 таблиц на SQL Server завершается ошибкой с тайм-аутом

Я хотел бы импортировать файл bacpac, который был экспортирован из БД объемом 500 МБ, в которой, однако, содержится около 25000 таблиц. Сам бакпак составляет около 18 МБ.

Импорт через пользовательский интерфейс SQL Server Management Studio завершается ошибкой OutOfMemoryException, поэтому я бы использовал SqlPackage.exe следующим образом:

"C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe" /Action:Import /SourceFile:"path\to\MyDB.bacpac" /TargetConnectionString:"Data Source=localhost;Initial Catalog=MyDB;Integrated Security=True;"

Я успешно использовал эту команду для импорта с предыдущими (меньшими, с меньшим количеством таблиц) версиями БД, но теперь он не работает с выводом ниже. Могу я здесь что-нибудь сделать?

Importing to database 'MyDB' on server 'localhost'.
Creating deployment plan
Initializing deployment
Verifying deployment plan
Analyzing deployment plan
Importing package schema and data into database
Updating database
An unexpected failure occurred: Data plan execution failed with message Unable t
o reconnect to database: Timeout expired.  The timeout period elapsed prior to c
ompletion of the operation or the server is not responding..

Unhandled Exception: Microsoft.SqlServer.Dac.Data.DataException: Data plan execu
tion failed with message Unable to reconnect to database: Timeout expired.  The
timeout period elapsed prior to completion of the operation or the server is not
 responding. ---> Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlReverseEngineer
Exception: Unable to reconnect to database: Timeout expired.  The timeout period
 elapsed prior to completion of the operation or the server is not responding. -
--> System.Data.SqlClient.SqlException: Timeout expired.  The timeout period ela
psed prior to completion of the operation or the server is not responding. --->
System.ComponentModel.Win32Exception: The wait operation timed out
   --- End of inner exception stack trace ---
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolea
n breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObj
ect stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand
 cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,
TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, Run
Behavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBe
havior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 time
out, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameter
EncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehav
ior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletio
nSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehav
ior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, S
tring method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader()
   at Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlReverseEngineerImpl.Execute
Populators(Tuple`2 connectionTuple, IList`1 populators, Int32 totalPopulatorsCou
nt, Int32 startIndex, Boolean progressAlreadyUpdated, ReverseEngineerOption opti
on, SqlReverseEngineerRequest request)
   --- End of inner exception stack trace ---
   at Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlReverseEngineerImpl.Execute
PopulatorsInPass(SqlReverseEngineerConnectionContext context, ReverseEngineerOpt
ion option, SqlReverseEngineerRequest request, Int32 totalCount, Tuple`2[] popul
atorsArray)
   at Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlReverseEngineerImpl.Populat
eBatch(SqlReverseEngineerConnectionContext context, SqlSchemaModel model, Revers
eEngineerOption option, ErrorManager errorManager, SqlReverseEngineerRequest req
uest, SqlImportScope importScope)
   at Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlReverseEngineer.PopulateEle
ments(SqlReverseEngineerConnectionContext context, DataSchemaModel model, Revers
eEngineerOption option, ErrorManager errorManager, SqlImportScope importScope, S
qlReverseEngineerRequest[] requests)
   at Microsoft.Data.Tools.Schema.Sql.Deployment.Steps.DacBulkCopyStep.GetImport
TableMetadata(ICollection`1 tables)
   at Microsoft.Data.Tools.Schema.Sql.Deployment.Steps.DacBulkCopyStep.Execute(I
DbConnection conn, CancellationToken token)
   at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlPlanDeployment.Execute(Deplo
ymentPlanHandle plan, String connectionString, String targetDatabaseName, Boolea
n IsAzureTarget, String databaseScriptPath, String masterScriptPath, Cancellatio
nToken cancelToken)
   at Microsoft.SqlServer.Dac.Deployment.PlanExecutor.Execute(DeploymentPlan pla
n, SqlConnectionStringBuilder connectionString, Boolean isAzureTarget, LoggingCo
ntext loggingContext, CancellationToken cancelToken)
   --- End of inner exception stack trace ---
   at Microsoft.SqlServer.Dac.Deployment.PlanExecutor.Execute(DeploymentPlan pla
n, SqlConnectionStringBuilder connectionString, Boolean isAzureTarget, LoggingCo
ntext loggingContext, CancellationToken cancelToken)
   at Microsoft.SqlServer.Dac.DeployOperation.UpdateDatabaseData(LoggingContext
loggingContext, CancellationToken token)
   at Microsoft.SqlServer.Dac.DeployOperation.<>c__DisplayClass10.<>c__DisplayCl
ass12.<CreatePlanExecutionOperation>b__f()
   at Microsoft.Data.Tools.Schema.Sql.Dac.OperationLogger.Capture(Action action)

   at Microsoft.SqlServer.Dac.DeployOperation.<>c__DisplayClass10.<CreatePlanExe
cutionOperation>b__e(Object operation, CancellationToken token)
   at Microsoft.SqlServer.Dac.Operation.Microsoft.SqlServer.Dac.IOperation.Run(O
perationContext context)
   at Microsoft.SqlServer.Dac.ReportMessageOperation.Microsoft.SqlServer.Dac.IOp
eration.Run(OperationContext context)
   at Microsoft.SqlServer.Dac.DeployOperation.Microsoft.SqlServer.Dac.IOperation
.Run(OperationContext context)
   at Microsoft.SqlServer.Dac.OperationExtension.Execute(IOperation operation, D
acLoggingContext loggingContext, CancellationToken cancellationToken)
   at Microsoft.SqlServer.Dac.DacServices.InternalDeploy(IPackageSource packageS
ource, Boolean isDacpac, String targetDatabaseName, DacDeployOptions options, Ca
ncellationToken cancellationToken, DacLoggingContext loggingContext)
   at Microsoft.SqlServer.Dac.DacServices.ImportBacpac(BacPackage package, Strin
g targetDatabaseName, DacImportOptions importOptions, Nullable`1 cancellationTok
en)
   at Microsoft.Data.Tools.Schema.CommandLineTool.Program.DoImportBacpacOperatio
n(CommandLineArguments parsedArgs)
   at Microsoft.Data.Tools.Schema.CommandLineTool.Program.PerformAction(CommandL
ineArguments parsedArgs)
   at Microsoft.Data.Tools.Schema.CommandLineTool.Program.Run(String[] args)
   at Microsoft.Data.Tools.Schema.CommandLineTool.Program.Main(String[] args)

Оказывается, решение так же просто, как указание большего таймаута. Однако имеет значение, какой тайм-аут (есть несколько переключателей тайм-аута для SqlPackage.exe, и это не тайм-аут соединения, указанный в строке подключения), это CommandTimeout. Приведенная ниже измененная команда не завершится ошибкой даже с бакпаком, содержащим большое количество таблиц (обратите внимание на последний, недавно добавленный переключатель):

"C:\Program Files (x86)\Microsoft SQL Server\120\DAC\bin\SqlPackage.exe" /Action:Import /SourceFile:"path\to\MyDB.bacpac" /TargetConnectionString:"Data Source=localhost;Initial Catalog=MyDB;Integrated Security=True;" /p:CommandTimeout="0"

«0» означает отсутствие тайм-аута, поэтому это применимо только тогда, когда нет опасности, если операции застревают или выполняются на неожиданно долгое время, например, при локальном импорте bacpac для разработки, как это делаю я.