Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel bietet Lösungen für häufige Fehler und Verbindungsprobleme mit dem go-mssqldb Treiber.
Fang mit den einfachsten Prüfungen an
Bevor Sie das Verbose-Logging aktivieren oder die Pool-Einstellungen ändern, arbeiten Sie sich die folgende Liste an:
- Überprüfen Sie die grundlegende Erreichbarkeit: Servername, Port, Firewall-Regeln und ob SQL Server oder Azure SQL Verbindungen akzeptiert.
- Überprüfen Sie die Authentifizierungseingaben: Treibername, Benutzername, Passwort, Domänenformat oder
fedauthKonfiguration. - Überprüfen Sie TLS-Einstellungen:
encrypt, Zertifikatspfade,hostnameincertificate, und obTrustServerCertificatesie für die Umgebung geeignet sind. - Erst wenn die Verbindung korrekt eingerichtet ist, sollten Sie die Erschöpfung des Verbindungspools, veraltete Verbindungen, die Wiederholungslogik sowie die Diagnose langsamer oder blockierter Abfragen untersuchen.
Verwenden Sie bei Fehlern bei der Einrichtung der Verbindung die ersten Abschnitte dieses Artikels. Verwenden Sie die späteren Abschnitte nur dann, wenn Verbindungen zumindest gelegentlich erfolgreich hergestellt werden und dann unter Last, nach einer Leerlaufzeit oder bei einem Failover ausfallen.
Verbindungsfehler
Die folgenden Abschnitte behandeln häufige verbindungsbezogene Fehlermeldungen und deren Lösungen.
TCP-Verbindung kann nicht geöffnet werden
Fehlermeldung: 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.
Ursachen und Lösungen:
- SQL Server läuft nicht. Starten Sie den SQL Server-Dienst.
- TCP/IP ist nicht aktiviert. Öffnen Sie den SQL Server-Konfigurations-Manager und aktivieren Sie TCP/IP unter den SQL Server Network Configuration>Protocols.
- Falscher Hafen. Verifizieren Sie den Port im SQL Server-Konfigurations-Manager oder verwenden Sie den SQL Server Browser für benannte Instanzen.
- Firewall blockiert den Port. Füge eine eingehende Regel für Port 1433 (oder deinen konfigurierten Port) hinzu.
Anmeldung für Benutzer fehlgeschlagen
Fehlermeldung: mssql: login error: Login failed for user '<user>'.
Ursachen und Lösungen:
- Falscher Benutzername oder Passwort. Überprüfe die Zugangsdaten.
- Die SQL Server-Authentifizierung ist deaktiviert. Aktivieren Sie SQL Server und den Windows-Authentifizierungsmodus in den Servereigenschaften.
- Der Login existiert nicht. Erstelle den Login in SQL Server.
- Der Login hat keinen Zugriff auf die Zieldatenbank. Datenbankzugriff gewähren mit
CREATE USER.
Fehler bei der Zertifikatüberprüfung
Fehlermeldung: TLS Handshake failed: x509: certificate signed by unknown authority
Ursachen und Lösungen:
- Der Server verwendet ein selbstsigniertes Zertifikat. Geben Sie den Zertifikatspfad mit dem Parameter
certificateoderserverCertificatean, oder setzen SieTrustServerCertificate=truenur für die Entwicklung. - Das CA-Zertifikat befindet sich nicht im System-Vertrauensspeicher. Füge das CA-Zertifikat dem OS-Trust Store hinzu oder gib es mit dem Parameter
certificatean. - Hostname stimmt nicht überein. Verwenden Sie
hostnameincertificate, um den erwarteten Namen im Zertifikat anzugeben.
Weitere Informationen finden Sie unter Verschlüsselung und Zertifikate.
Verbindungstimeout abgelaufen
Fehlermeldung: unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout
Ursachen und Lösungen:
- Probleme mit der Netzwerkverbindung. Vergewissern Sie sich, dass Sie den Server mit
telnet <server> 1433oderTest-NetConnection -ComputerName <server> -Port 1433erreichen können. - DNS-Auflösungsfehler. Überprüfen Sie, ob der Hostname korrekt aufgelöst wird.
- Erhöhen Sie
dial timeoutoderconnection timeoutin der Verbindungszeichenfolge.
Authentifizierungsfehler
Die folgenden Abschnitte behandeln Authentifizierungsfehlermeldungen.
NTLM-Authentifizierungsfehler
Fehlermeldung: NTLM authentication failed
Ursachen und Lösungen:
- Falsches Domain-Format. Verwenden Sie
DOMAIN\userim Parameteruser id. Im URL-Format kodiert man den Backslash als%5C. - Falsches Passwort. Überprüfen Sie das Domain-Passwort.
Kerberos-Authentifizierungsfehler
Fehlermeldung: krb5: cannot resolve KDC for realm
Ursachen und Lösungen:
-
/etc/krb5.conffehlt oder ist falsch konfiguriert. Überprüfen Sie, ob der[realms]Abschnitt die korrekte KDC-Adresse für Ihre Domain enthält. - Kein gültiges Ticket. Führen Sie
klistaus, um zu prüfen, ob ein gültiges Ticket vorhanden ist, oder führen Siekinitaus, um eines zu erhalten. - Keytab-Datei nicht gefunden. Überprüfen Sie den Pfad im Parameter
krb5-keytabfile.
Weitere Informationen finden Sie unter SQL Server und Windows-Authentifizierung.
Fehler bei der Microsoft Entra ID-Authentifizierung
Fehlermeldung: clientCredentialFromCert: error reading certificate: ... oder DefaultAzureCredential: failed to acquire a token
Ursachen und Lösungen:
- Falsche Client-ID, Mieter-ID oder Client Secret. Überprüfe die Werte in der Verbindungszeichenfolge oder in den Umgebungsvariablen.
- Die verwaltete Identität ist nicht auf dem Host konfiguriert. Verifizieren Sie die Identität im Azure-Portal.
- Fehlender
azureadPaketimport. Importieregithub.com/microsoft/go-mssqldb/azureadund benutze denazuresqlTreibernamen.
Weitere Informationen finden Sie unter Microsoft Entra ID-Authentifizierung.
Anmeldung fehlgeschlagen für Benutzer '' (leerer Benutzername)
Fehlermeldung: mssql: login error: Login failed for user ''.
Ursache: Sie haben sql.Open("sqlserver", ...) mit einem fedauth-Parameter verwendet. Die Entra ID-Authentifizierung erfordert den Treibernamen azuresql, der vom Paket azuread registriert wird. Beim Standardtreiber sqlserver wird der Parameter fedauth ignoriert und der Treiber versucht eine SQL-Authentifizierung ohne Benutzernamen.
Lösung: Importiere das azuread Paket und verwende den Treibernamen 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)
}
Weitere Informationen finden Sie unter Microsoft Entra ID-Authentifizierung.
Abfragefehler
Die folgenden Abschnitte behandeln Fehlermeldungen zur Abfrageausführung.
LastInsertId wird nicht unterstützt
Fehlermeldung: LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.
Lösung: Der go-mssqldb Treiber unterstützt LastInsertId()nicht . Verwenden Sie eine OUTPUT Klausel oder eine separate Abfrage SCOPE_IDENTITY() .
Temporäre Tabelle nicht gefunden
Fehlermeldung: mssql: Invalid object name '#TempTable'.
Ursache: Temporäre Tabellen sind pro Verbindung. Wenn du in einem Aufruf eine temporäre Tabelle erstellst und sie in einem anderen abfragst, werden dafür möglicherweise unterschiedliche Verbindungen aus dem Pool verwendet.
Lösung: Verwenden Sie db.Conn(ctx), um die Verbindung auf eine einzelne Verbindung zu binden, oder führen Sie Operationen in einer Transaktion aus.
Weitere Informationen finden Sie unter "Gespeicherte Prozeduren".
Azure SQL-Fehler
Die folgenden Abschnitte behandeln Fehler, die spezifisch für die Azure SQL-Datenbank sind.
Fehlernummern bei vorübergehenden Verbindungsfehlern
Verwenden Sie die folgende gemeinsame Liste als Referenz für vorübergehende Verbindungsaufstellungsfehler und Anfrage-Pfad-Transportfehler, die für begrenzte Wiederholungen zugelassen sind:
Die folgenden Fehler sind vorübergehend, wenn sie während der Verbindungseinrichtung oder beim Senden einer Anforderung an den Server auftreten. Versuchen Sie es mit einem kurzen, begrenzten Backoff. Fehler, die über einige Wiederholungen bestehen, weisen in der Regel auf ein Konfigurationsproblem hin (falscher Server, fehlende Berechtigungen, erschöpftes Kontingent), das nicht behoben werden kann.
| Fehler | Nachricht | 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.) |
Die TCP-Verbindung bricht während des Handshakes ab. Kein Anmeldefehler. Wenn sie weiterhin besteht, suchen Sie nach clientseitiger Netzwerkinstabilität oder einem Zwischengerät, das halb etablierte Verbindungen abbricht. |
233 |
The client was unable to establish a connection because of an error during connection initialization process before login. |
Transport- oder TLS-Fehler vor der Anmeldung. Der Server gibt sie häufig zurück, wenn sie die Verbindung nicht akzeptieren kann (Ressourcenausschöpfung, max. Verbindungen erreicht oder ein nicht unterstützter Client). Kein Anmeldefehler. Überprüfen Sie den Serverzustand und prüfen Sie dann die Anmeldezeitüberschreitung des Clients, die TLS-Einstellungen und die TLS-Version-Kompatibilität zwischen Client und Server. |
4060 |
Cannot open database "%.*ls" requested by the login. The login failed. |
Die Anmeldung authentifiziert sich, kann die angeforderte Datenbank aber nicht öffnen. Vorübergehende Ursachen sind unter anderem, dass sich die Datenbank in einem Übergangszustand befindet (Failover, Wiederherstellung, Skalierung) oder automatisch angehalten wurde. Persistente Ursachen (Datenbank ist nicht vorhanden, Anmeldezugriff fehlt) werden nicht durch Wiederholung behoben. Überprüfen Sie den Datenbanknamen, die Anmeldezuordnung und den Datenbankstatus. |
4221 |
Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. |
Das Replikat ist für die Anmeldung nicht verfügbar, da Zeilenversionen für Transaktionen fehlen, die im Test-Flight ausgeführt wurden, als das Replikat wiederverwendet wurde. Führen Sie ein Rollback aus, oder führen Sie einen Commit für die aktiven Transaktionen auf der primären Seite durch, um das Problem zu beheben. Abhilfe schaffen Sie, indem Sie lange Schreibtransaktionen auf der Primärinstanz vermeiden. |
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.) |
Die lokale Seite bricht die Verbindung ab. Überprüfen Sie die clientseitige Netzwerkintegrität und alle lokalen Firewalls oder VPN-Clients. |
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.) |
Die Gegenseite sendet einen TCP-Reset. Häufige Ursachen: der Peerprozess ist abgestürzt, eine Firewall hat ein Reset-Paket gesendet, oder das Azure SQL-Gateway hat eine inaktive Verbindung geschlossen. Aktivieren Sie für Idle-Reset-Muster tcp keepalive auf dem Client, oder kürzen Sie das Leerlauftimeout für den Verbindungspool. |
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. |
Die Datenbank überschreitet einen Grenzwert der Azure SQL-Ressourcensteuerung. Ressourcen-ID 1 gibt den Arbeitsgrenzwert an; Die Ressourcen-ID 2 gibt den Sitzungsgrenzwert an. Ermitteln Sie anhand der Meldung die Art der Begrenzung und verringern Sie dann die Parallelität, skalieren Sie die Datenbank hoch oder verkürzen Sie lang andauernde Vorgänge, die die Ressource belegen. |
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. |
Die Datenbank überschreitet ihre Mindestgarantie, und der zugrunde liegende Server drosselt die Leistung. Der Wiederholungsvorgang ist in der Regel erfolgreich, wenn die Benachbarte Last fällt. Dauerhafte Vorkommen deuten darauf hin, dass Sie eine höhere Dienstebene oder eine weniger laute Umgebung benötigen. |
40020, 40143, 40166, 40540 |
Gemeldet im Error code %d-Slot von Fehler 40197 während des Failovers. |
In eine 40197-Failovermeldung eingebettete Untercodes, die auf einigen Pfaden als Fehlernummer auf oberster Ebene erscheinen. Behandeln Sie sie genauso wie 40197. |
40197 |
The service has encountered an error processing your request. Please try again. Error code %d. |
Ein Softwareupgrade, Hardwarefehler oder ein anderes Failoverereignis in Azure SQL. Durch erneutes Verbinden werden Sie zu einem fehlerfreien Replikat weitergeleitet. Der eingebettete Fehlercode identifiziert den Failovertyp. Wenn der Fehler weiterhin besteht, erfassen Sie die Sitzungsablaufverfolgungs-ID, und wenden Sie sich an den Support. |
40501 |
The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. |
Drosselung der Azure SQL-Datenbank-Engine Die empfohlene Untergrenze für die Wartezeit beträgt 10 Sekunden. Eine dauerhafte Drosselung weist darauf hin, dass die Arbeitsauslastung die Ressourcenzuordnung der Datenbank überschritten hat; Skalieren Sie die Dienstebene, oder reduzieren Sie die Parallelität. |
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'. |
Die Datenbank ist nicht verfügbar, in der Regel mitten im Failover oder kurz während eines Skalierungsvorgangs. Versuchen Sie es nach einer Wartezeit erneut; wenn das Problem nach einigen Minuten weiterhin besteht, notieren Sie die Session-Trace-ID und eröffnen Sie einen Supportfall. |
42108 |
Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. |
Der dedizierte SQL-Pool (Synapse) befindet sich in einem angehaltenen Zustand. Der Wiederholungsversuch ist erst erfolgreich, nachdem der Pool wiederaufgenommen wurde. Nehmen Sie den Pool explizit wieder auf, oder planen Sie die Workload so, dass sie erst nach der Wiederaufnahme des Pools ausgeführt wird. |
42109 |
The SQL pool is warming up. Please try again. |
Der dedizierte SQL-Pool wird wieder aufgenommen. Wiederholen Sie einen Backoff, bis der Pool online ist. Das Aufwärmen dauert in der Regel ein paar Minuten. |
49918 |
Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. |
Der Server kann derzeit nicht genügend Ressourcen zuordnen, um die Anforderung zu erfüllen. Wiederholen Sie den Vorgang auf einem Backoff. Wenn der Fehler weiterhin besteht, skalieren Sie die Datenbank oder den elastischen Pool. |
49919 |
Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". |
Parallelitätsgrenze auf Abonnementebene bei Verwaltungsvorgängen. Reduzieren Sie parallele Erstellungs-/Aktualisierungsaufrufe oder führen Sie sie gestaffelt aus. |
49920 |
Cannot process request. Too many operations in progress for subscription "%ld". |
Parallelitätsgrenzwert auf Abonnementebene für Vorgänge in Flight. Reduzieren Sie die Parallelität, oder warten Sie, bis die laufenden Vorgänge abgeschlossen sind. |
Fehler auf Anweisungsebene befinden sich nicht in dieser Liste, da sie ausgelöst werden, nachdem die Verbindung hergestellt wurde und der Fehler die Sitzung nutzbar lässt. Die häufigsten Fehler bei Anweisungen, die erneut ausgeführt werden können, sind 1205 (Deadlock-Opfer) und 1222 (Zeitüberschreitung bei der Sperranforderung). Wiederholen Sie die gesamte Transaktion statt der einzelnen fehlerhaften Anweisung.
Fehlermeldungstext stammt aus Azure SQL vorübergehenden Verbindungsfehlern. Einzelne Treiber verwalten ihre eigenen integrierten Wiederholungslisten; in diesem Katalog wird beschrieben, welche Fehler in SQL Server, Azure SQL-Datenbank, Azure SQL Managed Instance, SQL-Datenbank in Microsoft Fabric und dedizierten SQL-Pools in Azure Synapse Analytics für Wiederholungen geeignet sind.
Server kann nicht geöffnet werden (Firewall)
Fehlermeldung: 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.
Ursachen und Lösungen:
- Deine Client-IP ist nicht in den Azure SQL-Firewall-Regeln enthalten. Füge eine Firewall-Regel im Azure-Portal hinzu: SQL Server>Networking>Füge eine Firewall-Regel hinzu.
- Wenn Ihre Anwendung in Azure ausgeführt wird, aktivieren Sie Azure-Diensten und -Ressourcen den Zugriff auf diesen Server erlauben.
- Für die private Verbindung konfigurieren Sie einen privaten Endpunkt.
Ressourcenbeschränkung erreicht
Fehlermeldung: mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.
Ursachen und Lösungen:
- Zu viele gleichzeitige Verbindungen für das Azure SQL-Tier. Senken Sie
MaxOpenConnsin Ihrer Pool-Konfiguration. - Verbindungslecks (nicht abgeschlossene Zeilen oder Transaktionen). Überprüfe, ob
defer rows.Close()- oderdefer tx.Rollback()-Aufrufe fehlen. - Mehrere Anwendungen teilen sich die Datenbank. Teilen Sie das Verbindungslimit auf alle Kunden auf.
Für Azure SQL-Verbindungsgrenzen nach Tier siehe Azure SQL-Datenbank.
Der Dienst ist derzeit ausgelastet (gedrosselt)
Fehlermeldung: mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.
Ursachen und Lösungen:
- Die Datenbank steht unter hoher Überlastung. Implementieren Sie eine Logik für Wiederholungsversuche mit exponentiellem Backoff.
- Die Arbeitslast übersteigt die DTU- oder vCore-Kapazität der Stufe. Erwäge eine Hochskalierung.
Für Retry-Implementierungsmuster siehe Error Handling und Retry Patterns.
Datenbank derzeit nicht verfügbar
Fehlermeldung: mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.
Ursache: Azure SQL konfiguriert die Datenbank neu (Failover-, Update- oder Skalierungsoperation). Diese Bedingung ist ein vorübergehender Fehler.
Lösung: Versuchen Sie die Operation erneut. Die Datenbank ist in der Regel innerhalb von Sekunden verfügbar. Weitere Informationen finden Sie unter Fehlerbehandlung und Wiederholungsmuster.
Schlechte Verbindungsfehler
Ein driver: bad connection Fehler bedeutet, dass der Treiber erkannt hat, dass eine bestehende Verbindung nicht mehr nutzbar ist. Der Pool database/sql versucht die Operation automatisch auf einer neuen Verbindung für nicht-transaktionale Aufrufe, aber Operationen innerhalb einer aktiven Transaktion schlagen sofort fehl.
Fang nicht mit diesem Abschnitt an, wenn die Anwendung nie erfolgreich verbunden wurde.
driver: bad connection dies weist in der Regel auf die Wiederverwendung der Verbindung, Failover, Leerlauf-Timeout oder Netzwerkunterbrechungen hin, nachdem die erste Verbindung bereits funktionierte.
Häufige Ursachen
| Ursache | Typisches Szenario | Beheben |
|---|---|---|
| Leerlaufzeitüberschreitung des Azure SQL-Gateways | Verbindung war 30+ Minuten im Leerlauf hinter dem Azure-Gateway. | Stellen Sie db.SetConnMaxIdleTime(2 * time.Minute) so ein, dass inaktive Verbindungen wiederverwendet werden, bevor das Gateway sie trennt. |
| Netzwerkunterbrechung | Vorübergehender Netzwerkausfall zwischen Client und Server. | Implementiere Wiederholungslogik für nicht-transaktionale Operationen. Weitere Informationen finden Sie unter Fehlerbehandlung. |
| Serverseitige Sitzungsbeendigung | DBA hat die Sitzung beendet oder der Server wurde neu gestartet. | Wiederholen. Stellen Sie db.SetConnMaxLifetime so ein, dass Verbindungen gedreht werden. |
| Azure SQL-Neukonfiguration | Failover-, Skalierungs- oder Patch-Evente haben die Verbindung abgebrochen. | Stell es auf 5 Minuten oder weniger ein.ConnMaxLifetime Implementieren Sie die Wiederholungslogik. |
| Langanhaltende Transaktionszeitsperre | Azure SQL beendete die Sitzung (Fehler 40549). | Halten Sie die Transaktionen kurz. Unterteilen Sie große Vorgänge in kleinere Batches. |
Wie Datenbank/SQL mit schlechten Verbindungen umgeht
Für Anrufe außerhalb einer Transaktion (db.QueryContext, db.ExecContext), versucht der Pool database/sql automatisch die Operation auf einer neuen Verbindung, wenn der Treiber eine fehlerhafte Verbindung meldet. Dieser Wiederholungsversuch ist für deinen Code transparent.
Für Aufrufe innerhalb einer Transaktion (tx.QueryContext, tx.ExecContext), kann der Pool nicht erneut versuchen, da der Transaktionszustand verloren geht. Dein Code muss den Fehler erkennen, zurückrollen und die gesamte Transaktion erneut versuchen.
Empfohlene Pool-Einstellungen für Azure SQL
Konfigurieren Sie den Pool so, dass er Azure-Gateway-Timeouts und Failovers verarbeitet:
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.
Bei lokal installiertem SQL Server ist ConnMaxIdleTime weniger kritisch, da es keine Leerlaufzeitüberschreitung des Gateways gibt. Die Aktivierung verhindert jedoch hängengebliebene Verbindungen bei Netzwerkunterbrechungen.
Für detaillierte Konfigurationsanleitungen siehe Azure SQL-Datenbank.
Erschöpfung des Pools
Pool-Erschöpfung tritt auf, wenn alle Verbindungen im Pool genutzt werden und neue Anrufer das Warten auf eine Verbindung blockieren.
Symptome
- Anfragen werden bei hoher Last langsamer oder es kommt zu Zeitüberschreitungen.
-
db.Stats().WaitCountwächst kontinuierlich. -
db.Stats().InUseentsprichtMaxOpenConns. - Die Kontextfrist überschritt die Fehler während der Spitzenverkehrszeit.
Diagnose
Fügen Sie Ihrer Anwendung Poolüberwachung hinzu:
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)
Häufige Ursachen und Lösungen
| Ursache | So identifizieren Sie | Beheben |
|---|---|---|
rows.Close() nicht aufgerufen |
InUse wächst mit der Zeit, nimmt aber nie ab. |
Fügen Sie nach jedem QueryContext ein defer rows.Close() hinzu. |
| Lang andauernde Transaktionen |
InUse Bleibt während der Chargenverarbeitung hoch. |
Halten Sie die Transaktionen kurz. Verarbeiten Sie große Mengen in kleineren Stücken. |
MaxOpenConns zu niedrig |
WaitCount wächst unter normaler Last stetig, nachdem gebundene Ressourcen und Lecks ausgeschlossen wurden. |
Erhöhe MaxOpenConns. |
MaxOpenConns nicht festgelegt |
Hunderte offene Verbindungen unter Spitzenbelastung. | Legen Sie für MaxOpenConns einen begrenzten Wert fest. |
Goroutine-Leck beim Aufruf von db.Conn |
InUse wächst, ohne dass die Anzahl der Anfragen entsprechend zunimmt. |
Stellen Sie sicher, dass jedes db.Conn() Ergebnis mit defer conn.Close()abgeschlossen ist. |
Für detaillierte Hinweise zur Poolkonfiguration siehe Connection Pooling.
Langsame oder blockierte Abfragediagnostik
Abfrage-Timeouts festlegen
Nutzen Sie Kontextfristen, um langsame Abfragen zu identifizieren und zu verhindern, dass blockierte SQL-Aufrufe Verbindungen festnageln und Anrufer verzögern:
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()
Für einen vollständigen Workflow zur Leistungsuntersuchung, einschließlich Abfragespeicher, DMVs, Analyse fehlender Indizes und Benchmarking, siehe Leistungsoptimierung.
Deadlock-Diagnostik
Fehlermeldung: mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Fehlernummer: 1205
Lösung: In gleichzeitigen Systemen treten Deadlocks auf. Automatische Wiederholungslogik für Fehler 1205 implementieren. Für eine Deadlock-Wiederholungs-Wrapper-Funktion siehe Transaktionen.
Präventionsstrategien:
- Zugreifen Sie auf Tabellen in derselben Reihenfolge über alle Abfragen hinweg.
- Halten Sie Transaktionen kurz und vermeiden Sie die Interaktion der Nutzer während der Transaktionen.
- Verwenden Sie die
READ COMMITTED SNAPSHOTisolation, um Sperrkonflikte zu reduzieren.
Wiederholte Deadlocks bei derselben Abfrage deuten auf ein Designproblem hin. Verwenden Sie den Deadlockgraphen (erfasst über Extended Events oder die Sitzung „system_health“), um die konkurrierenden Anweisungen und Sperrtypen zu ermitteln. Eine ausführliche Anleitung finden Sie im Deadlocks-Leitfaden. Für Deadlock-Handling-Strategien in Go siehe Deadlock-Handling und Handle Deadlocks.
Zertifikatsfehler bei Containern (Go 1.23 und spätere Versionen)
Fehlermeldung: x509: negative serial number
Ursache: Go 1.23 setzt RFC 5280 strikt durch. Das selbstsignierte Zertifikat, das SQL Server in Docker-Containern generiert, verwendet eine negative Seriennummer, die Go ablehnt.
Lösungen:
- Für Testumgebungen fügen Sie
TrustServerCertificate=truehinzu, um die Zertifikatsvalidierung zu überspringen, oderencrypt=disable, um die Verschlüsselung vollständig zu deaktivieren. - Für CI/CD setze die
GODEBUG=x509negativeserial=1Umgebungsvariable so, dass sie das Verhalten vor Go 1.23 wiederherstellt, ohne deine Verbindungszeichenfolge zu ändern. - In
go.mod(Go 1.23 und neueren Versionen) füge die Anweisunggodebug x509negativeserial=1hinzu, um die Überschreibung beim Build anzuwenden.
Achtung
Nicht verwenden TrustServerCertificate=true oder encrypt=disable in Produktion. Diese Optionen deaktivieren Sicherheitsprüfungen. Für die Produktion verwenden Sie ein ordnungsgemäß unterschriebenes Zertifikat.
SHA-1-Zertifikatsfehler (Go 1.24 und neuere Versionen)
Fehlermeldung: tls: handshake failure Oder TLS Handshake failed: EOF beim Verbinden mit älteren SQL Server-Instanzen.
Ursache: Go 1.24 erlaubt standardmäßig keine SHA-1-Signaturalgorithmen in TLS-Zertifikaten. Ältere SQL Server-Versionen und einige On-Premises-Installationen verwenden Zertifikate, die mit SHA-1 signiert sind.
Lösungen:
- Stellen Sie das Serverzertifikat mit SHA-256 oder neuer (empfohlen) neu aus.
- Stellen Sie die
GODEBUG=tlssha1=1Umgebungsvariable so ein, dass sie SHA-1-Unterstützung vorübergehend wieder aktiviert. - In
go.mod(Go 1.23 und neueren Versionen) füge eine Direktivegodebug tlssha1=1hinzu.
Wann encrypt=disable bzw. TrustServerCertificate=true verwendet werden sollte
| Konfiguration | Was es bewirkt | Wann verwenden? |
|---|---|---|
TrustServerCertificate=true |
Verschlüsselt den Datenverkehr, überspringt aber die Zertifikatsvalidierung. | Lokale Entwicklung und Testung, bei der der Server ein selbstsigniertes Zertifikat verwendet. |
encrypt=disable |
Sendet den Datenverkehr im Klartext (ohne TLS). | Legacy-Umgebungen, in denen TLS nicht verfügbar ist. Nicht empfohlen. |
encrypt=strict |
TDS 8.0 mit vollständiger TLS-Validierung ab dem ersten Byte. | Produktion auf SQL Server 2022 oder Azure SQL. |
Weitere Informationen finden Sie unter Testing und Verschlüsselung sowie Zertifikate.
Kodierungs- und Sortierungsprobleme
Warnungen vor impliziter Umwandlung
Wenn Sie stringParameter (übergeben als nvarchar) an varcharSpalten übergeben, führt SQL Server eine implizite Konvertierung durch, die die Verwendung von Indizes verhindern kann.
Dieses Beispiel setzt das database/sql Setup mssql aus früheren Ausschnitten dieses Artikels fort.
Lösung: Verwendung mssql.VarChar für varchar Spalten:
db.QueryContext(ctx, "SELECT * FROM Production.Product WHERE ProductNumber = @p1",
mssql.VarChar("FR-R92B-58"))
CharsetToUTF8-Fehler mit nicht-lateinischen Zeichen
Fehlermeldung: CharsetToUTF8: ... beim Abfragen von varchar Spalten, die chinesische, japanische oder andere nicht-lateinische Zeichen enthalten, die in einer Kollation wie SQL_Latin1_General_CP1_CI_AS gespeichert sind.
Ursache: Der Treiber versucht, die Codepage der Spalte in UTF-8 umzuwandeln, aber die gespeicherten Bytes entsprechen nicht der erwarteten Kodierung der Kollation.
Lösungen:
- Verwenden
nvarcharSie stattvarcharfür Spalten, die nicht-lateinischen Text speichern.nvarcharSpeichert Daten als UTF-16 und vermeidet Codepage-Konvertierung. - Wenn du den Spaltentyp nicht ändern kannst, prüfe, ob die Datenbank-Sortierung den Zeichensatz unterstützt, den du speicherst.
Diagnoseprotokollierung aktivieren
Verwenden Sie den Verbindungsparameter log , um das Logging auf Treiberebene zu ermöglichen:
sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=63
Log-Flags sind Bitmaskenwerte: 1 (Fehler), 2 (Nachrichten), 4 (Zeilen), 8 (SQL), 16 (Params), 32 (Transaktionen), 64 (Debugging). Kombinieren Sie Werte, indem Sie sie addieren (zum Beispiel 63 = alle außer Debug, 127 = alle).
Verwenden Sie für programmgesteuertes Logging SetLogger oder SetContextLogger. Siehe Protokollierung und Diagnose.
Checkliste zur Problembehandlung
| Symptom | Erster Schritt |
|---|---|
| Verbindung verweigert | Überprüfen Sie, ob der SQL Server läuft und TCP/IP aktiviert ist. |
| Fehler bei der Anmeldung | Überprüfe Zugangsdaten und Authentifizierungsmodus. |
| Zertifikatfehler | Überprüfe das Serverzertifikat oder die Einstellung TrustServerCertificate=true (nur Entwickler). |
| Verbindungstimeout | Verifizieren Sie den Netzwerkpfad mit Test-NetConnection. Überprüfen Sie die Firewall-Regeln. |
| Azure SQL Firewall | Füge deine IP zu den Azure SQL-Firewall-Regeln hinzu. |
| Drosselungsfehler | Implementiere Wiederholungsversuche mit exponentiell ansteigender Wartezeit. Skaliere die Stufe hoch. |
| Schlechte Verbindung | Setzen Sie ConnMaxIdleTime für Azure SQL auf unter 30 Minuten fest. Implementieren Sie die Wiederholungslogik. |
| Erschöpfung des Pools | Monitor db.Stats(). Beheben Sie nicht abgeschlossene Zeilen/Transaktionen. Erhöhe MaxOpenConns. |
| Langsame Abfragen | Timeouts für den Kontext festlegen. Fragen Sie bei DMVs nach teuren Anfragen. |
| Deadlocks | Wiederholung bei Fehler 1205 implementieren. Greifen Sie in einheitlicher Reihenfolge auf Tabellen zu. |
| Implizite Konvertierung | Verwenden Sie mssql.VarChar bei varchar Spalten. |