High severityresource
MySQL Error:
1436
What does this error mean?
MySQL Error 1436 wordt gegenereerd wanneer een stored procedure, functie of query meer stack-ruimte verbruikt dan de thread_stack parameter toestaat. Elke MySQL-thread krijgt bij verbinding een vaste hoeveelheid stack-geheugen toegewezen; recursieve aanroepen, diep geneste subqueries en complexe parse-trees stapelen stack-frames op tot die limiet bereikt is. In een data-pipeline ziet de engineer dit typisch als een abrupte fout in een ADF Stored Procedure-activiteit of een dbt run die een model aanroept dat intern een procedure uitvoert — de query wordt niet afgebroken door een timeout maar door een harde stack-overflow diep in de MySQL-engine.
Common causes
- 1Recursieve stored procedures zonder exitconditie of met een te diepe maximale recursie: elke aanroep van CALL zichzelf plaatst een nieuw stack-frame; bij een recursie van honderden niveaus overschrijdt dit al snel de standaard 1 MB thread_stack op MySQL 8.0.
- 2Complexe query-parse-trees met tientallen geneste subqueries of meerdere niveaus van CTE-verwijzingen: MySQL's parser en optimizer bouwen interne bomen die stack-ruimte vergen; een query met 15+ geneste selects kan de stack overbelasten nog vóór de executiefase.
- 3thread_stack staat te laag ingesteld in my.cnf — op oudere installaties of managed services (Cloud SQL, RDS met custom parameter groups) staat de waarde soms nog op 192K of 256K, terwijl moderne workloads met JSON-functies en window-functies beduidend meer stack vragen.
- 4Triggers die stored procedures aanroepen die zelf weer triggers activeren: een INSERT-trigger roept CALL proc_a() aan, proc_a doet een INSERT die trigger_b activeert — deze indirecte recursie is moeilijk te zien maar verbruikt stack even snel als directe recursie.
- 5Gebruik van GROUP_CONCAT of JSON_TABLE met zeer diepe nesting in combinatie met recursieve CTEs (WITH RECURSIVE): de combinatie van een recursieve CTE en een complexe aggregatie kan de optimizer dwingen tot een diepere interne call-stack dan elk afzonderlijk zou veroorzaken.
- 6Stored functions aangeroepen vanuit een view die op zijn beurt wordt gebruikt in een andere view: MySQL evalueert views door ze te inlinen; bij meerdere lagen van view-views-met-functies groeit de parse-stack onverwacht.
- 7ADF Copy-activiteiten met een stored procedure als pre/post-SQL die op het production-schema draait terwijl datzelfde schema recursieve triggers heeft — de combinatie van ADF-timing en trigger-recursie reproduceert de fout alleen onder load.
How to fix it
- 1Stap 1 — Verhoog thread_stack in my.cnf: voeg onder [mysqld] de regel `thread_stack=512K` toe (of `thread_stack=1M` voor zware workloads). Verifieer de actieve waarde zonder herstart via `SHOW VARIABLES LIKE 'thread_stack';`.
- 2Stap 2 — Herstart MySQL om de nieuwe waarde actief te maken: `sudo systemctl restart mysql`. Op managed services (RDS, Cloud SQL) pas je de parameter group of database flag aan en trigger je een reboot via de console of CLI: `aws rds reboot-db-instance --db-instance-identifier <id>`.
- 3Stap 3 — Identificeer de recursieve procedure: voer `SHOW PROCESSLIST;` uit tijdens de fout of bekijk de slow query log. Zoek naar de procedurenaam in de error-tekst: `ERROR 1436 (HY000): Thread stack overrun: <X> bytes used of a <Y> byte stack`. De procedurenaam staat vaak in de call-stack direct erna.
- 4Stap 4 — Refactor recursieve procedures naar iteratieve logica: vervang de recursieve CALL door een WHILE-loop met een tijdelijke tabel als werkvlak. Voorbeeld: `CREATE TEMPORARY TABLE _queue (id INT); INSERT INTO _queue VALUES (root_id); WHILE (SELECT COUNT(*) FROM _queue) > 0 DO ... END WHILE;` — dit verbruikt O(1) stack ongeacht diepte.
- 5Stap 5 — Ontleed complexe geneste queries: splits een query met 10+ geneste subqueries op in afzonderlijke stappen via tijdelijke tabellen of meerdere WITH-blokken in een WITH RECURSIVE-structuur met een expliciete UNION ALL-recursie-limiet (`SET SESSION cte_max_recursion_depth = 100;`).
- 6Stap 6 — Detecteer trigger-ketens die stack verbruiken: voer `SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'jouw_db';` uit en teken de trigger→tabel→trigger-relaties handmatig. Verbreek cirkels door de aangeroepen procedure te refactoren zodat hij geen INSERT/UPDATE doet op een tabel met een actieve trigger.
- 7Stap 7 — Valideer de fix in staging vóór productie-deploy: roep de procedure aan met de maximale verwachte recursie-diepte via een testscript: `CALL proc_recursive(root_id, 0);` en controleer dat `SHOW WARNINGS;` leeg is. Verhoog daarna pas de thread_stack in productie.
Example log output
ERROR 1436 (HY000): Thread stack overrun: 995312 bytes used of a 1048576 byte stack, and 8192 bytes needed. Use 'mysqld --thread_stack=#' to specify a bigger stack.
[ADF] Activity 'sp_transform_lineage' failed: MySqlException: Thread stack overrun on connection ID 4821.
[dbt] Database Error in model stg_lineage (models/staging/stg_lineage.sql): 1436 (HY000): Thread stack overrun