Skip to content

Commit 3c98036

Browse files
SDBM-1909: Change statement_rows dict to a TTL cache to fix mysql memory leaks (#21097)
* always emit session_id as integer * change statement_rows to TTL cache * changelog and remove accidental change * fix changelog * expire old keys upon run job
1 parent 2f9a6b6 commit 3c98036

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

mysql/changelog.d/21097.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Change statement_rows to TTL cache to fix mysql memory leaks

mysql/datadog_checks/mysql/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def __init__(self, instance, init_config):
4545
self.full_statement_text_samples_per_hour_per_query = instance.get(
4646
'full_statement_text_samples_per_hour_per_query', 1
4747
)
48+
self.statement_rows_cache_max_size = instance.get('statement_rows_cache_max_size', 10000)
49+
self.statement_rows_cache_ttl = instance.get('statement_rows_cache_ttl', 3600)
4850
self.statement_samples_config = instance.get('query_samples', instance.get('statement_samples', {})) or {}
4951
self.statement_metrics_config = instance.get('query_metrics', {}) or {}
5052
self.settings_config = instance.get('collect_settings', {}) or {}

mysql/datadog_checks/mysql/statements.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ def __init__(self, check, config, connection_args):
9696

9797
# statement_rows: cache of all rows for each digest, keyed by (schema_name, query_signature)
9898
# This is used to cache the metrics for queries that have the same query_signature but different digests
99-
self._statement_rows = {} # type: Dict[(str, str), Dict[str, PyMysqlRow]]
99+
self._statement_rows = TTLCache(
100+
maxsize=self._config.statement_rows_cache_max_size,
101+
ttl=self._config.statement_rows_cache_ttl,
102+
)
100103

101104
def _get_db_connection(self):
102105
"""
@@ -119,6 +122,7 @@ def _close_db_conn(self):
119122

120123
def run_job(self):
121124
start = time.time()
125+
self._statement_rows.expire()
122126
self.collect_per_statement_metrics()
123127
self._check.gauge(
124128
"dd.mysql.statement_metrics.collect_metrics.elapsed_ms",
@@ -300,9 +304,9 @@ def _add_associated_rows(self, rows):
300304
"""
301305
for row in rows:
302306
key = (row['schema_name'], row['query_signature'])
303-
if key not in self._statement_rows:
304-
self._statement_rows[key] = {}
305-
self._statement_rows[key][row['digest']] = row
307+
digest_rows = self._statement_rows.get(key, {})
308+
digest_rows[row['digest']] = row
309+
self._statement_rows[key] = digest_rows
306310

307311
return [row for statement_row in self._statement_rows.values() for row in statement_row.values()]
308312

0 commit comments

Comments
 (0)