Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten artykuł zawiera rozwiązania typowych błędów i problemów z łącznością sterownika go-mssqldb .
Zacznij od najprostszych testów
Zanim włączysz szczegółowe rejestrowanie lub zmienisz ustawienia puli, zapoznaj się z poniższą listą:
- Sprawdź podstawową dostępność: nazwę serwera, port, reguły zapory oraz czy SQL Server czy Azure SQL akceptuje połączenia.
- Weryfikuj dane uwierzytelniające: nazwa sterownika, nazwa użytkownika, hasło, format domeny lub
fedauthkonfiguracja. - Sprawdź ustawienia TLS:
encrypt, ścieżkihostnameincertificatecertyfikatów , oraz czyTrustServerCertificatesą odpowiednie dla danego środowiska. - Dopiero po poprawnym skonfigurowaniu połączenia sprawdź wyczerpanie puli, przestarzałe połączenia, logikę powtórek oraz spowolnioną lub zablokowaną diagnostykę zapytań.
Skorzystaj z wczesnych sekcji tego artykułu na temat awarii konfiguracji połączenia. Korzystaj z dalszych sekcji dopiero wtedy, gdy połączenia przynajmniej czasami działają poprawnie, a następnie zaczynają zawodzić pod obciążeniem, po okresie bezczynności lub podczas przełączania awaryjnego.
Błędy połączenia
Poniższe sekcje omawiają typowe komunikaty o błędach związanych z połączeniem oraz ich rozwiązania.
Nie udało się otworzyć połączenia TCP
Komunikat o błędzie: unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.
Przyczyny i rozwiązania:
- SQL Server nie działa. Uruchom usługę SQL Server.
- TCP/IP nie jest włączone. Otwórz SQL Server Configuration Manager i włącz TCP/IP w SQL Server> Protocols.
- Zły port. Zweryfikowaj port w SQL Server Configuration Manager lub użyj SQL Server Browser dla nazwanych instancji.
- Zapora sieciowa blokuje port. Dodaj regułę przychodzącą dla portu 1433 (lub skonfigurowanego portu).
Logowanie użytkownika nie powiodło się
Komunikat o błędzie: mssql: login error: Login failed for user '<user>'.
Przyczyny i rozwiązania:
- Błędna nazwa użytkownika lub hasło. Zweryfikowaj dane uwierzytelniające.
- Uwierzytelnianie SQL Server jest wyłączone. Włącz tryby uwierzytelniania SQL Server i Windows w właściwościach serwera.
- Login nie istnieje. Utworz logowanie w SQL Server.
- Login nie ma dostępu do docelowej bazy danych. Przyznaj dostęp do bazy danych za pomocą
CREATE USER.
Błędy walidacji certyfikatów
Komunikat o błędzie: TLS Handshake failed: x509: certificate signed by unknown authority
Przyczyny i rozwiązania:
- Serwer korzysta z certyfikatu podpisanego samodzielnie. Podaj ścieżkę certyfikatu za pomocą parametru
certificatelubserverCertificate, albo ustawTrustServerCertificate=truewyłącznie do celów programistycznych. - Certyfikat CA nie znajduje się w sklepie System Trust. Dodaj certyfikat CA do magazynu zaufania systemu operacyjnego lub określ go parametrem
certificate. - Niezgodność nazwy hosta. Użyj
hostnameincertificate, aby określić oczekiwaną nazwę w certyfikacie.
Więcej informacji można znaleźć w artykule Szyfrowanie i certyfikaty.
Upłynął limit czasu połączenia
Komunikat o błędzie: unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout
Przyczyny i rozwiązania:
- Problemy z łącznością sieciową. Sprawdź, czy możesz połączyć się z serwerem, używając
telnet <server> 1433lubTest-NetConnection -ComputerName <server> -Port 1433. - Błąd rozwiązywania nazw DNS. Sprawdź, czy nazwa hosta jest poprawnie rozwiązana.
- Zwiększ
dial timeoutlubconnection timeoutw parametrach połączenia.
Błędy uwierzytelniania
Poniższe sekcje dotyczą komunikatów o błędach uwierzytelniania.
Awarie uwierzytelniania NTLM
Komunikat o błędzie: NTLM authentication failed
Przyczyny i rozwiązania:
- Nieprawidłowy format domeny. Zastosowanie
DOMAIN\userw parametrzeuser id. W formacie URL zakoduj ukośnik wsteczny jako%5C. - Złe hasło. Sprawdź hasło do domeny.
Niepowodzenia uwierzytelniania protokołu Kerberos
Komunikat o błędzie: krb5: cannot resolve KDC for realm
Przyczyny i rozwiązania:
- Brakuje lub jest źle skonfigurowana
/etc/krb5.conf. Sprawdź, czy sekcja[realms]zawiera poprawny adres KDC dla Twojej domeny. - Brak ważnego biletu. Uruchom
klist, aby sprawdzić, czy masz ważny bilet, albo uruchomkinit, aby go uzyskać. - Nie znaleziono pliku keytab. Zweryfikowaj ścieżkę w parametrze
krb5-keytabfile.
Więcej informacji można znaleźć w sekcji SQL Server i Windows authentication.
Błędy uwierzytelniania Microsoft Entra ID
Komunikat o błędzie: clientCredentialFromCert: error reading certificate: ... lub DefaultAzureCredential: failed to acquire a token
Przyczyny i rozwiązania:
- Nieprawidłowy identyfikator klienta, identyfikator najemcy lub sekret klienta. Zweryfikuj wartości w parametrach połączenia lub zmiennych środowiskowych.
- Zarządzana tożsamość nie jest skonfigurowana na hostze. Zweryfikowaj tożsamość w portalu Azure.
- Brakuje importu
azureadpaczki. Zaimportujgithub.com/microsoft/go-mssqldb/azureadi użyj nazwy sterownikaazuresql.
Aby uzyskać więcej informacji, zobacz Microsoft Entra ID authentication (Uwierzytelnianie za pomocą identyfikatora Entra firmy Microsoft).
Logowanie użytkownika '' nie powiodło się (pusta nazwa użytkownika)
Komunikat o błędzie: mssql: login error: Login failed for user ''.
Przyczyna: Używasz sql.Open("sqlserver", ...) z parametrem fedauth . Uwierzytelnianie Entra ID wymaga nazwy sterownika azuresql, zarejestrowanej przez pakiet azuread. W przypadku standardowego sterownika sqlserver parametr fedauth jest ignorowany, a sterownik próbuje przeprowadzić uwierzytelnianie SQL bez podania nazwy użytkownika.
Rozwiązanie: Importuj azuread pakiet i użyj nazwy sterownika azuresql :
import _ "github.com/microsoft/go-mssqldb/azuread"
db, err := sql.Open("azuresql",
"sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
panic(err)
}
Aby uzyskać więcej informacji, zobacz Microsoft Entra ID authentication (Uwierzytelnianie za pomocą identyfikatora Entra firmy Microsoft).
Błędy zapytań
Poniższe sekcje dotyczą komunikatów o błędach wykonywania zapytań.
LastInsertId nie obsługiwany
Komunikat o błędzie: LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.
Rozwiązanie: Sterownik go-mssqldb nie obsługuje LastInsertId(). Użyj klauzuli OUTPUT lub zapytania SCOPE_IDENTITY() osobno.
Tabela tymczasowa nie znaleziona
Komunikat o błędzie: mssql: Invalid object name '#TempTable'.
Przyczyna: Tabele tymczasowe są przypisane do danego połączenia. Jeśli utworzysz tabelę tymczasową w jednym wywołaniu i odpytasz ją w innym, mogą one używać różnych połączeń z puli.
Rozwiązanie: Użyj db.Conn(ctx), aby przypiąć do jednego połączenia, lub wykonuj operacje w ramach transakcji.
Aby uzyskać więcej informacji, zobacz Procedury składowane.
Błędy Azure SQL
Poniższe sekcje dotyczą błędów specyficznych dla Azure SQL Database.
Numery błędów połączenia przejściowego
Użyj poniższej wspólnej listy jako punktu odniesienia dla przejściowych błędów podczas nawiązywania połączenia oraz awarii warstwy transportowej na ścieżce żądania, które kwalifikują się do ograniczonego ponawiania:
Następujące błędy są przejściowe, gdy występują podczas nawiązywania połączenia lub podczas wysyłania żądania do serwera. Ponów próbę na krótkim, ograniczonym wycofywaniu. Błędy, które utrzymują się po kilku ponownych próbach, zwykle wskazują problem z konfiguracją (niewłaściwy serwer, brakujące uprawnienia, wyczerpany limit przydziału), które ponawianie próby nie zostaną rozwiązane.
| Error | Message | Troubleshooting |
|---|---|---|
64 |
A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) |
Połączenie TCP zostaje przerwane w trakcie negocjacji. To nie jest błąd poświadczenia. Jeśli problem będzie się powtarzał, sprawdź, czy po stronie klienta nie występuje niestabilność sieci lub czy urządzenie pośredniczące nie zrywa połączeń na wpół ustanowionych. |
233 |
The client was unable to establish a connection because of an error during connection initialization process before login. |
Błąd transportu przed logowaniem lub błąd protokołu TLS. Serwer często zwraca go, gdy nie może zaakceptować połączenia (wyczerpanie zasobów, osiągnięto maksymalną liczbę połączeń lub nieobsługiwanego klienta). To nie jest błąd poświadczenia. Sprawdź kondycję serwera, a następnie sprawdź limit czasu logowania klienta, ustawienia protokołu TLS i zgodność wersji protokołu TLS klienta/serwera. |
4060 |
Cannot open database "%.*ls" requested by the login. The login failed. |
Logowanie uwierzytelnia się, ale nie może otworzyć żądanej bazy danych. Przejściowe przyczyny obejmują sytuacje, w których baza danych jest w trakcie zmiany stanu (przełączenie awaryjne, przywracanie, skalowanie) lub została automatycznie wstrzymana. Trwałe przyczyny (baza danych nie istnieje, konto logowania nie ma dostępu) nie zostaną usunięte przez ponowienie próby; sprawdź nazwę bazy danych, mapowanie konta logowania oraz stan bazy danych. |
4221 |
Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. |
Replika nie jest dostępna do logowania, ponieważ brakuje wersji wierszy dla transakcji, które były w locie podczas recyklingu repliki. Wycofaj lub zatwierdź aktywne transakcje na serwerze podstawowym, aby rozwiązać problem. Ogranicz to ryzyko, unikając długotrwałych transakcji zapisu na serwerze głównym. |
10053 |
A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) |
Strona lokalna zrywa połączenie. Sprawdź stan sieci po stronie klienta oraz lokalną zaporę lub klienta VPN. |
10054 |
A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) |
Po stronie zdalnej jest wysyłane resetowanie protokołu TCP. Typowe przyczyny: proces równorzędny uległ awarii, zapora wymusiła reset połączenia lub brama Azure SQL zamknęła bezczynne połączenie. W przypadku resetowania połączenia z powodu bezczynności włącz mechanizm TCP keepalive po stronie klienta lub skróć limit czasu bezczynności w puli połączeń. |
10928 |
Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. |
Baza danych przekracza limit nadzoru nad zasobami Azure SQL. Identyfikator zasobu 1 oznacza limit procesów roboczych; identyfikator zasobu 2 oznacza limit sesji. Zidentyfikuj typ limitu na podstawie komunikatu, a następnie zmniejsz współbieżność, zwiększ zasoby bazy danych lub skróć długotrwałe operacje blokujące zasób. |
10929 |
Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. |
Baza danych przekroczyła swoje minimalne gwarantowane zasoby, a serwer bazowy ogranicza jej wydajność. Ponowienie próby zwykle kończy się powodzeniem, gdy obciążenie sąsiada spadnie. Trwałe wystąpienia wskazują, że potrzebujesz wyższej warstwy usług lub mniej hałaśliwego środowiska. |
40020, 40143, 40166, 40540 |
Zgłoszone w Error code %d miejscu błędu 40197 podczas pracy w trybie failover. |
Podkody osadzone w komunikacie failover 40197, które w niektórych ścieżkach wykonania są zwracane jako kod błędu najwyższego poziomu. Traktuj je tak samo jak 40197. |
40197 |
The service has encountered an error processing your request. Please try again. Error code %d. |
Uaktualnienie oprogramowania, awaria sprzętu lub inne zdarzenie trybu failover w Azure SQL. Ponowne połączenie kieruje do sprawnej repliki. Wbudowany kod błędu identyfikuje typ przełączenia awaryjnego. Jeśli błąd będzie się powtarzać, przechwyć identyfikator śledzenia sesji i skontaktuj się z pomocą techniczną. |
40501 |
The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. |
Ograniczanie silnika Azure SQL Zalecane minimalne opóźnienie wynosi 10 sekund. Długotrwałe ograniczanie wydajności wskazuje, że obciążenie przekroczyło przydzielone zasoby bazy danych; przejdź na wyższą warstwę usługi lub zmniejsz współbieżność. |
40613 |
Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'. |
Baza danych jest niedostępna, zwykle w połowie trybu failover lub krótko podczas operacji skalowania. Ponów próbę po odczekaniu; jeśli problem będzie się utrzymywał dłużej niż kilka minut, zapisz identyfikator śledzenia sesji i otwórz zgłoszenie do działu pomocy technicznej. |
42108 |
Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. |
Dedykowana pula SQL (Synapse) jest wstrzymana. Ponowienie próby zakończy się powodzeniem dopiero po wznowieniu puli. Wznów pulę ręcznie lub zaplanuj uruchomienie obciążenia po wznowieniu puli. |
42109 |
The SQL pool is warming up. Please try again. |
Dedykowana pula SQL jest wznawiana. Ponów próbę w przypadku wycofywania, dopóki pula nie będzie w trybie online; rozgrzewka zwykle trwa kilka minut. |
49918 |
Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. |
Serwer nie może obecnie przydzielić wystarczającej ilości zasobów, aby spełnić żądanie. Ponów próbę z opóźnieniem. Jeśli błąd będzie się powtarzać, przeprowadź skalowanie w górę bazy danych lub elastycznej puli. |
49919 |
Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". |
Limit współbieżności na poziomie subskrypcji dla operacji zarządzania. Zmniejszenie równoległych wywołań tworzenia/aktualizacji lub ich rozłożenie. |
49920 |
Cannot process request. Too many operations in progress for subscription "%ld". |
Limit współbieżności na poziomie subskrypcji dla operacji w locie. Zmniejsz równoległość lub poczekaj, aż trwające operacje się zakończą. |
Błędów na poziomie instrukcji nie ma na tej liście, ponieważ występują po nawiązaniu połączenia, a awaria pozostawia sesję w stanie używalnym. Najczęstsze błędy instrukcji, które można ponowić, to 1205 (ofiara impasu) i 1222 (przekroczenie limitu czasu żądania blokady). Ponów całą transakcję zamiast pojedynczej instrukcji, która nie powiodła się.
Tekst komunikatu o błędzie pochodzi z błędów połączenia przejściowego Azure SQL. Poszczególne sterowniki utrzymują własne wbudowane listy ponawiania prób; W tym wykazie opisano, które błędy kwalifikują się do ponawiania próby między SQL Server, Azure SQL Database, Azure SQL Managed Instance, bazą danych SQL w Microsoft Fabric i dedykowanymi pulami SQL w programie Azure Synapse Analytics.
Nie można uzyskać dostępu do serwera (zapora)
Komunikat o błędzie: mssql: login error: Cannot open server '<server>' requested by the login. Client with IP address '203.0.113.42' is not allowed to access the server.
Przyczyny i rozwiązania:
- Twój adres IP klienta nie znajduje się w regułach zapory Azure SQL. Dodaj regułę zapory w portalu Azure: SQL server>Networking>Dodaj regułę zapory.
- Jeśli Twoja aplikacja działa w Azure, włącz opcję Zezwalaj usługom i zasobom Azure na dostęp do tego serwera.
- Aby uzyskać łączność prywatną, skonfiguruj prywatny punkt końcowy.
Osiągnięto limit zasobów
Komunikat o błędzie: mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.
Przyczyny i rozwiązania:
- Zbyt wiele łączeń równoczesnych dla poziomu Azure SQL. Zmniejsz wartość
MaxOpenConnsw konfiguracji puli. - Przecieki połączeń (niezamknięte wiersze lub transakcje). Sprawdź, czy nie ma zaginionych
defer rows.Close()lubdefer tx.Rollback()połączeń telefonicznych. - Wiele aplikacji współdzielących bazę danych. Podziel limit połączenia między wszystkich klientów.
Aby uzyskać ograniczenia połączeń Azure SQL według tier, zobacz Azure SQL Database.
Usługa jest obecnie przeciążona (ograniczanie przepustowości)
Komunikat o błędzie: mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.
Przyczyny i rozwiązania:
- Baza danych jest pod dużym obciążeniem. Zaimplementuj logikę ponawiania przy użyciu wycofywania wykładniczego.
- Obciążenie przewyższa pojemność DTU lub vCore danego poziomu. Rozważ skalowanie.
Aby poznać wzorce implementacyjne retry, zobacz Obsługa błędów i wzorce retry.
Baza danych niedostępna obecnie
Komunikat o błędzie: mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.
Przyczyna: Azure SQL rekonfiguruje bazę danych (operacja failover, aktualizacja lub skalowanie). Ten warunek jest błędem przejściowym.
Rozwiązanie: Spróbuj operacji ponownie. Baza danych zazwyczaj staje się dostępna w ciągu kilku sekund. Więcej informacji można znaleźć w artykule Obsługa błędów i wzorce ponownych prób.
Błędy połączenia
Błąd driver: bad connection oznacza, że sterownik wykrył, że istniejące połączenie nie jest już użyteczne. Pula database/sql automatycznie ponawia operację na świeżym połączeniu w przypadku wywołań nietransakcyjnych, ale operacje wewnątrz aktywnej transakcji kończą się natychmiast niepowodzeniem.
Nie zaczynaj od tej sekcji, jeśli aplikacja nigdy nie została pomyślnie połączona.
driver: bad connection Zazwyczaj oznacza ponowne użycie połączenia, przełączanie awaryjne, przerwę bezczynności lub przerwy w sieci po tym, jak początkowe połączenie już działało.
Typowe przyczyny
| Przyczyna | Typowy scenariusz | Napraw. |
|---|---|---|
| Limit czasu bezczynności bramy Azure SQL | Połączenie pozostaje bezczynne przez ponad 30 minut za bramą platformy Azure. | Ustaw db.SetConnMaxIdleTime(2 * time.Minute) tak, aby poddawał recyklingowi bezczynne połączenia, zanim brama je zamknie. |
| Przerwy w działaniu sieci | Przejściowe awarie sieci między klientem a serwerem. | Implementuj logikę powtórek dla operacji nietransakcyjnych. Zobacz Obsługa błędów. |
| Zakończenie sesji po stronie serwera | DBA zakończyło sesję lub serwer został zrestartowany. | Ponów próbę. Ustaw opcję db.SetConnMaxLifetime, aby rotować połączenia. |
| Rekonfiguracja usługi Azure SQL | Przełączenie awaryjne, skalowanie lub instalowanie poprawek spowodowały zerwanie połączenia. | Ustaw ConnMaxLifetime na 5 minut lub mniej. Zaimplementuj logikę ponawiania prób. |
| Limit czasu dla długotrwałej transakcji | Azure SQL zakończył sesję (błąd 40549). | Utrzymuj transakcje krótkie. Podziel duże operacje na mniejsze partie. |
Jak baza danych/SQL radzi sobie ze złymi połączeniami
Dla wywołań poza transakcją (db.QueryContext, db.ExecContext), pula database/sql automatycznie ponawia operację przy użyciu nowego połączenia, gdy sterownik zgłasza nieprawidłowe połączenie. To ponowienie próby jest niewidoczne dla twojego kodu.
W przypadku wywołań wewnątrz transakcji (tx.QueryContext, tx.ExecContext) pula nie może ponowić próby, ponieważ stan transakcji zostaje utracony. Twój kod musi wychwycić błąd, cofnąć się i ponownie spróbować całej transakcji.
Zalecane ustawienia puli dla Azure SQL
Konfiguruj pulę tak, aby obsługiwała timeouty i failovery bram Azure:
db.SetConnMaxLifetime(5 * time.Minute) // Rotate connections to recover from failovers.
db.SetConnMaxIdleTime(2 * time.Minute) // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10) // Keep warm connections for quick recovery.
db.SetMaxOpenConns(20) // Stay below your tier's connection limit.
W przypadku lokalnego programu SQL Server ConnMaxIdleTime jest mniej istotny, ponieważ nie ma limitu czasu bezczynności bramy. Jednak ustawienie tego zapobiega nietrwałym połączeniom po zakłóceniach sieci.
Szczegółowe wskazówki dotyczące konfiguracji znajdziesz w Azure SQL Database.
Wyczerpanie basenu
Wyczerpanie puli występuje, gdy wszystkie połączenia w puli są zajęte, a nowi dzwoniący blokują się czekając na połączenie.
Symptoms
- Żądania zwalniają lub wygasają pod obciążeniem.
-
db.Stats().WaitCountrośnie nieustannie. -
db.Stats().InUserówna sięMaxOpenConns. - Termin kontekstowy przekraczał błędy podczas szczytowego ruchu.
Diagnoza
Dodaj monitorowanie puli do swojej aplikacji:
stats := db.Stats()
log.Printf("Pool: open=%d inUse=%d idle=%d waitCount=%d waitDuration=%v",
stats.OpenConnections, stats.InUse, stats.Idle,
stats.WaitCount, stats.WaitDuration)
Typowe przyczyny i rozwiązania
| Przyczyna | Jak rozpoznać problem | Napraw. |
|---|---|---|
rows.Close() nie wywołano |
InUse rośnie z czasem, nigdy nie maleje. |
Dodaj defer rows.Close() po każdym QueryContext. |
| Długotrwałe transakcje |
InUse utrzymuje wysoki poziom podczas przetwarzania wsadowego. |
Utrzymuj transakcje krótkie. Przetwarzaj duże partie w mniejszych częściach. |
MaxOpenConns za nisko |
WaitCount rośnie systematycznie pod normalnym obciążeniem po wykluczeniu przypiętych zasobów i wycieków. |
Zwiększ wartość MaxOpenConns. |
MaxOpenConns nie ustawiono |
Setki otwartych połączeń przy skokowym obciążeniu. | Ustaw MaxOpenConns wartość ograniczoną. |
Wyciek goroutine podczas wywoływania db.Conn |
InUse rośnie bez odpowiadającego temu wzrostu liczby żądań. |
Upewnij się, że każdy db.Conn() wynik jest zamknięty przez defer conn.Close(). |
Szczegółowe wskazówki dotyczące konfiguracji puli połączeń można znaleźć w artykule Pula połączeń.
Diagnostyka wolnych lub zablokowanych zapytań
Ustaw limity czasu zapytań
Używaj terminów kontekstowych do wykrywania wolnych zapytań i zapobiegania zablokowanym wywołaniom SQL w wyniku przypinania połączeń i zatrzymywania wywoływaczy:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
rows, err := db.QueryContext(ctx, "SELECT * FROM LargeTable WHERE Status = @s",
sql.Named("s", "active"))
if err != nil {
// Check if the error was a timeout.
if ctx.Err() == context.DeadlineExceeded {
log.Println("Query exceeded 5-second timeout")
}
return err
}
defer rows.Close()
Pełny opis procesu badania wydajności, obejmującego Query Store, widoki DMV, analizę brakujących indeksów oraz testy porównawcze, można znaleźć w sekcji Dostrajanie wydajności.
Diagnostyka impasu
Komunikat o błędzie: mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Numer błędu: 1205
Rozwiązanie: Zastoje występują w systemach współbieżnych. Wprowadź automatyczną logikę powtórek dla błędu 1205. Dla funkcji otoczki martwego zablokowania ponownego próbowania, zobacz Transactions.
Strategie zapobiegania:
- Dostęp do tabel w tej samej kolejności dla wszystkich zapytań.
- Utrzymuj transakcje krótkie i unikaj interakcji z użytkownikami podczas transakcji.
- Użyj poziomu izolacji
READ COMMITTED SNAPSHOT, aby zmniejszyć rywalizację o blokady.
Powtarzające się blokady na tym samym zapytaniu wskazują na problem projektowy. Użyj grafu zakleszczenia (zarejestrowanego za pomocą Extended Events lub sesji kondycji systemu), aby zidentyfikować kolidujące instrukcje i typy blokad. Pełny poradnik znajdziesz w poradniku Deadlocks. Informacje o strategiach obsługi zakleszczeń w Go można znaleźć w Obsługa zakleszczeń oraz Radzenie sobie z zakleszczeniami.
Błędy certyfikatów przy kontenerach (wersje Go 1.23 i nowsze)
Komunikat o błędzie: x509: negative serial number
Przyczyna: Go 1.23 ściśle egzekwuje RFC 5280. Certyfikat z podpisem własnym generowany przez SQL Server w kontenerach Docker używa ujemnego numeru seryjnego, który Go odrzuca.
Rozwiązania:
- W środowiskach testowych dodaj
TrustServerCertificate=trueopcję pominięcia walidacji certyfikatów lubencrypt=disablecałkowite wyłączenie szyfrowania. - Dla CI/CD ustaw zmienną środowiskową
GODEBUG=x509negativeserial=1tak, aby przywróciła zachowanie sprzed Go 1.23 bez zmiany parametry połączenia. - W
go.mod(w wersjach Go 1.23 i nowszych) dodaj dyrektywęgodebug x509negativeserial=1, aby zastosować przesłonięcie podczas kompilacji.
Uwaga
Nie używaj TrustServerCertificate=true lub encrypt=disable na produkcji. Te opcje wyłączają kontrole bezpieczeństwa. Do produkcji używaj prawidłowo podpisanego certyfikatu.
Błędy certyfikatów SHA-1 (wersje Go 1.24 i nowsze)
Komunikat o błędzie: tls: handshake failure lub TLS Handshake failed: EOF podczas łączenia się ze starszymi instancjami SQL Server.
Przyczyna: Go 1.24 domyślnie zabrania algorytmów podpisu SHA-1 w certyfikatach TLS. Starsze wersje SQL Server oraz niektóre instalacje lokalne wykorzystują certyfikaty podpisane za pomocą SHA-1.
Rozwiązania:
- Ponownie wydaj certyfikat serwera z SHA-256 lub nowszym (zalecane).
- Ustaw zmienną środowiskową
GODEBUG=tlssha1=1, aby tymczasowo ponownie włączyć wsparcie SHA-1. - W
go.mod(wersjach Go 1.23 i nowszych) dodaj dyrektywęgodebug tlssha1=1.
Kiedy używać encrypt=disable, a kiedy TrustServerCertificate=true
| Ustawienia | Do czego służy | Kiedy stosować |
|---|---|---|
TrustServerCertificate=true |
Szyfruje ruch, ale pomija walidację certyfikatów. | Lokalne tworzenie i testowanie, gdzie serwer używa certyfikatu podpisanego samodzielnie. |
encrypt=disable |
Wysyła ruch w formacie jawnym (bez TLS). | Środowiska starsze, gdzie TLS nie jest dostępny. Nie polecam. |
encrypt=strict |
TDS 8.0 z pełną walidacją TLS z pierwszego bajtu. | Środowisko produkcyjne w SQL Server 2022 lub Azure SQL. |
Więcej informacji można znaleźć w sekcji Testowanie i szyfrowanie oraz certyfikaty.
Problemy z kodowaniem i sortowaniem
Ukryte ostrzeżenia o konwersji
Jeśli przekażesz string parametry (wysyłane jako nvarchar) do varchar kolumn, SQL Server wykonuje niejawną konwersję, która może uniemożliwić użycie indeksu.
Ten przykład kontynuuje konfigurację database/sql i mssql z wcześniejszych fragmentów tego artykułu.
Rozwiązanie: Zastosowanie mssql.VarChar dla varchar kolumn:
db.QueryContext(ctx, "SELECT * FROM Production.Product WHERE ProductNumber = @p1",
mssql.VarChar("FR-R92B-58"))
Błąd CharsetToUTF8 przy znakach niełacińskich
Komunikat o błędzie: CharsetToUTF8: ... podczas zapytania varchar kolumn zawierających znaki chińskie, japońskie lub inne niełacińskie zapisane w zestawieniu takim jak SQL_Latin1_General_CP1_CI_AS.
Przyczyna: Sterownik próbuje przekonwertować stronę kodową kolumny na UTF-8, ale przechowywane bajty nie odpowiadają oczekiwanemu kodowaniu w sortacji.
Rozwiązania:
- Używaj
nvarcharzamiastvarcharw przypadku kolumn przechowujących tekst niełaciński.nvarcharprzechowuje dane jako UTF-16 i unika konwersji stron kodowych. - Jeśli nie możesz zmienić typu kolumny, sprawdź, czy sortowanie bazy danych obsługuje zestaw znaków, który przechowujesz.
Włącz rejestrowanie diagnostyczne
Użyj parametru połączenia log , aby umożliwić logowanie na poziomie sterownika:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=63
Flagi dziennika to wartości maski bitowej: 1 (błędy), 2 (komunikaty), 4 (wiersze), 8 (SQL), 16 (parametry), 32 (transakcje), 64 (debugowanie). Łącz wartości, dodając je (na przykład 63 = wszystkie oprócz debugowania, 127 = wszystkie).
Do programowego logowania użyj SetLogger lub SetContextLogger. Zobacz Rejestrowanie i diagnostyka.
Lista kontrolna rozwiązywania problemów
| Objaw | Pierwszy krok |
|---|---|
| Odmowa połączenia | Sprawdź, czy SQL Server działa i że TCP/IP jest włączone. |
| Logowanie nie powiodło się | Sprawdź dane uwierzytelniające i tryb uwierzytelniania. |
| Błąd certyfikatu | Sprawdź certyfikat serwera lub ustaw TrustServerCertificate=true (tylko w środowisku deweloperskim). |
| Przekroczenie limitu czasu połączenia | Weryfikuj ścieżkę sieciową za pomocą Test-NetConnection. Sprawdzanie reguł zapory. |
| Zapora Usługi Azure SQL | Dodaj swój adres IP do reguł zapory Azure SQL. |
| Błędy ograniczania przepustowości | Wdróż mechanizm ponawiania prób z wykładniczym wydłużaniem odstępów. Przejdź na wyższy poziom. |
| Złe połączenie | Ustaw ConnMaxIdleTime poniżej 30 minut dla Azure SQL. Zaimplementuj logikę ponawiania prób. |
| Wyczerpanie basenu | Monitor db.Stats(). Napraw niezamknięte wiersze/transakcje. Zwiększ wartość MaxOpenConns. |
| Wolne zapytania | Ustaw limity czasu kontekstu. Pytaj DMV o drogie zapytania. |
| Deadlocks | Wprowadź powtórkę przy błędzie 1205. Dostęp do tabel w spójnej kolejności. |
| Niejawna konwersja | Użyj mssql.VarChar w przypadku kolumn varchar. |