From d9ee0c469e77f87193bc7bd6648e3b73782b786c Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Fri, 11 Sep 2026 22:03:28 -0700 Subject: [PATCH 1/2] Document the glibc static-TLS ImportError in the FAQ Add an entry for 'cannot allocate memory in static TLS block', a recurring ImportError when other native extensions have already claimed glibc's small static-TLS surplus before _mysql dlopen()s. It has hit multiple unrelated consumers (Apache Airflow #17546 and its 2024 recurrence in #40503) but was never documented here. Signed-off-by: 1fanwang <1fannnw@gmail.com> --- doc/FAQ.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/FAQ.rst b/doc/FAQ.rst index 14c8f72c..b0e3fd68 100644 --- a/doc/FAQ.rst +++ b/doc/FAQ.rst @@ -89,6 +89,32 @@ every major release of GCC changes the ABI in some why, so linking code compiled with GCC-3.3 and GCC-4.0, for example, can be problematic. + ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: cannot allocate memory in static TLS block + +This happens when other native extensions already loaded into the +process (each linking libstdc++) have used up glibc's small static-TLS +surplus before _mysql gets its turn to dlopen(). It isn't a MySQLdb bug +or a bad build; it's a general glibc/dlopen interaction, and it recurs +whenever a new native dependency tips a process over the threshold +(see `Apache Airflow #17546 +`_, and its 2024 +recurrence in `#40503 +`_ with a different +native dependency as the trigger each time). + +Workaround, in production use in Apache Airflow's own Docker image +since 2021 (`airflow#19010 +`_): preload libstdc++ +before anything else can claim the surplus. + +.. code-block:: sh + + export LD_PRELOAD="/usr/lib/$(uname -m)-linux-gnu/libstdc++.so.6" + +On RHEL/CentOS the path is typically ``/lib64/libstdc++.so.6`` instead. +glibc fixed the equivalent static-TLS waste on aarch64/powerpc64 in +2.32; on other architectures the small default surplus is intentional, +so LD_PRELOAD remains the practical fix. My data disappeared! (or won't go away!) ---------------------------------------- From 724bc695ee5362b6478fd315d2d2049992866a82 Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Fri, 11 Sep 2026 23:19:09 -0700 Subject: [PATCH 2/2] Clarify static TLS loading and the preload workaround Signed-off-by: 1fanwang <1fannnw@gmail.com> --- doc/FAQ.rst | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/doc/FAQ.rst b/doc/FAQ.rst index b0e3fd68..161db130 100644 --- a/doc/FAQ.rst +++ b/doc/FAQ.rst @@ -91,30 +91,31 @@ problematic. ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: cannot allocate memory in static TLS block -This happens when other native extensions already loaded into the -process (each linking libstdc++) have used up glibc's small static-TLS -surplus before _mysql gets its turn to dlopen(). It isn't a MySQLdb bug -or a bad build; it's a general glibc/dlopen interaction, and it recurs -whenever a new native dependency tips a process over the threshold -(see `Apache Airflow #17546 -`_, and its 2024 -recurrence in `#40503 -`_ with a different -native dependency as the trigger each time). - -Workaround, in production use in Apache Airflow's own Docker image -since 2021 (`airflow#19010 -`_): preload libstdc++ -before anything else can claim the surplus. +Previously loaded native extensions can consume glibc's static-TLS +surplus. The dynamic loader can then fail to load ``MySQLdb._mysql`` or +one of its dependencies when it needs more static TLS, particularly +with the initial-exec TLS model. The static allocation cannot grow +after process startup, so this can occur even with a correct +mysqlclient build. Examples include `Apache Airflow #17546 +`_ and `#40503 +`_. + +Preload the library named in the error before Python starts, as in +`Apache Airflow #19010 `_. +An exported ``LD_PRELOAD`` is inherited by child processes, including +programs that would not otherwise load that library. Scope it to the +affected service or container; startup and memory costs depend on the +program and platform. + +On Debian-based systems with ``dpkg-dev`` installed, use the platform's +multiarch name rather than ``uname -m``: .. code-block:: sh - export LD_PRELOAD="/usr/lib/$(uname -m)-linux-gnu/libstdc++.so.6" + export LD_PRELOAD="/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/libstdc++.so.6" -On RHEL/CentOS the path is typically ``/lib64/libstdc++.so.6`` instead. -glibc fixed the equivalent static-TLS waste on aarch64/powerpc64 in -2.32; on other architectures the small default surplus is intentional, -so LD_PRELOAD remains the practical fix. +On other distributions, use the path from the error. For example, +RHEL/CentOS commonly uses ``/lib64/libstdc++.so.6`` instead. My data disappeared! (or won't go away!) ---------------------------------------- @@ -159,4 +160,3 @@ Other Resources * Read `PEP-249`_ .. _`PEP-249`: https://www.python.org/dev/peps/pep-0249/ -