(Eine wahre Geschichte aus dem Maschinenraum der Datenintegration)

TL;DR

In Remote-Abfragen kontrollieren fünf unabhängige Timer den Ablauf: SSMS/SSIS-Timeout, SQL Server-remote query timeout, ODBC-Inaktivitäts-Timeout, MySQL-Server-Timeouts und Netzwerk-Idle-Timer. Kritische 10-Minuten-Abbrüche entstehen fast immer, weil SQL Server länger als 600 s auf die erste Datenzeile eines Linked-Server-Calls wartet – oft verschärft durch parallele SSIS-Tasks. Wer diese „First-Row-Uhr“ anpasst oder die Last serialisiert, eliminiert 90 % aller nächtlichen Timeout-Fehler.

1 | Einleitung

Freitag, 23:30 Uhr. Ich will gerade in den Feierabend starten, da ploppt in Teams eine rote Meldung auf: „SSIS-Paket abgebrochen, OLE DB-Fehler*“.
Merkwürdig: Öffne ich dieselbe Stored Procedure in SSMS und lasse sie laufen, zieht sie gemütlich ihre Daten über den Linked Server – 22 Minuten lang, aber ohne Murren. Warum bricht das SSIS-Paket nach exakt zehn Minuten ab, obwohl beide Wege dieselbe SP verwenden?

Nach einer Nacht mit Kaffee und vielen Recherchen kam das Aha-Erlebnis: Timeouts sind wie versteckte Zeitzünder – und jeder Client besitzt seinen eigenen.

2 | Fehlersymptome

SSIS meldet sporadisch

The OLE DB provider "MSDASQL" for linked server "XXXX" reported an error.
– meist nach 600 s (10 min).

SSMS führt exakt dieselbe Prozedur zuverlässig aus, egal ob das Remote-SELECT 5, 15 oder 25 Minuten dauert.

3 | Die Timeout-Landschaft – ein Rundgang durch alle Schichten

Damit ETL-Jobs aus SSIS, Ad-hoc-Abfragen in SSMS und Remote-SELECTs via Linked Server reibungslos zusammenspielen, muss man verstehen, auf welcher Stufe welcher Timer zuschnappt. Im Folgenden findest du die komplette “Timeout-Topografie” in Fließtext – vom äußeren Client bis in die Tiefen des ODBC-Treibers.


3.1 | Die Client-Ebene – wo alles beginnt

SSMS ist der geduldige Partyschreck: Standardmäßig steht sein Execution timeout auf 0 Sekunden – also unendlich. Der Client wartet, bis SQL Server fertig ist, ganz gleich ob das zehn Minuten oder zwei Stunden dauert.

