Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mysql/changelog.d/24178.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix MariaDB multi-channel replication reporting 0 channels by using SHOW ALL REPLICAS STATUS when no specific channel is configured.
7 changes: 6 additions & 1 deletion mysql/datadog_checks/mysql/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,12 @@ def _get_replica_stats(self, db):
for replica in replica_status:
# MySQL <5.7 does not have Channel_Name.
# For MySQL >=5.7 'Channel_Name' is set to an empty string by default
channel = self._config.replication_channel or replica.get('Channel_Name') or 'default'
channel = (
self._config.replication_channel
or replica.get('Channel_Name')
or replica.get('Connection_name')
or 'default'
)
for key, value in replica.items():
if value is not None:
replica_results[key]['channel:{0}'.format(channel)] = value
Expand Down
10 changes: 7 additions & 3 deletions mysql/datadog_checks/mysql/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,17 @@

def show_replica_status_query(version, is_mariadb: bool, channel: str = '') -> tuple[str, tuple[str, ...]]:
if version.version_compatible((10, 5, 1)) or not is_mariadb and version.version_compatible((8, 0, 22)):
base_query = "SHOW REPLICA STATUS"
replica_keyword = "REPLICA"
else:
base_query = "SHOW SLAVE STATUS"
replica_keyword = "SLAVE"
base_query = "SHOW {0} STATUS".format(replica_keyword)
if channel and not is_mariadb:
return ("{0} FOR CHANNEL %s".format(base_query), (channel,))
elif is_mariadb and not channel:
# MariaDB uses Connection_name (not Channel_Name) to identify channels.
return ("SHOW ALL {0}S STATUS".format(replica_keyword), ())
else:
return ("{0}".format(base_query), ())
return (base_query, ())


def get_indexes_query(version, is_mariadb, placeholders):
Expand Down
36 changes: 34 additions & 2 deletions mysql/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,20 @@ def test_collect_replication_metrics_returns_vars_when_has_replicas_connected():
assert results.get('Replicas_connected') == 2


def test_get_replica_stats_tags_each_mariadb_connection():
"""Each MariaDB Connection_name maps to its own channel tag in _get_replica_stats."""
mysql_check = MySql(common.CHECK_NAME, {}, instances=[{'server': 'localhost', 'user': 'datadog'}])
mysql_check._config.replication_enabled = True
mysql_check._get_replica_replication_status = mock.MagicMock(
return_value=[
{'Connection_name': 'conn_a', 'Seconds_Behind_Master': 1},
{'Connection_name': 'conn_b', 'Seconds_Behind_Master': 2},
]
)
results = mysql_check._get_replica_stats(mock.MagicMock())
assert results['Seconds_Behind_Master'] == {'channel:conn_a': 1, 'channel:conn_b': 2}


def test_source_with_zero_replicas_emits_warning_service_check(aggregator, instance_basic):
"""Test that a source with 0 connected replicas emits WARNING for replica-loss detection."""
mysql_check = MySql(common.CHECK_NAME, {}, instances=[instance_basic])
Expand Down Expand Up @@ -777,10 +791,28 @@ class TestShowReplicaStatusQuery:
'my-channel',
'SHOW REPLICA STATUS',
(),
id='mariadb_ignores_channel',
id='mariadb_modern_with_channel',
),
pytest.param(
'10.4.0-MariaDB', 'MariaDB', True, '', 'SHOW SLAVE STATUS', (), id='mariadb_legacy_no_channel'
'10.5.1-MariaDB',
'MariaDB',
True,
'',
'SHOW ALL REPLICAS STATUS',
(),
id='mariadb_modern_no_channel',
),
pytest.param(
'10.4.0-MariaDB', 'MariaDB', True, '', 'SHOW ALL SLAVES STATUS', (), id='mariadb_legacy_no_channel'
),
pytest.param(
'10.4.0-MariaDB',
'MariaDB',
True,
'my-channel',
'SHOW SLAVE STATUS',
(),
id='mariadb_legacy_with_channel',
),
],
)
Expand Down
Loading