SqlPackage.exe - "System.StackruException"
У меня есть серия скриптов PowerShell, которые запускаются агентом TFS и являются частью процесса сборки. Они запускаются на нескольких серверах (Windows Server 2012 R2), которые публикуют серию DACPAC в заданном наборе баз данных. Недавно я обновил все агенты сборки TFS до последней версии ( TFS 2018)
Сегодня я заметил, что один из этих серверов в моем процессе сборки больше не работает, в частности он не запускает "SqlPackage.exe" из-за ошибки "System.StackruException" (что очень подходит для этого сайта).
Эту же проблему можно воспроизвести, запустив скрипт Power Shell вручную, но только на этом одном сервере, все остальные работают без проблем. Сценарий выглядит так:
$arguements = '/a:Publish /pr:"' + $scriptPath + $database + ".publish.xml" + '" /sf:"' + $dacPac + '" /tcs:"Data Source=' + $servername + ';Persist Security Info=True;User ID=' + $username + ';Password=' + $password + ';Pooling=False;MultipleActiveResultSets=False;Connect Timeout=60;Encrypt=False;TrustServerCertificate=True"'
Start-Process -FilePath "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\SqlPackage.exe" -ArgumentList $arguements -NoNewWindow -PassThru -Wait
При ручном запуске исключение отладки:
Необработанное исключение типа "System.StackruException" произошло в Microsoft.SqlServer.TransactSql.ScriptDom.dll
Я действительно не уверен, какая конфигурация на этом сервере вызовет такого рода проблемы. Ресурсный сервер очень мощный с большими объемами доступной памяти, другие серверы работают нормально. Я пробовал разные версии "SqlPackage"(13, 14), но, похоже, это не дает никакого эффекта. Я поменял DacPac, но это тоже не сработало...
Кто-нибудь видел эту проблему раньше? Какая конфигурация сервера может вызвать такую проблему?
Обновление 1
Хммм, просто переключитесь на новый "14.0", "SqlPackage.exe", теперь я получаю его на всех своих машинах, мне интересно, связано ли это с какими-либо реализованными dll, такими как те, которые я установил в SSDT.
На самом деле, теперь, когда я думаю об этом, я думаю, что эта проблема возникла на сервере, когда я впервые установил VS 2017, мне интересно, как это повлияет на SqlPackage.exe?
Я также нашел этот интересный пост, интересно, смогу ли я обойти это таким образом...
0 ответов
Я так и не понял, как решить эту проблему для "SqlPackage", в итоге мы создали наше собственное консольное приложение для развертывания пакетов и вместо этого вызывали его через консольное приложение ("DacpacDeployUtility"):
static int Main(string[] args)
{
try
{
string destinationServer = args[0];
string destinationDatabase = args[1];
string userID = args[2];
string password = args[3];
string publishFileFullPath = args[4];
string dacpacFileFullPath = args[5];
SetupRegistryQueryExecutionTimeout();
PublishDacpacSimple(destinationServer, destinationDatabase, userID, password, publishFileFullPath, dacpacFileFullPath);
return 0; //where 0 = success
}
catch (Exception ex)
{
Console.WriteLine("Error in Main: " + ex.Message + "\n" + ex.StackTrace);
for (int i = 0; i < args.Length; i++)
{
Console.WriteLine("Value in args[" + i + "]: " + (i == 3 ? "**********" : args[i]));
}
Console.WriteLine("Failed to publish dacpac.");
//Return error state
return 1;
}
}
private static void SetupRegistryQueryExecutionTimeout()
{
//Fixes an annoying issue with slow sql servers: https://stackru.com/a/26108419/2912011
RegistryKey myKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\VisualStudio\\12.0\\SQLDB\\Database", true);
if (myKey != null)
{
myKey.SetValue("QueryTimeoutSeconds", "0", RegistryValueKind.DWord);
myKey.Close();
}
myKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\VisualStudio\\14.0\\SQLDB\\Database", true);
if (myKey != null)
{
myKey.SetValue("QueryTimeoutSeconds", "0", RegistryValueKind.DWord);
myKey.Close();
}
myKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\VisualStudio\\15.0\\SQLDB\\Database", true);
if (myKey != null)
{
myKey.SetValue("QueryTimeoutSeconds", "0", RegistryValueKind.DWord);
myKey.Close();
}
}
private static void PublishDacpacSimple(string destinationServer,
string destinationDatabase,
string userID,
string password,
string publishFileFullPath,
string dacpacFileFullPath)
{
string connectionString = BuildConnectionString(destinationServer, destinationDatabase, userID, password);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(publishFileFullPath);
DacServices ds = new DacServices(connectionString);
using (DacPackage package = DacPackage.Load(dacpacFileFullPath))
{
var options = new DacDeployOptions();
options.CommandTimeout = 600;
ds.Message += (object sender, DacMessageEventArgs eventArgs) => Console.WriteLine(eventArgs.Message.Message);
ds.Deploy(package, destinationDatabase, true, options);
}
}
Затем вызовите это в скрипте PowerShell:
$DacPacDeployerPath = """" + $scriptPath + "..\..\..\DacpacDeployUtility\bin\release\EBMDacpacDeployUtility.exe"""
$Output = Start-Process -FilePath $DacPacDeployerPath -ArgumentList $arguements -NoNewWindow -PassThru -Wait