In typischen .NET-Tools (PowerShell, C#, Python-pyodbc, …) sieht das anders aus:

  • ADO.NET hat ein Default-CommandTimeout von 30 Sekunden.
  • ODBC-Wrapper wie pyodbc erben diesen Wert oder setzen ihn hart auf 0 (keine Begrenzung), je nach API-Version.

Merke: Das Verhalten in SSMS ist also keine Garantie dafür, dass es in SSIS oder der eigenen App genauso lange durchhält.


3.2 | SSIS – der Regisseur deiner Pakete

Im Execute SQL Task (und ebenso in OLE DB- bzw. ADO.NET-Quellen eines Data Flows) gibt es den Property-Eintrag TimeOut.

  • 0 Sekunden heißt auch hier: SSIS selbst hat kein Limit.
  • Jeder andere Wert sorgt dafür, dass der SSIS-Runtime-Thread nach Ablauf dieser Frist den Task hart abbricht – selbst dann, wenn SQL Server noch fleißig Daten zieht.

Wichtig: Viele Organisationen stellen ihre SSIS-Templates auf 30 s oder 600 s (10 Min.) vorein – typisch für Timeouts, die man plötzlich nur noch in der nächtlichen Job-Historie wiederfindet.


3.3 | SQL Server – der Vermittler zum entfernten Daten­universum

Sobald SQL Server für dich Client wird (z. B. in OPENQUERY, OPENDATASOURCE oder EXEC(...) AT), greifen zwei Timer:

  1. connect_timeout des Linked Servers
    Wenn das TCP-Handshake zum entfernten System länger dauert als dieser Wert, bricht SQL Server ab.
    Standard: 10 Sekunden (wenn 0 eingetragen ist).
  2. query_timeout (pro Linked Server)
    Zeitspanne vom Senden des Befehls bis zum ersten Datenpaket, nicht den kompletten Transfer! Sobald die allererste Zeile ankommt, wird dieser Timer gestoppt.
    Fehlt ein expliziter Wert (0), zieht SQL Server den globalen Fallback aus
    sp_configure 'remote query timeout (s)' (600 s = 10 Min. ab Werk).

Wichtig: query_timeout / remote query timeout stoppen nicht den Download großer Resultsets. Sie schützen nur davor, dass der Remote-Server ewig für Parsing, Optimizer oder die erste Zeile braucht.

Damit ist klar: Auch wenn du SSIS auf „unendlich“ stellst, kann SQL Server nach exakt 600 s stoppen – es sei denn, du hebst entweder den globalen oder den lokalen Timer an. SSIS oder SSMS würden beide dann stoppen, wenn das erste Datenpaket (also mindestens die erste Zeile) nicht binnen der query_timeout Zeit ankommt.


Interpretation der Spalten

SpalteBedeutung
connect_timeout_secMax. Zeit für den Verbindungsaufbau zum Linked Server (0 = SQL-Standard 10 s).
query_timeout_secMax. Ab­lauf­zeit für Remote-Abfragen über OPENQUERY.
0 → nutze Fallback (global_remote_query_timeout_sec).
global_remote_query_timeout_secServerweite Vorgabe (Standard: 600 s). Wirkt nur, wenn query_timeout_sec = 0.

Dh. In diesem Fall ist der query_timout_sec = 0. Daher kommt es zum Fallback zum global_remote_query_timeout_sec = 600. Die Lösung besteht darin, entweder die serverweite Vorgabe oder die max. Ablaufzeit für Remote-Abfragen zu erhöhen.

3.4 | OLE DB-Provider & ODBC – das Nadelöhr im Unterholz

Sobald deine T-SQL-Anweisung über OPENQUERY, OPENDATASOURCE oder EXEC … AT in Richtung MySQL abbiegt, verlässt sie die heimische SQL-Server-Welt und wird von MSDASQL (OLE DB over ODBC) getragen. Ab hier übernimmt der MySQL Connector/ODBC die Regie – und genau dort verstecken sich die nächsten Stoppuhren.

3.4.1 | Die drei internen ODBC-Timer

ParameterDefault, wenn nicht gesetztMisst …Wann läuft er ab?
CONNECT_TIMEOUT0 s (unbegrenzt, OS-Timeout greift)Dauer des Verbindungsaufbaus (TCP-Handshake + Login)wenn die komplette Connect-Phase > Wert
READ_TIMEOUT0 s (unbegrenzt)Leerlauf­zeit zwischen zwei eingehenden Paketenwenn kein Paket innerhalb des Werts ankommt
WRITE_TIMEOUT0 s (unbegrenzt)Leerlauf­zeit zwischen zwei gesendeten Paketenwenn kein Paket innerhalb des Werts gesendet wird

Wichtig: Die Timeout-Parameter begrenzen nicht die Gesamtdauer des Transfers, sondern nur Inaktivitäts­phasen. Fließen kontinuierlich Daten, bleibt der Zähler immer wieder bei 0 stehen – auch nach Stunden.


3.4.2 | Warum Defaults oft trügerisch sind

  • Bei 0 s wartet der Treiber geduldig – echte Abbrüche kommen dann meist von außen:
    • Windows-TCP (Syn-Retries ≈ 21 s)
    • Firewalls/VPNs mit Idle-Cut (300–900 s)
    • MySQL-Server-Parameter wait_timeout / interactive_timeout
  • Das führt zu scheinbar „spontanen“ OLE DB-Fehlern: The OLE DB provider "MSDASQL" reported an error. The provider did not give any information. In Wirklichkeit hat eine Netz­komponente die Verbindung gekappt, weil 5 Minuten lang kein Paket kam – ODBC selbst hatte gar kein Limit.

3.4.3 | Wann und wie man eigene Werte setzt

Typische Ziele und Einstellungen

ZielSinnvolle WerteBeispiel-String
Schnell scheitern, wenn Host totCONNECT_TIMEOUT = 15 – 30…;CONNECT_TIMEOUT=20;…
Netz-Drops erkennen, lange Streams erlaubenREAD_TIMEOUT = 900 – 1800
WRITE_TIMEOUT = 900 – 1800
…;READ_TIMEOUT=1800;WRITE_TIMEOUT=1800;…
Harte Obergrenze für KomplettlaufGeht nur über SSIS-TimeOut, Job-Steuerung oder Anwendungscode

Eintragen kannst du die Parameter

  • im DSN-Dialog (Driver=…; … ;READ_TIMEOUT=1800;…)
  • oder direkt im Linked-Server-Provider String: DRIVER={MySQL ODBC 8.0 ANSI Driver}; SERVER=meinhost;PORT=3306;DATABASE=shop; UID=bi;PWD=***; CONNECT_TIMEOUT=20; READ_TIMEOUT=1800; WRITE_TIMEOUT=1800;

3.4.4 | Zusammenspiel mit SSIS und SQL Server

  1. Verbindungsaufbau
    • Greift CONNECT_TIMEOUT, bevor SQL Server auch nur ein Byte an MySQL schicken kann.
  2. Erste Zeile kommt ⇢ SQL-Server-query_timeout stoppt
    • Jetzt zählen nur noch ODBC-Leerlauf-Timer und der SSIS-Task-Timer.
  3. Kontinuierlicher Datenstrom
    • ODBC-Timer wird stetig neu gestartet.
    • Nur SSIS-TimeOut (oder deine eigene App-Logik) kann jetzt noch einen harten Schnitt setzen.

3.4.5 | Merksätze für die Praxis

  • 0 ≠ unendlich sicher – irgend­eine Netzschicht kann trotzdem kappen.
  • ODBC-Timeouts = Inaktivitäts-Grenzen, nicht Gesamt-Laufzeit-Grenzen.
  • Willst du wirklich nach z. B. 30 Minuten Schluss machen, brauchst du zusätzlich:
    • SSIS-TimeOut oder
    • eigene Logik im Aufrufer (C#, Python) oder
    • Job-Scheduler, der das Statement nach X Minuten killt.

Richtig konfiguriert sorgt das Dreigestirn aus Linked-Server-Timer → ODBC-Timeout → SSIS-Task-Timer dafür, dass weder Verbindungs­aufbau noch stundenlanges Warten auf Daten dein ETL-Fenster sprengt – und deine Nachtjobs bleiben grün.

Solange CONNECT_TIMEOUT, READ_TIMEOUT und WRITE_TIMEOUT im MySQL-ODBC-Treiber auf 0 stehen, arbeitet der Treiber selbst völlig passiv: Er startet keinen eigenen Countdown und löst daher keine Verbindungsabbrüche aus. Alle Timeouts, die dann noch auftreten, stammen entweder von SQL Server (z. B. query_timeout), vom SSIS-Task oder von externen Instanzen wie Firewalls, VPN-Gateways oder dem MySQL-Server selbst. Mit anderen Worten: Bleiben die ODBC-Defaults bei 0, kann der Treiber niemals der Täter sein – er wartet geduldig, bis jemand anderes die Verbindung kappt.


3.5 | MySQL-Server-Timeouts – die unsichtbare Brandmauer auf der Gegenseite

Auch der MySQL-Server selbst besitzt mehrere „Sicherungen“. Sie sind unabhängig von SQL Server, ODBC-Treiber oder SSIS und schlagen zu, sobald der Client zu lange inaktiv bleibt oder das Netz ins Stocken gerät. Wichtig: Diese Timer greifen identisch, egal ob du die Abfrage aus SSMS oder via SSIS/Linked Server ausführst – denn für MySQL ist beides nur eine TCP-Verbindung.

Server-VariableDefault¹Misst …Typischer AuslöserGreift nicht, wenn …
wait_timeout28 800 s (8 h)Idle-Zeit einer Non-Interactive Session (z. B. ODBC)Session liegt komplett brach – kein Query, kein Fetch, keine Keep-Aliveswährend ein SELECT … Result­sets liefert oder ein neues Query gesendet wird
interactive_timeout28 800 s (8 h)Idle-Zeit von mysql-CLI, Workbench …dito – aber nur für Sessions, die als “interactive” einloggenODBC- & Linked-Server-Logins werden als non-interactive behandelt
net_read_timeout30 sWie lange MySQL beim Lesen von Client-Paketen (z. B. INSERT … VALUES) wartetNetz bricht, Client sendet keine Daten mehrSELECT-Streaming vom Server → Client
net_write_timeout60 sWie lange MySQL beim Senden eines Pakets auf ACK vom Client wartetClient ruft Fetch nicht mehr ab / Netz-DropClient holt weiter Daten (mysql_fetch)
lock_wait_timeout8 sWie lange ein DML-Statement auf einen InnoDB-Lock wartetklassischer Deadlock / konkurrierende Updatesreine SELECTs; betrifft nur schreibende Queries

¹ Distributionsabhängig – MariaDB & einige Applikations-Stacks liefern geringere Defaults (oft 300 s).


3.5.1 | Wann schlagen diese Timer zu?

  1. Zwischen zwei Abfragen
    Führt deine SP erst DELETE, dann nach fünf Stunden INSERT aus und die Connection bleibt dazwischen völlig ruhig, kann wait_timeout zuschnappen.
  2. Bei Fetch-Unterbrechungen
    Bleibt der Client 65 s lang stehen (größer net_write_timeout = 60 s) und ruft das nächste Resultset-Paket nicht ab, beendet MySQL die Session.
  3. Bei Lock-Warteschlangen
    Schreibt dein Query und trifft auf einen gesperrten Datensatz, wird es nach lock_wait_timeout abgebrochen.

3.5.2 | Warum merkt man sie oft nicht?

  • Lange SELECT-Streams sind „aktiv“
    Während MySQL Pakete verschickt und der Client (ODBC) sie brav abholt, gilt die Verbindung nicht als idle – wait_timeout und interactive_timeout werden fortlaufend zurückgesetzt.
  • ODBC liest kontinuierlich
    Selbst wenn das SSIS-Buffering nur alle paar Sekunden einen Block anfordert, liegt die Lese-Pause fast nie über 30/60 s; somit feuern net_*_timeout nicht.
  • SSMS vs. SSIS – kein Unterschied
    Beide nutzen dieselbe TCP-Verbindung, d. h. MySQL behandelt sie identisch. Schlägt einer dieser Timer zu, siehst du denselben Fehler in SSMS und im SSIS-Log („MySQL server has gone away“ oder generischer OLE DB-Error).

3.5.3 | Kann eine SP „stundenlang“ laufen, ohne dass MySQL-Timeouts greifen?

Ja – solange einer dieser Fälle zutrifft:

  1. Der erste Row-Chunk wird schnell gesendetnet_write_timeout startet immer neu.
  2. Der Client holt Pakete regelmäßig ab → keine 60-s-Lücke → net_write_timeout läuft nie voll.
  3. Zwischen zwei Queries ist nie > 8 h Idlewait_timeout bleibt unberührt.

Folge: Eine Stored Procedure kann problemlos 45, 60 oder 120 Minuten Resultsets übertragen, ohne dass MySQL die Sitzung schließt. Passiert das, liegt es nicht an wait_timeout, interactive_timeout oder net_*_timeout, sondern an einem kleineren Timer oberhalb (SSIS-TimeOut, ODBC-READ_TIMEOUT, Firewall-Idle).


3.5.4 | Wann lohnt es sich, MySQL-Timeouts anzupassen?

SzenarioEmpfehlung
ETL-Jobs mit vielen Mini-Queries und langen Pausenwait_timeout hochdrehen (z. B. 200 000 s)
Instabile VPNs ↔ Keep-Alive benötigtnet_write_timeout auf 120 s erhöhen, TCP-Keep-Alive aktivieren
Deadlock-Spiralen bei Mass-Updateslock_wait_timeout erhöhen oder Abfrage neu designen

Merksatz

„Wirft deine SP nach zwei Stunden keinen ‘MySQL server has gone away’, kannst du die MySQL-Timeouts als Ursache abhaken – der Disconnect kam dann von einer höheren Ebene.“

Damit weißt du, dass MySQL-Timeouts zwar existieren, aber in den meisten laufenden Fetch-Sessions weder SSMS- noch SSIS-Aufrufe frühzeitig abschneiden – die echten Show-Stopper sitzen meist davor.

3.6 | Netzwerk-Schicht – wenn die Leitung selbst den Stecker zieht

3.6.1 | Idle-Timer in Firewalls, VPN-Gateways und Proxys

Die meisten modernen Netz­komponenten sind “stateful”: Sie merken sich jede TCP-Session und werfen sie aus der Tabelle, sobald zu lange kein Paket mehr fließt. Die Standard-Grenzen liegen je nach Hersteller bei 300 – 900 Sekunden (5 – 15 Minuten).

GerätetypTypische Idle-EinstellungBemerkung
Unternehmens-Firewall (Fortigate, Palo Alto, Check Point)600 soft pro Service konfigurierbar, z. B. “TCP / 3306 (MySQL)”.
NAT-Router / Heim-Firewall300 – 600 sConsumer-Firmware killt Sessions aggressiver.
SSL-VPN / IPSec-Gateway600 – 900 sParameter heißen meist Session-Timeout oder Idle-Timeout.
HTTP(S)-Proxy60 – 300 sWeb-Proxys erkennen MySQL nicht, beenden „unbekannte“ lange Leerlaufverbindungen oft früher.

Sobald der Idle-Timer zuschlägt, schickt das Gerät ein TCP-RST oder verwirft still Pakete – auf SQL-Server-Seite liest du dann Meldungen wie “Communication link failure” oder OLE DB error 0x80004005. SSMS und SSIS reagieren identisch, weil beide auf dieselbe TCP-Strecke angewiesen sind.


3.6.2 | Windows TCP-Keep-Alive – der stille Lebensretter (oder Schlafmütze)

Windows sendet erst nach 7 200 Sekunden (2 h) das erste Keep-Alive-Probe‐Paket – viel zu spät für ETL-Jobs, bei denen Netzgeräte nach 10 Minuten dichtmachen.

Registry-KeyDefaultSinnvolle Werte für ETL
HKEY_LOCAL_MACHINE\System\CurrentControlSet\
Services\Tcpip\Parameters\TcpKeepAliveTime
7 200 000 ms (2 h)600 000 ms (10 min)
TcpKeepAliveInterval1 000 ms1 000 ms (belassen)
TcpMaxDataRetransmissions53–5

Achtung: Änderung erfordert Neustart des Servers oder Neustart des SQL-Dienstes.

Alternativ kann man in MySQL einen regelmäßigen SELECT 1 über mysql_ping() auslösen oder auf VPN-Ebene Ping-Pakete konfigurieren (OpenVPN ping 30, IPSec DPD).


3.6.3 | Strategien gegen Netz-Timeouts

  1. Idle-Timer hochdrehen
    – Netzwerk-Team bitten, den “TCP 3306”-Timer der Firewall auf 3 600 s zu setzen.
  2. Keep-Alive verkürzen
    – Windows-Registry anpassen oder ODBC-Option OPT_CONNECT_ATTR_MARK_AS_INTERACTIVE=1 (MySQL 8.0.26+) nutzen, damit der Client eigene Pings sendet.
  3. Heartbeat-Query
    – Im SSIS-Package nach jedem großen Batch EXEC sp_executesql N'SELECT 1' AT LL3_AOTG_SLAVE; ausführen.
  4. VPN-Tuning
    – OpenVPN: ping 30 ping-restart 360
    – Cisco AnyConnect: ClientIdleTimeout, DPDInterval erhöhen.

3.6.4 | Fehlersuche

  1. Zeitstempel‐Vergleich
    Log‐Zeitpunkt Abbruch minus letztes Paket im WireShark ≈ 300 – 900 s → Indiz für Firewall-Idle.
  2. SQL-Error-Text TCP Provider: An existing connection was forcibly closed by the remote host – passt zu Netz-RST.
  3. Wireshark‐Trace
    • Siehst du ein RST von einer Firewall-IP? → Session wurde entsorgt.
    • Nur Retransmissions ohne Antwort? → Idle-Drop, Firewall verwirft still.

3.6.5 | Fazit

Wer länger als zehn Minuten in völliger Stille über dieselbe TCP-Session schweigt, wird von modernen Netzen als „tote Leitung“ entsorgt.

Deshalb: Entweder Pakete am Leben halten (Keep-Alive, Heartbeat-Query) oder die Netz-Timer anheben. Dann ist selbst ein zweistündiger Select-Stream kein Problem – egal, ob du ihn aus SSMS, SSIS oder einem sonstigen Client startest.


3.7 | Wer gewinnt? – Die Reihenfolge der Abbrüche

  1. Kleinstes Timeout siegt: Greift ein ODBC-READ_TIMEOUT bei 300 s, dann erlebt weder SSIS noch SQL Server den Abbruch des Linked-Server-Timers.
  2. Fehlermeldungen verketten sich: ODBC schickt „Client lost in connection-time­out“, MSDASQL verwandelt es in „provider did not give information“, SQL Server meldet Msg 7399, SSIS zeigt nur noch „OLE DB error“.
  3. SSMS bleibt stoisch – solange SQL Server einen Fehler bekommt, meldet er ihn brav zurück, aber SSMS bricht selbst nicht ab, wenn sein Timeout = 0 ist.

3.8 | Best-Practice-Matrix

SchichtEmpfohlener Wert bei >15-Min-Abfragen
SSIS‐Task TimeOut1 800 s oder 0 (unbegrenzt)
Linked Server query_timeout≥ 1 800 s
Linked Server connect_timeout30 s
MySQL ODBC READ/WRITE_TIMEOUT≥ 1 800 s
Global remote query timeoutReserve, > 1 800 s oder unverändert lassen

Damit liegt der kleinste Timer bei ≥1 800 s, alle höheren Schichten haben keinen Grund, vorher abzubrechen.


3.9 | Kurz zusammengefasst

Ein Data-Flow reist von SSIS über OLE DB/ODBC, durch SQL Server, weiter zum Linked Server, dann zum MySQL-Treiber und landet schließlich auf dem MySQL-Server. Jeder Abschnitt verfügt über einen eigenen „Sicherungsautomaten“. Kenne und justiere jeden einzelnen – sonst wirst du immer dort gestoppt, wo der Timer am kleinsten eingestellt ist.

Und das Beste: Hat man alle Schalter im Griff, verwandeln sich nächtliche Timeout-Fehler in friedliches Job-Grün – ganz ohne zusätzliche Kaffeerationen.

4 | Warum SSMS nicht meckert, SSIS aber schon?

(und wann die 600-Sekunden-Bombe trotzdem in beiden hochgeht)

Auf den ersten Blick existiert nur eine einzige Stellschraube, bei der sich SSMS und SSIS unterscheiden:

EbeneSSMSSSIS
Client-TimerExecution time-out (GUI) → Standard 0 s = unbegrenztExecute SQL Task → TimeOut → frei wählbar (oft 30 s / 600 s / 0 s)

Alle anderen Schrauben – query_timeout, remote query timeout (s), ODBC-Timeouts, MySQL-Timeouts, Firewall-Idle-Timer – wirken identisch auf jede T-SQL-Session, egal von welchem Client sie stammt.

Das Aber: parallele Workloads in SSIS

SSMS führt gewöhnlich nur eine Abfrage gleichzeitig aus. In SSIS dagegen laufen häufig mehrere Execute-SQL-Tasks oder Data-Flows parallel – etwa, um gleichzeitig verschiedene DataAreas vom MySQL-Server zu ziehen. Genau dadurch verschiebt sich das Zeitfenster „bis zur ersten Zeile“ in kritische Bereiche:

  1. Linked-Server-Thread-Pool
    MSDASQL kann nur eine begrenzte Zahl gleichzeitiger Requests abarbeiten. Hält Task A schon einen Provider-Thread, muss Task B warten – während SQL Server die 600-s-Uhr (remote query timeout) schon zählt.
  2. MySQL-Optimizer-/Lock-Stau
    Mehrere schwere Queries konkurrieren um Disk IO, InnoDB-Buffer oder Locks. Der letzte Task in der Schlange braucht womöglich > 600 s, ehe MySQL überhaupt das erste Paket losschickt.
  3. Folge:
    • Bei SSMS tritt dieser Fall selten auf → eine Session, eine Uhr, meistens < 600 s bis Row 1.
    • Bei SSIS kann ein einzelner Task die First-Row-Hürde (600 s Standard) reißen, obwohl sein TimeOut = 0 ist. SQL Server löst dann remote query timeout aus, SSIS meldet einen OLE DB-Fehler.

Was tun?

  • Last serialisieren
    SSIS → Package Properties → MaxConcurrentExecutables = 1 oder Tasks in Sequenz-Containern nacheinander ausführen.
  • query_timeout erhöhen
    EXEC sp_serveroption 'XXX', 'query timeout', 1800; -- 30 min
  • MySQL-Abfragen optimieren / Indizes setzen, damit die erste Zeile schneller kommt.

So bleibt die einzige echte Differenz – der Client-Timer – unter Kontrolle, und die 600-Sekunden-Bombe explodiert weder in SSIS noch in SSMS.

5 | Fazit – Wer (und was) in einer Remote-Abfrage wirklich das Sagen hat

Timeout-Probleme sind selten das Ergebnis einer fehlkonfigurierten Option – sie entstehen, weil viele unabhängige Uhren in einer langen Kette „tick-tack“ sagen. Erst wenn du jede einzelne kennst, lassen sich ETL-Jobs dauerhaft stabilisieren.

5.1 | Nur eine echte Differenz zwischen SSMS und SSIS

  • SSMS-Execution-Time-out (GUI) vs. SSIS‐Task-TimeOut: Das ist die einzige Stellschraube, bei der sich die Clients bewusst unterscheiden.
  • Alle übrigen Timer – query_timeout, ODBC-Inaktivitäts-Timer, MySQL-Idle-Timer, Firewall-Idle-Timer – arbeiten client-agnostisch.

5.2 | SQL Servers 600-Sekunden-Regel

remote query timeout (und sein Linked-Server-Pendant) misst nur die Zeit bis zum ersten Datenpaket. Kommt innerhalb von 10 Minuten ein Row-Header, ist der Countdown abgehakt.
Erst wenn der Optimizer/Lock/Thread-Stau länger als 600 s dauert, fliegt die Session – egal ob SSMS oder SSIS.

5.3 | Warum SSIS öfter scheitert als SSMS

Mehrere parallele Tasks teilen sich Provider-Threads, ODBC-Verbindungen und MySQL-Ressourcen. Der „letzte“ Task bekommt seine erste Zeile zu spät, trifft auf die 600-Sekunden-Grenze und bricht ab. SSMS, das gewöhnlich solistisch arbeitet, erlebt diesen Grenzfall kaum.

5.4 | ODBC-Defaults sind kein Geheimbomber

CONNECT_TIMEOUT = 0, READ_TIMEOUT = 0, WRITE_TIMEOUT = 0 bedeuten: Der Treiber kappt niemals selbst die Leitung. Wenn trotzdem ein Verbindungsfehler auftritt, kommt er von SQL Server, vom Netzwerk oder vom MySQL-Server.

5.5 | MySQL- und Netzwerk-Timer sind Idle-Wächter

  • wait_timeout, interactive_timeout, net_*_timeout greifen nur bei Pausen – nicht während aktiver Streams.
  • Firewalls und VPNs schmeißen «tote» Sessions gerne nach 5–15 Minuten raus, sofern keine Keep-Alives oder Heartbeat-Queries laufen.
  • Windows-Keep-Alive ist mit 2 h oft zu träge.

5.6 | Stabilitäts-Checkliste

  1. Serialisiere oder dosiere parallele MySQL-Zugriffe in SSIS.
  2. Erhöhe query_timeout/remote query timeout nur dann, wenn das Pre-Fetch-Fenster regelmäßig > 600 s ist.
  3. Setze ODBC-Timeouts (READ/WRITE) sinnvoll, aber erwarte keine Gesamt-Laufzeit-Grenze davon.
  4. Aktiviere Keep-Alives oder Heartbeats, wenn Firewalls Sessions kappen.
  5. Optimiere MySQL-Abfragen und Indizes, damit die erste Zeile schnell kommt.

Quintessenz

Zeitüberschreitungen sind ein Staffellauf, kein Sprint.
Jeder Timer hält seinen Stab nur so lange, bis er ihn weiter­gibt – oder fallen lässt. Wer alle Übergaben kennt, sprintet durch die Nachtjobs, ohne dass ein Stab zu Boden geht.

Beherrschst du die gesamte Timeout-Topografie – vom SSIS-Task über remote query timeout, ODBC-Idle-Timer, MySQL-Server-Parameter bis hin zu Firewall-Idle – werden deine Datenpipelines nicht mehr zufällig nach zehn Minuten stolpern, sondern zuverlässig dort ankommen, wo du sie haben willst: im Data Warehouse und im grünen Status-Feld deiner Job-Überwachung.