Rozwiązywanie problemów i wydajności przy użyciu pakietu SqlPackage
W niektórych scenariuszach operacje SqlPackage trwają dłużej niż oczekiwano lub kończą się niepowodzeniem. W tym artykule opisano niektóre często sugerowane taktyki rozwiązywania problemów lub poprawy wydajności tych operacji. Zaleca się zapoznanie się z konkretnymi stronami dokumentacji dla każdej akcji, aby zrozumieć dostępne parametry i właściwości, jednak ten artykuł służy jako punkt wyjścia do poznania operacji SqlPackage.
Ogólna strategia
Ogólnie rzecz biorąc, lepszą wydajność można uzyskać z użyciem .NET w wersji SqlPackage, zamiast wersji .NET Framework zainstalowanej przy użyciu DacFramework.msi.
Jeśli nie możesz zainstalować narzędzia SqlPackage dotnet, które umożliwia wykonywanie poleceń SqlPackage z wiersza polecenia w dowolnym katalogu:
- Pobierz zip dla pakietu SqlPackage na platformie .NET 8 dla systemu operacyjnego (Windows, macOS lub Linux).
- Rozpakuj archiwum zgodnie z zaleceniami na stronie pobierania.
- Otwórz wiersz polecenia i zmień katalog (
cd
) na folder SqlPackage.
Ważne jest, aby używać najnowszej dostępnej wersji pakietu SqlPackage, ponieważ ulepszenia wydajności i poprawki błędów są regularnie wydawane.
Zastąp pakiet SqlPackage usługą Import/Export
Jeśli podjęto próbę zaimportowania lub wyeksportowania bazy danych przy użyciu usługi Import/Export, możesz użyć pakietu SqlPackage do wykonania tej samej operacji z większą kontrolą nad opcjonalnymi parametrami i właściwościami.
W przypadku importowania przykładowe polecenie to:
./SqlPackage /Action:Import /sf:<source-bacpac-file-path> /tsn:<full-target-server-name> /tdn:<a new or empty database> /tu:<target-server-username> /tp:<target-server-password> /df:<log-file>
W przypadku eksportu przykładowe polecenie to:
./SqlPackage /Action:Export /tf:<target-bacpac-file-path> /ssn:<full-source-server-name> /sdn:<source-database-name> /su:<source-server-username> /sp:<source-server-password> /df:<log-file>
Alternatywą dla nazwy użytkownika i hasła może być uwierzytelnianie wieloskładnikowe, które służy do logowania za pośrednictwem Microsoft Entra (dawniej Azure Active Directory) z użyciem uwierzytelniania wieloskładnikowego. Zastąp parametry nazwy użytkownika i hasła /ua:true
i /tid:"yourdomain.onmicrosoft.com"
.
Diagnostyka
Diagnozowanie błędów i nieoczekiwanego zachowania w pakiecie SqlPackage jest obsługiwane przez dzienniki diagnostyczne i pakiet diagnostyczny. Dzienniki diagnostyczne są niezbędne do rozwiązywania problemów i zapisywane do pliku za pomocą parametru /DiagnosticsFile:<filename>
.
Poziom szczegółów w danych wyjściowych diagnostycznych jest kontrolowany za pomocą parametru /DiagnosticsLevel
. Wartości Information
i Verbose
są przydatne podczas uzyskiwania dodatkowych szczegółów.
Dane śledzenia związane z wydajnością można rejestrować, ustawiając zmienną środowiskową DACFX_PERF_TRACE=true
przed uruchomieniem pakietu SqlPackage. Dane śledzenia zwiększają dane wyjściowe dziennika, więc uwzględniane są tylko podczas diagnozowania problemów z wydajnością. Aby ustawić tę zmienną środowiskową w programie PowerShell, użyj następującego polecenia:
Set-Item -Path Env:DACFX_PERF_TRACE -Value true
W programie SqlPackage 162.5 i nowszych można wygenerować pakiet diagnostyczny, aby pomóc w rozwiązywaniu problemów. Pakiet diagnostyczny zawiera wersję sqlPackage, wykonane polecenie, informacje o źródłowych i docelowych modelach baz danych oraz dane wyjściowe polecenia. Aby wygenerować pakiet diagnostyczny, użyj parametru /DiagnosticsPackageFile:<filename>
.
Typowe problemy
Błędy przekroczenia limitu czasu
W przypadku problemów związanych z przekroczeniami limitu czasu można użyć następujących właściwości, aby dostroić połączenie między pakietem SqlPackage i wystąpieniem SQL:
-
/p:CommandTimeout=
: określa limit czasu polecenia w sekundach po wykonaniu zapytania. Ustawienie domyślne: 60 -
/p:DatabaseLockTimeout=
: określa limit czasu blokady bazy danych w sekundach. -1 może służyć do oczekiwania na czas nieokreślony, wartość domyślna: 60 -
/p:LongRunningCommandTimeout=
: określa limit czasu długotrwałego polecenia w sekundach. Wartość domyślna, 0, jest używana do oczekiwania na czas nieokreślony.
Użycie zasobów klienta
W przypadku poleceń eksportu i wyodrębniania dane tabeli są przekazywane do katalogu tymczasowego w celu zbuforowania przed zapisaniem w pliku bacpac/dacpac. To wymaganie dotyczące magazynu może być duże i jest powiązane z pełnym rozmiarem danych do wyeksportowania. Określ alternatywny katalog tymczasowy z właściwością /p:TempDirectoryForTableData=<path>
.
Model schematu jest kompilowany w pamięci, więc w przypadku dużych schematów bazy danych wymaganie dotyczące pamięci na maszynie klienckiej z uruchomionym pakietem SqlPackage może być znaczące.
Niskie zużycie zasobów serwera
Domyślnie pakiet SqlPackage ustawia maksymalną równoległość serwera na 8. Jeśli zauważysz niskie użycie zasobów serwera, zwiększenie wartości parametru MaxParallelism
może poprawić wydajność.
Token dostępu
Użycie parametru /AccessToken:
lub /at:
umożliwia uwierzytelnianie oparte na tokenach dla pakietu SqlPackage, ale przekazanie tokenu do polecenia może być trudne. Jeśli analizujesz obiekt tokenu dostępu w programie PowerShell, jawnie przekaż wartość ciągu lub zawiń odwołanie do właściwości tokenu w $(). Na przykład:
$Account = Connect-AzAccount -ServicePrincipal -Tenant $Tenant -Credential $Credential
$AccessToken_Object = (Get-AzAccessToken -Account $Account -Resource "https://database.windows.net/")
$AccessToken = $AccessToken_Object.Token
SqlPackage /at:$AccessToken
# OR
SqlPackage /at:$($AccessToken_Object.Token)
Połączenie
Jeśli program SqlPackage nie może nawiązać połączenia, serwer może nie mieć włączonego szyfrowania lub skonfigurowany certyfikat może nie zostać wystawiony z zaufanego urzędu certyfikacji (takiego jak certyfikat z podpisem własnym). Możesz zmienić polecenie SqlPackage, aby nawiązać połączenie bez szyfrowania lub zaufać certyfikatowi serwera. Najlepszym rozwiązaniem jest upewnienie się, że można ustanowić zaufane zaszyfrowane połączenie z serwerem.
- Łączenie bez szyfrowania:
/SourceEncryptConnection:False
lub/TargetEncryptConnection:False
- Certyfikat serwera zaufania:
/SourceTrustServerCertificate:True
lub/TargetTrustServerCertificate:True
Podczas nawiązywania połączenia z wystąpieniem SQL można zobaczyć dowolny z następujących komunikatów ostrzegawczych wskazujących, że parametry wiersza polecenia mogą wymagać zmian w celu nawiązania połączenia z serwerem:
The settings for connection encryption or server certificate trust may lead to connection failure if the server is not properly configured.
The connection string provided contains encryption settings which may lead to connection failure if the server is not properly configured.
Więcej informacji o zmianach zabezpieczeń połączenia w programie SqlPackage jest dostępnych w temacie Ulepszenia zabezpieczeń połączeń w programie SqlPackage 161.
Błąd akcji importowania 2714 dla ograniczenia
Podczas wykonywania akcji importowania może zostać wyświetlony błąd 2714, jeśli obiekt już istnieje:
*** Error importing database:Could not import package.
Error SQL72014: Core Microsoft SqlClient Data Provider: Msg 2714, Level 16, State 5, Line 1 There is already an object named 'DF_Department_ModifiedDate_0FF0B724' in the database.
Error SQL72045: Script execution error. The executed script:
ALTER TABLE [HumanResources].[Department]
ADD CONSTRAINT [DF_Department_ModifiedDate_] DEFAULT ('') FOR [ModifiedDate];
Oto przyczyny i rozwiązania dotyczące tego błędu:
- Sprawdź, czy importowane miejsce docelowe jest pustą bazą danych.
- Jeśli baza danych ma ograniczenia korzystające z atrybutu DEFAULT (gdzie program SQL Server przypisuje losową nazwę do ograniczenia) i jawnie nazwane ograniczenie, ograniczenie o tej samej nazwie może zostać utworzone dwukrotnie. Należy używać albo wszystkich jawnie nazwanych ograniczeń (bez użycia opcji DEFAULT), albo wszystkich nazw systemowo zdefiniowanych (z użyciem opcji DEFAULT).
- Ręcznie zmodyfikuj model.xml i zmień nazwę ograniczenia, w którym występuje błąd, na unikatową nazwę. Ta opcja powinna być podejmowana tylko w przypadku, gdy jest zalecona przez pomoc techniczną firmy Microsoft i stanowi ryzyko uszkodzenia
.bacpac
.
Wyjątek przepełnienia stosu
Duże skrypty języka T-SQL z wieloma zagnieżdżonymi instrukcjami są często przyczyną sporadycznych lub trwałych wyjątków przepełnienia stosu. W takim przypadku komunikat o błędzie będzie zawierać tekst Stack overflow
i ślad stosu:
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.Visit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.ExplicitVisit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Parametr dla SqlPackage jest dostępny we wszystkich poleceniach, /ThreadMaxStackSize:
, który określa maksymalny rozmiar stosu wątku obsługującego proces SqlPackage. Wartość domyślna jest określana przez wersję platformy .NET z uruchomionym pakietem SqlPackage. Ustawienie dużej wartości może mieć wpływ na ogólną wydajność pakietu SqlPackage, jednak zwiększenie tej wartości może rozwiązać wyjątek przepełnienia stosu spowodowany przez zagnieżdżone instrukcje. Refaktoryzacja kodu T-SQL jest zalecana, aby uniknąć wyjątków przepełnienia stosu zawsze, gdy jest to możliwe, ale parametr /ThreadMaxStackSize:
można użyć jako obejścia.
W przypadku korzystania z parametru /ThreadMaxStackSize:
zaleca się dostrojenie powtarzających się operacji do najniższej wartości, która rozwiązuje wyjątek przepełnienia stosu, jeśli zauważono wpływ na wydajność. Wartość parametru jest wyrażona w megabajtach (MB), przykładowe wartości do testowania jako obejście obejmują 10 i 100.
Porady dotyczące akcji importowania
W przypadku importów zawierających duże tabele lub tabele z wieloma indeksami użycie /p:RebuildIndexesOfflineForDataPhase=True
lub /p:DisableIndexesForDataPhase=False
może zwiększyć wydajność. Te właściwości modyfikują operację ponownego kompilowania indeksu, aby wystąpiła odpowiednio w trybie offline lub nie. Te i inne właściwości są dostępne, aby dostroić operację importowania SqlPackage.
Porady dotyczące akcji eksportowania
Częstą przyczyną obniżenia wydajności podczas eksportowania są nierozwiązane odwołania do obiektów, co powoduje wielokrotne podjęcie próby rozpoznania obiektu przez pakiet SqlPackage. Na przykład widok jest zdefiniowany, który odwołuje się do tabeli, a tabela już nie istnieje w bazie danych. Jeśli nierozwiązane odwołania pojawią się w dzienniku eksportu, rozważ poprawienie schematu bazy danych w celu zwiększenia wydajności eksportu.
W scenariuszach, w których miejsce na dysku systemu operacyjnego jest ograniczone i kończy się podczas eksportowania, użycie /p:TempDirectoryForTableData
umożliwia buforowane dane do eksportu na dysku alternatywnym. Miejsce wymagane dla tej akcji może być duże i jest powiązane z pełnym rozmiarem bazy danych. Dane i inne właściwości są dostępne, aby dostroić operację eksportu SqlPackage .
Podczas procesu eksportowania dane tabeli są kompresowane w pliku bacpac. Użycie /p:CompressionOption
ustawionego na Fast
, SuperFast
lub NotCompressed
może poprawić szybkość procesu eksportowania, zmniejszając jednocześnie stopień kompresji pliku bacpac danych wyjściowych.
Aby uzyskać schemat bazy danych i dane podczas pomijania weryfikacji schematu, wykonaj Export z opcją /p:VerifyExtraction=False
. Może zostać wygenerowany nieprawidłowy eksport, którego nie można zaimportować.
Azure SQL Database
Poniższe porady dotyczą uruchamiania importowania lub eksportowania w usłudze Azure SQL Database z maszyny wirtualnej platformy Azure:
- Aby uzyskać najlepszą wydajność, użyj bazy danych klasy Business Critical lub Premium.
- Użyj magazynu SSD na maszynie wirtualnej.
- Upewnij się, że jest wystarczająco dużo miejsca, aby rozpakować plik .bacpac.
- Wykonaj pakiet SqlPackage z maszyny wirtualnej w tym samym regionie co baza danych.
- Włącz przyspieszoną sieć na maszynie wirtualnej.
Aby uzyskać więcej informacji na temat używania skryptu programu PowerShell do zbierania dodatkowych informacji na temat operacji importowania, zobacz Lesson Learned #211: Monitoring SQLPackage Import Process.
Więcej zasobów
Blog pomocy technicznej usługi Azure Database zawiera wiele artykułów dotyczących rozwiązywania problemów i dostrajania wydajności dla usługi Azure SQL Database, w tym kilka artykułów na temat pakietu SqlPackage.
Oto niektóre z najbardziej odpowiednich artykułów:
- Migrowanie bazy danych Azure SQL do Azure SQL Managed Instance przy użyciu SqlPackage i Azure Data Factory (ADF)
- Lekcja poznana #446: upraszczanie debugowania dzienników SQLPackage przy użyciu programu PowerShell
- Jak używać pakietu Sqlpackage z tożsamością zarządzaną
- pl-PL: Lesson Learned #298: Ogromny czas eksportowania bazy danych przy użyciu sqlpackage
- Lekcja poznana #281: Eksportowanie kończy się niepowodzeniem z powodu wyjątku braku pamięci systemu
- Lesson Learned #281: Rozwiązywanie problemów z ograniczeniem CHECK podczas importowania pliku bacpac z powodu logiki biznesowej
- Lesson Learned #272: Komunikat o błędzie: Przekroczono limit czasu wykonania podczas importowania pliku Bacpac
- Lesson Learned #213: Nie można ustawić właściwości AccessToken, jeśli zintegrowane zabezpieczenia zostały ustawione
- Lekcja poznana #211: Monitorowanie procesu importowania pakietu SQLPackage
- Lekcja wyciągnięta #51: Managed Instance — importowanie za pośrednictwem Sqlpackage.exe nie zezwala na automatyczny wzrost rozmiaru
- Wnioski z nauki #32: Jak wyeksportować wiele baz danych z serwera SQL Server do Bacpac
- krok po kroku: jak używać pakietu SQLPackage z tokenem dostępu
- konflikt sortowania podczas przenoszenia bazy danych Azure SQL DB do lokalnego serwera SQL lub maszyny wirtualnej platformy Azure przy użyciu pakietu SQLPackage.