Skip to content

Commit 86510c4

Browse files
pierreln-ddclaude
andauthored
MariaDB: use SHOW ALL REPLICAS STATUS for multi-channel replication (DataDog#24178)
* fix(mysql): use SHOW ALL REPLICAS STATUS for MariaDB multi-channel replication Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * add changelog for DataDog#24178 * refactor(mysql): use replica_keyword variable; add Connection_name tagging test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e5b996e commit 86510c4

4 files changed

Lines changed: 48 additions & 6 deletions

File tree

mysql/changelog.d/24178.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix MariaDB multi-channel replication reporting 0 channels by using SHOW ALL REPLICAS STATUS when no specific channel is configured.

mysql/datadog_checks/mysql/mysql.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,12 @@ def _get_replica_stats(self, db):
11441144
for replica in replica_status:
11451145
# MySQL <5.7 does not have Channel_Name.
11461146
# For MySQL >=5.7 'Channel_Name' is set to an empty string by default
1147-
channel = self._config.replication_channel or replica.get('Channel_Name') or 'default'
1147+
channel = (
1148+
self._config.replication_channel
1149+
or replica.get('Channel_Name')
1150+
or replica.get('Connection_name')
1151+
or 'default'
1152+
)
11481153
for key, value in replica.items():
11491154
if value is not None:
11501155
replica_results[key]['channel:{0}'.format(channel)] = value

mysql/datadog_checks/mysql/queries.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,17 @@
288288

289289
def show_replica_status_query(version, is_mariadb: bool, channel: str = '') -> tuple[str, tuple[str, ...]]:
290290
if version.version_compatible((10, 5, 1)) or not is_mariadb and version.version_compatible((8, 0, 22)):
291-
base_query = "SHOW REPLICA STATUS"
291+
replica_keyword = "REPLICA"
292292
else:
293-
base_query = "SHOW SLAVE STATUS"
293+
replica_keyword = "SLAVE"
294+
base_query = "SHOW {0} STATUS".format(replica_keyword)
294295
if channel and not is_mariadb:
295296
return ("{0} FOR CHANNEL %s".format(base_query), (channel,))
297+
elif is_mariadb and not channel:
298+
# MariaDB uses Connection_name (not Channel_Name) to identify channels.
299+
return ("SHOW ALL {0}S STATUS".format(replica_keyword), ())
296300
else:
297-
return ("{0}".format(base_query), ())
301+
return (base_query, ())
298302

299303

300304
def get_indexes_query(version, is_mariadb, placeholders):

mysql/tests/test_unit.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,20 @@ def test_collect_replication_metrics_returns_vars_when_has_replicas_connected():
704704
assert results.get('Replicas_connected') == 2
705705

706706

707+
def test_get_replica_stats_tags_each_mariadb_connection():
708+
"""Each MariaDB Connection_name maps to its own channel tag in _get_replica_stats."""
709+
mysql_check = MySql(common.CHECK_NAME, {}, instances=[{'server': 'localhost', 'user': 'datadog'}])
710+
mysql_check._config.replication_enabled = True
711+
mysql_check._get_replica_replication_status = mock.MagicMock(
712+
return_value=[
713+
{'Connection_name': 'conn_a', 'Seconds_Behind_Master': 1},
714+
{'Connection_name': 'conn_b', 'Seconds_Behind_Master': 2},
715+
]
716+
)
717+
results = mysql_check._get_replica_stats(mock.MagicMock())
718+
assert results['Seconds_Behind_Master'] == {'channel:conn_a': 1, 'channel:conn_b': 2}
719+
720+
707721
def test_source_with_zero_replicas_emits_warning_service_check(aggregator, instance_basic):
708722
"""Test that a source with 0 connected replicas emits WARNING for replica-loss detection."""
709723
mysql_check = MySql(common.CHECK_NAME, {}, instances=[instance_basic])
@@ -777,10 +791,28 @@ class TestShowReplicaStatusQuery:
777791
'my-channel',
778792
'SHOW REPLICA STATUS',
779793
(),
780-
id='mariadb_ignores_channel',
794+
id='mariadb_modern_with_channel',
781795
),
782796
pytest.param(
783-
'10.4.0-MariaDB', 'MariaDB', True, '', 'SHOW SLAVE STATUS', (), id='mariadb_legacy_no_channel'
797+
'10.5.1-MariaDB',
798+
'MariaDB',
799+
True,
800+
'',
801+
'SHOW ALL REPLICAS STATUS',
802+
(),
803+
id='mariadb_modern_no_channel',
804+
),
805+
pytest.param(
806+
'10.4.0-MariaDB', 'MariaDB', True, '', 'SHOW ALL SLAVES STATUS', (), id='mariadb_legacy_no_channel'
807+
),
808+
pytest.param(
809+
'10.4.0-MariaDB',
810+
'MariaDB',
811+
True,
812+
'my-channel',
813+
'SHOW SLAVE STATUS',
814+
(),
815+
id='mariadb_legacy_with_channel',
784816
),
785817
],
786818
)

0 commit comments

Comments
 (0)