From 6be2595ca82aac43c04940e9f0e013b085beefd4 Mon Sep 17 00:00:00 2001 From: Christophe Haen Date: Tue, 5 Dec 2023 17:35:16 +0100 Subject: [PATCH] feat (MySQL): introduce DIRAC_MYSQL_CONNECTION_GRACE_TIME to allow for non reused connection --- .../environment_variable_configuration.rst | 3 +++ src/DIRAC/Core/Utilities/MySQL.py | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/source/AdministratorGuide/ServerInstallations/environment_variable_configuration.rst b/docs/source/AdministratorGuide/ServerInstallations/environment_variable_configuration.rst index 1e17e11e874..4c20e6b6a1d 100644 --- a/docs/source/AdministratorGuide/ServerInstallations/environment_variable_configuration.rst +++ b/docs/source/AdministratorGuide/ServerInstallations/environment_variable_configuration.rst @@ -50,6 +50,9 @@ DIRAC_M2CRYPTO_SSL_CIPHERS DIRAC_M2CRYPTO_SSL_METHODS If set, overwrites the default SSL methods accepted. It should be a colon separated list. See :py:mod:`DIRAC.Core.DISET` +DIRAC_MYSQL_CONNECTION_GRACE_TIME + If set to an integer, default of the grace time before the connection is reused. See :py:class:`DIRAC.Core.Utilities.MySQL.ConnectionPool` + DIRAC_MYSQL_OPTIMIZER_TRACES_PATH If set, it should point to an existing directory, where MySQL Optimizer traces will be stored. See :py:func:`DIRAC.Core.Utilities.MySQL.captureOptimizerTraces` diff --git a/src/DIRAC/Core/Utilities/MySQL.py b/src/DIRAC/Core/Utilities/MySQL.py index 3f594862ee4..46f5428c27c 100755 --- a/src/DIRAC/Core/Utilities/MySQL.py +++ b/src/DIRAC/Core/Utilities/MySQL.py @@ -327,7 +327,21 @@ class ConnectionPool: Management of connections per thread """ - def __init__(self, host, user, passwd, port=3306, graceTime=600): + # The idea of the grace time is that a given thread should not keep a connection object for too long + # However, in case of long running queries, this is unavoidable. + # If the DISET/HTTPs connection timeout is longer than the MySQL grace time, + # the connection will be reallocated to another thread, and that does not go down well + # From the mysqlclient doc ("threadsafety" of https://mysqlclient.readthedocs.io/user_guide.html#mysqldb) + # "The general upshot of this is: Don’t share connections between threads." + # The best thing to do, if we don't want to have a lock, is to set this value to 0 + # so it is not used. LHCb will run in prod with the value 0 for a while, and if no issue arrises, + # it will become the default + try: + MYSQL_CONNECTION_GRACE_TIME = int(os.environ.get("DIRAC_MYSQL_CONNECTION_GRACE_TIME")) + except Exception: + MYSQL_CONNECTION_GRACE_TIME = 600 + + def __init__(self, host, user, passwd, port=3306, graceTime=MYSQL_CONNECTION_GRACE_TIME): self.__host = host self.__user = user self.__passwd = passwd @@ -446,7 +460,7 @@ def clean(self, now=False): data = self.__assigned[thid] except KeyError: continue - if now - data[2] > self.__graceTime: + if self.__graceTime and now - data[2] > self.__graceTime: self.__pop(thid) def transactionStart(self, dbName):