The APM Infrastructure Agent (APMIA) MySQL extension does not include Galera replication (wsrep_*) metrics out of the box. Customers running a Galera-based cluster, MariaDB Galera or Percona XtraDB Cluster (PXC), cannot monitor cluster health (node status, cluster size, flow control, replication state) through APMIA without customizing the extension.
This article describes how to add the 10 most relevant wsrep_* status variables to the MySQL extension's schema.json. It uses a single approach that works on any agent/extension version.
The 10 variables covered: wsrep_cluster_status, wsrep_cluster_size, wsrep_local_state, wsrep_local_state_comment, wsrep_last_applied, wsrep_last_committed, wsrep_flow_control_status, wsrep_flow_control_active, wsrep_flow_control_requested, wsrep_local_recv_queue.
DX O2 Agents 25x and 26x
The stock MySQL extension only maps standard counters from SHOW GLOBAL STATUS (e.g. Threads_running, Connections, InnoDB counters). The Galera wsrep_* variables are not mapped in the shipped schema.json, so they never reach the Metric Browser. They must be added with a dedicated mapping.
Add a dedicated aggregated SELECT block with positional access to schema.json located in APMIA MySql extension folder.
This single technique works on all agent/extension builds (25.x and 26.x).
Step 1: Add the block
Add the block below as another element of the sqlMetricMappings array in extensions/mysql-<hash>-<version>/config/schema.json (at the end of the array; add a comma to the previous block).
Change only the FROM clause according to the database flavorat the end of the query:
MariaDB Galera: information_schema.GLOBAL_STATUS
Percona XtraDB Cluster 8: performance_schema.global_status
{
"query": "SELECT COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_cluster_status' THEN VARIABLE_VALUE END),'N/A') AS wsrep_cluster_status, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_cluster_size' THEN CAST(VARIABLE_VALUE AS SIGNED) END),-1) AS wsrep_cluster_size, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_local_state' THEN CAST(VARIABLE_VALUE AS SIGNED) END),-1) AS wsrep_local_state, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_local_state_comment' THEN VARIABLE_VALUE END),'N/A') AS wsrep_local_state_comment, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_last_applied' THEN CAST(VARIABLE_VALUE AS SIGNED) END),-1) AS wsrep_last_applied, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_last_committed' THEN CAST(VARIABLE_VALUE AS SIGNED) END),-1) AS wsrep_last_committed, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_flow_control_status' THEN VARIABLE_VALUE END),'N/A') AS wsrep_flow_control_status, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_flow_control_active' THEN VARIABLE_VALUE END),'N/A') AS wsrep_flow_control_active, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_flow_control_requested' THEN VARIABLE_VALUE END),'N/A') AS wsrep_flow_control_requested, COALESCE(MAX(CASE WHEN VARIABLE_NAME='wsrep_local_recv_queue' THEN CAST(VARIABLE_VALUE AS SIGNED) END),-1) AS wsrep_local_recv_queue FROM information_schema.GLOBAL_STATUS",
"metrics": [
{ "metricPath": [{ "name": "Replication|Galera:Cluster Status" }], "metricType": "StringEvent", "metricValue": "$.resultSet[0].wsrep_cluster_status" },
{ "metricPath": [{ "name": "Replication|Galera:Cluster Size" }], "metricType": "IntFluctuatingCounter", "metricValue": "$.resultSet[0].wsrep_cluster_size" },
{ "metricPath": [{ "name": "Replication|Galera:Local State" }], "metricType": "IntFluctuatingCounter", "metricValue": "$.resultSet[0].wsrep_local_state" },
{ "metricPath": [{ "name": "Replication|Galera:Local State Comment" }], "metricType": "StringEvent", "metricValue": "$.resultSet[0].wsrep_local_state_comment" },
{ "metricPath": [{ "name": "Replication|Galera:Last Applied (seqno)" }], "metricType": "LongCounter", "metricValue": "$.resultSet[0].wsrep_last_applied" },
{ "metricPath": [{ "name": "Replication|Galera:Last Committed (seqno)" }], "metricType": "LongCounter", "metricValue": "$.resultSet[0].wsrep_last_committed" },
{ "metricPath": [{ "name": "Replication|Galera:Flow Control Status" }], "metricType": "StringEvent", "metricValue": "$.resultSet[0].wsrep_flow_control_status" },
{ "metricPath": [{ "name": "Replication|Galera:Flow Control Active" }], "metricType": "StringEvent", "metricValue": "$.resultSet[0].wsrep_flow_control_active" },
{ "metricPath": [{ "name": "Replication|Galera:Flow Control Requested" }], "metricType": "StringEvent", "metricValue": "$.resultSet[0].wsrep_flow_control_requested" },
{ "metricPath": [{ "name": "Replication|Galera:Local Receive Queue" }], "metricType": "IntFluctuatingCounter", "metricValue": "$.resultSet[0].wsrep_local_recv_queue" }
]
}
There is a single difference when using MariaDB x Percona/MySql, the end of the from query will be as below, change accordingly your environment, the string to be modified is highlight in Bold in the above query:
MariaDB: information_schema.GLOBAL_STATUS",
Percona/MySql: performance_schema.global_status",
Step 2: Apply and verify:
1. Validate the JSON (any comma/brace error breaks parsing): python -m json.tool schema.json or a linter.
2. Restart the monitored process / agent (systemctl restart <apmia>, or roll out the change on Kubernetes).
3. Check in the SaaS: MySQL Databases | <host> | <db> | Replication | Galera | * (10 metrics).
4. (Optional) Enable DEBUG to see values in the log: add introscope.agent.log.level.IntroscopeAgent.DBMonitor=DEBUG to IntroscopeAgent.profile, restart, and look for Metric Value:[…] and metric pushed:N.
Database prerequisites user grants:
MariaDB: PROCESS, REPLICATION CLIENT, SELECT;
MySQL 8 / Percona: PROCESS, REPLICATION CLIENT, SELECT ON *.* (the SELECT covers performance_schema).
The node must be a member of a Galera/PXC cluster; otherwise the wsrep_* variables do not exist.
Kubernetes delivery:
When APMIA runs as a Kubernetes Deployment, the schema.json lives inside the pod. Deliver the modified file via a mounted ConfigMap (subPath) over extensions/mysql-<hash>-<version>/config/schema.json, then kubectl rollout restart deployment/<apmia>. Keep the original schema.json for rollback (remove the mount).
Attachments sections contains a sample of Json already modified for MySql/Percona.
Source by flavor: information_schema.GLOBAL_STATUS exists on MariaDB but was removed in MySQL 8 (returns ERROR 1109 Unknown table);
MySQL 8 / Percona expose the data in performance_schema.global_status. This is why the FROM clause must match the flavor.
COALESCE / NULL handling: on a single node some variables may be absent (wsrep_last_applied, wsrep_flow_control_status). COALESCE returns a sentinel (-1 for numeric, 'N/A' for text) and prevents PathNotFoundException. On a real multi-node cluster all 10 are populated.
Reading the values: Cluster Status = Primary and Local State = 4 (Local State Comment = Synced) indicate a healthy node.
Suggested alerting (optional, via configure.json): Cluster Status ≠ Primary, Local State ≠ 4/Synced, or a high Local Receive Queue.