Connection pool can briefly exceed max_size when pooling is disabled under load
Les mainteneurs répondent en général sous 2 jours
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 62/100
Piste de recherche
Lisez mssql_python/pybind/connection/connection_pool.cpp, en vous concentrant sur l'interception de l'échec de la phase 3 de ConnectionPool::acquire, closePools() et ConnectionPool::close. Suivez les chemins de réservation et de nettoyage, puis examinez comment PR #678 a modifié la construction de Connection. C'est terminé lorsqu'un test de régression couvre l'interleaving entre l'échec et la désactivation et que le nombre de connexions physiques actives ne dépasse jamais max_size.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Describe the bug
The connection pool can transiently exceed its configured max_size when pooling is disabled (or the process begins shutting down) while new physical connections are being opened concurrently. The pool's internal reserved-capacity counter (_current_size) can drift below the true number of live connections, after which the pool opens more physical connections than max_size allows. It is transient and self-corrects as connections close.
Root cause: _current_size is a bare counter with no record of which reservation a given decrement belongs to. The failed-open cleanup runs if (_current_size > 0) --_current_size, while a pool disable/close runs _current_size = 0. If a reset lands between a thread reserving a slot and that same thread's open failing, the thread's decrement cancels a different thread's live reservation instead of its own.
Exception message: none. This is a silent _current_size accounting drift, no exception or stack trace.
To reproduce
This is a rare timing race, so it is not deterministically reproducible from a plain script. It requires a new connection to fail to open at the exact moment pooling is disabled or the process is shutting down. The interleave that produces it, with max_size = 2:
import mssql_python
from concurrent.futures import ThreadPoolExecutor
mssql_python.pooling(max_size=2)
# 1. Thread A calls connect(), reserves a slot -> _current_size = 1,
# then starts opening a new physical connection (outside the pool lock).
# 2. Another thread disables pooling: closePools() sets _current_size = 0.
# 3. Thread B calls connect(), reserves the freed slot -> _current_size = 1.
# 4. Thread A's open fails (handle alloc / network error): its cleanup runs
# --_current_size -> 0, cancelling B's slot instead of A's.
# 5. Thread B's open succeeds, but _current_size now reads 0.
# 6. Further connect() calls see room and open past max_size.
Observable symptom while the count is drifted: more live sessions than the configured cap.
SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE login_name = 'yourapp';
-- transiently returns 3 with max_size = 2
Expected behavior
The number of live physical connections should never exceed max_size, regardless of a connection-open failure racing a pooling disable or process shutdown.
Further technical details
Python version: any
SQL Server version: any
Operating system: any. The race is in the cross-platform C++ pool, not platform specific.
Additional context
Area: mssql_python/pybind/connection/connection_pool.cpp, the Phase 3 failure catch in ConnectionPool::acquire, plus closePools() and ConnectionPool::close.
Regression status: pre-existing for the connect()-failure path. PR #678 moved Connection construction out of _mutex (required to fix the #671 deadlock), which widens the same race to also cover constructor failures such as ODBC env init, handle allocation, and OOM. Raised during review of #678.
Proposed fix: give the pool a generation counter. close()/closePools() bumps it under the lock, a reserver snapshots it at ++_current_size, and the failure cleanup only decrements if the generation still matches. This makes the decrement attributable and closes both the constructor and connect paths. Roughly 6 to 8 lines plus a regression test that forces the interleave.
- Langage dominant
- Python
- Étoiles
- 478
- Forks
- 62
- Merge moyen
- 3 j 19 min
- PR mergées (30 j)
- 28
Préparer son environnement
Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de microsoft/mssql-python
-
area: bulk-copy triage needed
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
microsoft/mssql-python#843 · 1 commentaire ·
Les mainteneurs répondent en général sous 2 jours
-
triage needed
Difficulté 4/5 3-5 jours Accessibilité débutants 35/100
microsoft/mssql-python#846 · 1 commentaire ·
Les mainteneurs répondent en général sous 2 jours
-
macOS: encrypted connections fail after Homebrew moved the `openssl` alias to `openssl@4`Peut-être pris @bewithgaurav l’a pris il y a 15 jours. Ouvertearea: packaging-platform bug triage needed
Difficulté 4/5 3-5 jours Accessibilité débutants 55/100
microsoft/mssql-python#826 · 2 commentaires · 1 personne assignée ·
Les mainteneurs répondent en général sous 2 jours
-
Announcement: mssql-python is coming to Django through mssql-django 2.0Peut-être à nouveau libre @bewithgaurav l’a pris il y a 42 jours, et aucune pull request n’est ouverte. Ouverteannouncement
microsoft/mssql-python#748 · 1 personne assignée ·
Les mainteneurs répondent en général sous 2 jours
-
Decimal in money range still string-binds on the executemany pathPeut-être pris @bewithgaurav l’a pris il y a 24 jours. Ouvertearea: data-types bug triage done under development
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
microsoft/mssql-python#745 · 1 commentaire · 1 personne assignée ·
Les mainteneurs répondent en général sous 2 jours
Toutes les issues de microsoft/mssql-python
Issues similaires
-
mermaid_extract.py silently discards single-line state-diagram notes; sequence notes are keptOuverte
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
cathrynlavery/diagram-design#441 ·
Les mainteneurs répondent en général sous 2 jours
-
[Cleanup] Include the public header in work_split.cppPeut-être pris @blozano-tt l’a pris aujourd’hui. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
tenstorrent/tt-metal#60850 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 1 jour
-
backend::sglang bug language::python observability
Difficulté 2/5 Une demi-journée Accessibilité débutants 65/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 75/100
OpenShot/openshot-qt#6202 ·
Les mainteneurs répondent en général sous 1 jour