Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
be13eff
feat(mysqlreceiver): add MySQL <8 and MariaDB version compatibility
cjksplunk Apr 1, 2026
efd30a1
test(mysqlreceiver): add integration tests for multi-version capabili…
cjksplunk Apr 1, 2026
d87c30c
fix(mysqlreceiver): address code review findings
cjksplunk Apr 1, 2026
3865157
fix(mysqlreceiver): make getDBVersion thread-safe with sync.Once
cjksplunk Apr 1, 2026
dced59b
docs(mysqlreceiver): document supported versions and query plan avail…
cjksplunk Apr 1, 2026
856500e
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 1, 2026
24b31c2
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 2, 2026
4110f6c
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 2, 2026
6e53e3b
feat(mysqlreceiver): add MySQL <v8 and MariaDB multi-version support
cjksplunk Apr 2, 2026
c30310d
fix(mysqlreceiver): address code review findings from multi-version PR
cjksplunk Apr 2, 2026
8350ed8
fix(mysqlreceiver): clarify one-shot version detection and log detect…
cjksplunk Apr 2, 2026
1c827e0
fix(mysqlreceiver): add fallback query sample template for MySQL <5.7…
cjksplunk Apr 2, 2026
5877cf9
test(mysqlreceiver): add unit and integration test coverage for suppo…
cjksplunk Apr 2, 2026
f9b073b
Merge branch 'open-telemetry:main' into mysql-multi-version-support
cjksplunk Apr 2, 2026
43253ac
feat(mysqlreceiver): warn on EOL MySQL version at startup
cjksplunk Apr 3, 2026
6515f55
feat(mysqlreceiver): stamp db.version and db.product as scope attributes
cjksplunk Apr 3, 2026
ba4d22a
refactor(mysqlreceiver): move version decisions from client to scraper
cjksplunk Apr 3, 2026
dd981cc
test(mysqlreceiver): fix and extend coverage for version-based capabi…
cjksplunk Apr 3, 2026
961ec47
test(mysqlreceiver): extend integration and unit test coverage
cjksplunk Apr 3, 2026
06e1eb8
Merge branch 'main' of https://github.com/open-telemetry/opentelemetr…
cjksplunk Apr 3, 2026
dd2c7b0
docs(mysqlreceiver): correct query plan availability claims in README…
cjksplunk Apr 3, 2026
ad49208
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 7, 2026
4a99d69
refactor(mysqlreceiver): simplify version predicates, extract helpers…
cjksplunk Apr 7, 2026
436878f
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 7, 2026
28b9a8a
fix(mysqlreceiver): query processlist_port for client.port and networ…
cjksplunk Apr 7, 2026
e05c6a9
fix(mysqlreceiver): use processlist_host directly for client.address;…
cjksplunk Apr 7, 2026
4e21dff
fix(mysqlreceiver): populate client.address and client.port from info…
cjksplunk Apr 7, 2026
1ea5903
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 7, 2026
123cc69
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 8, 2026
d403c37
feat(mysqlreceiver): populate client.port via performance_schema.proc…
cjksplunk Apr 10, 2026
53214a5
fix(mysqlreceiver): populate mysql.events_waits_current.timer_wait fo…
cjksplunk Apr 10, 2026
1b4eb2c
docs(mysqlreceiver): add version compatibility matrix and COMPATIBILI…
cjksplunk Apr 10, 2026
9428af7
chore: update chloggen entry for mysql-multi-version-support
cjksplunk Apr 10, 2026
5e5ba09
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 10, 2026
8d12d25
docs(mysqlreceiver): add tested platforms matrix and events_waits_cur…
cjksplunk Apr 14, 2026
4564094
fix(mysqlreceiver): handle IPv6 client addresses in processlist HOST …
cjksplunk Apr 14, 2026
fcd137a
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 15, 2026
293358d
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 16, 2026
15cf578
fix(mysqlreceiver): timebox version detection to prevent startup stall
cjksplunk Apr 16, 2026
628d318
fix(mysqlreceiver): make MariaDB version parsing robust
cjksplunk Apr 16, 2026
d544fc1
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 17, 2026
50e9fc2
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 17, 2026
7ee57f5
Merge branch 'open-telemetry:main' into mysql-multi-version-support
cjksplunk Apr 17, 2026
439d5ff
Merge branch 'open-telemetry:main' into mysql-multi-version-support
cjksplunk Apr 17, 2026
ff17201
Merge remote-tracking branch 'origin/mysql-multi-version-support' int…
cjksplunk Apr 20, 2026
9402cac
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 20, 2026
612ddd4
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 21, 2026
e5b51de
feat(receiver/mysqlreceiver): remove MySQL <=5.7.2 and MariaDB <=10.5…
cjksplunk Apr 21, 2026
6ad461b
docs(receiver/mysqlreceiver): remove supportsUserVariablesByThread fr…
cjksplunk Apr 21, 2026
59aad4e
Merge remote-tracking branch 'upstream/main' into mysql-multi-version…
cjksplunk Apr 21, 2026
3f36b13
docs: update version compatibility docs and changelog for mysql-multi…
cjksplunk Apr 21, 2026
b5aa318
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 21, 2026
8518ec1
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 21, 2026
c5dccc6
chore: fix yaml syntax in chloggen entry
cjksplunk Apr 21, 2026
3f4f955
Merge branch 'mysql-multi-version-support' of https://github.com/cjks…
cjksplunk Apr 21, 2026
cb1e947
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 21, 2026
277ad58
chore: fix chloggen component name in changelog entry
cjksplunk Apr 21, 2026
9f4fcd9
Merge remote-tracking branch 'origin/mysql-multi-version-support' int…
cjksplunk Apr 21, 2026
5ef6db8
Merge branch 'main' into mysql-multi-version-support
cjksplunk Apr 21, 2026
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
14 changes: 14 additions & 0 deletions .chloggen/mysql-multi-version-support.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
change_type: enhancement

component: receiver/mysql

note: |
Add MySQL <8 and MariaDB compatibility for query sample and top-query collection. The receiver now detects the server product and version at connect time and gates behavior accordingly. Changes include: (1) top-query collection uses a fallback template on MySQL <8 and MariaDB that omits `query_sample_text` (absent on those versions); (2) `client.port` and `network.peer.port` are now populated on MySQL 8.0.22+ via a lock-free join on `performance_schema.processlist`, and remain 0 on older MySQL and all MariaDB versions where this table is unavailable; (3) `mysql.events_waits_current.timer_wait` now uses a three-tier fallback — exact `TIMER_WAIT` for completed waits, a PS timer approximation for in-progress waits on MySQL 5.7+/8.0+, and `thread.processlist_time` (integer-second precision) as a universal fallback for MariaDB and older MySQL.

issues: [47302]

subtext: |
Supported products and versions: MySQL 5.7.3+, 8.0+; MariaDB 10.5.2+, 11.x.
See COMPATIBILITY.md in the receiver directory for a full version × feature matrix.

change_logs: [user]
73 changes: 73 additions & 0 deletions receiver/mysqlreceiver/COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Version Compatibility

This document lists every version-gated capability in the MySQL receiver. Version detection runs once at `Connect()` time via `fetchDBVersion()`. If detection fails, all predicates return `false`, which falls back to MySQL <8 behavior.

## Capability Predicates

| Predicate | Minimum Version | Fallback Behavior |
|---|---|---|
| `supportsQuerySampleText()` | MySQL 8.0.3+ | Top-query scraper uses 5-column fallback template (`topQueryNoSampleText.tmpl`); `querySampleText` is empty and `EXPLAIN` is skipped |
| `supportsReplicaStatus()` | MySQL 8.0.22+ | `SHOW SLAVE STATUS` is used instead of `SHOW REPLICA STATUS` |
| `supportsProcesslist()` | MySQL 8.0.22+ | `client.port` and `network.peer.port` remain `0`; `information_schema.PROCESSLIST` is **not** used as a fallback (it holds a global mutex, was deprecated in MySQL 8.0, removed in MySQL 9.0, and has already been removed from this receiver) |

## Timer Wait Tiers (`querySample.tmpl`)

Query sample duration is resolved in order. The first tier that produces a value is used.

| Tier | Source | Availability |
|---|---|---|
| 1 | Exact `TIMER_WAIT` for completed waits | All supported versions |
| 2 | PS timer approximation for in-progress waits | MySQL 5.7+ / 8.0+; **not used for MariaDB** — MariaDB's `statement.TIMER_WAIT` is updated only at yield points, not continuously, making it unreliable for in-progress statements |
| 3 | `thread.processlist_time` integer-second fallback | MySQL 5.7+, all supported MariaDB versions |

## Version Detection

- Detection runs **once** at `Connect()` time via `fetchDBVersion()`.
- Failure is **non-fatal**: `dbVersion` stays at its zero value and `Connect()` returns `nil`. All capability predicates return `false`, which produces MySQL <8 fallback behavior.
- The `dbVersion` struct holds two fields: `product` (MySQL or MariaDB) and `version` (semver).
- Connection errors surface on the first scrape, not at connect time.

## Tested Platforms

The following product/version/platform combinations have been validated against a live deployment. Each row reflects the capability matrix observed for that exact configuration.

- **Exact Version** — the full string returned by `SELECT VERSION()` on the tested instance
- **Platform** — deployment type and instance class (e.g. `AWS RDS db.t3.micro`, `Docker 27.x`, `bare metal`)
- **Date** — date live validation passed

| Product | Series | Exact Version | Platform | `supportsQuerySampleText` | `supportsProcesslist` | `supportsReplicaStatus` | Timer Wait Tiers | Date |
|---|---|---|---|---|---|---|---|---|
| MySQL | 8.4 | 8.4.7 | AWS RDS db.t3.micro | ✓ | ✓ | ✓ | 1, 2, 3 | 2026-04-21 |
| MySQL | 5.7 | 5.7.44 | AWS RDS db.t3.micro | ✗ | ✗ | ✗ | 1, 2, 3 | 2026-04-21 |
| MariaDB | 10.5 | 10.5.28 | AWS RDS db.t3.micro | ✗ | ✗ | ✗ | 1, 3 | 2026-04-21 |
| MariaDB | 11.8 | 11.8.2 | AWS RDS db.t3.micro | ✗ | ✗ | ✗ | 1, 3 | 2026-04-21 |

**Legend:**
- ✓ = capability enabled
- ✗ = capability disabled (fallback behavior active)

## `events_waits_current` Consumer

The `mysql.events_waits_current.timer_wait` attribute requires the `events_waits_current`
Performance Schema consumer. This consumer is **disabled by default** on all supported platforms,
including AWS RDS.

### Enablement by platform

| Platform | Method | Persistent? |
|---|---|---|
| MySQL / MariaDB — manual server | `performance-schema-consumer-events-waits-current=ON` in `[mysqld]` (`my.cnf`) | Yes |
| AWS RDS — MySQL / MariaDB | `UPDATE performance_schema.setup_consumers SET ENABLED='YES' WHERE NAME='events_waits_current'` | No — resets on restart/failover |

AWS RDS does not expose this as a parameter group setting. The runtime `UPDATE` must be re-applied
after each restart. The receiver user needs `UPDATE ON performance_schema.setup_consumers` for this.

### Expected behavior once enabled

| Product | Timer Wait Tier Used | Notes |
|---|---|---|
| MySQL 5.7 | Tier 1 or 2 | Tier 1 if wait has completed; Tier 2 (PS timer approximation) if wait is in progress |
| MySQL 8.x | Tier 1 or 2 | Same as 5.7 |
| MariaDB (all versions) | Tier 1 or 3 | Tier 2 is not used — MariaDB `statement.TIMER_WAIT` is stale during active execution; falls through to integer-second `processlist_time` |

See the Timer Wait Tiers section above for tier definitions.
76 changes: 75 additions & 1 deletion receiver/mysqlreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,22 @@ There are also optional metrics that you must specify in your configuration to c

## Prerequisites

This receiver supports MySQL version 8.0 and MariaDB 10.11.
The receiver detects the database product and version on first connection and adjusts its
behavior accordingly.

### Supported database versions

| Product | Versions | Query plans on `db.server.top_query` | Traceparent propagation | `client.port` / `network.peer.port` | Replica status syntax |
|---------|----------|--------------------------------------|-------------------------|--------------------------------------|-----------------------|
| MySQL | 5.7.x | No | Yes | 0 | `SHOW SLAVE STATUS` |
| MySQL | 8.0.0–8.0.21 | Yes | Yes | 0 | `SHOW SLAVE STATUS` |
| MySQL | 8.0.22+ | Yes | Yes | Populated | `SHOW REPLICA STATUS` |
| MySQL | 8.4.x | Yes | Yes | Populated | `SHOW REPLICA STATUS` |
| MySQL | 9.x | Yes | Yes | Populated | `SHOW REPLICA STATUS` |
| MariaDB | 10.5.x–10.11.x | No | Yes | 0 | `SHOW SLAVE STATUS` |
| MariaDB | 11.x (LTS: 11.4, 11.8) | No | Yes | 0 | `SHOW SLAVE STATUS` |

See [COMPATIBILITY.md](./COMPATIBILITY.md) for full details on version-gated behavior and fallbacks.

Collecting most metrics requires the ability to execute `SHOW GLOBAL STATUS`.

Expand Down Expand Up @@ -109,6 +124,24 @@ application transactions to be correlated with query samples collected by this r
> spelled them. The JOIN condition `VARIABLE_NAME = 'traceparent'` therefore
> matches any case variation the client used (e.g. `SET @TraceParent = '...'`
> works identically to `SET @traceparent = '...'`).
### Query plan availability by version

EXPLAIN needs a concrete SQL statement. The normalized digest text in
`events_statements_summary_by_digest` uses placeholders (`SELECT ? FROM t WHERE id = ?`),
which MySQL will not execute.

MySQL 8.0 added `query_sample_text` to `events_statements_summary_by_digest`. It holds an
actual statement that was run for each digest, so the top-query scraper can call EXPLAIN
without needing to catch the query in flight.

MariaDB and MySQL 5.x do not have `query_sample_text`, so the top-query scraper has nothing
to EXPLAIN. Query plans are not available for these versions.

If a statement is truncated (the stored text ends with `...`), the receiver skips EXPLAIN for
that statement on all versions. Truncation is controlled by
[`performance_schema_max_sql_text_length`](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-system-variables.html#sysvar_performance_schema_max_sql_text_length)
(default 1024). Setting it to `4096` is recommended — see the requirements table below.

### MySQL Requirements to enable log collection

| Parameter | Value | Description |
Expand All @@ -117,3 +150,44 @@ application transactions to be correlated with query samples collected by this r
| `max_digest_length` | `4096` (Recommended) | Maximum length of digest text |
| `performance_schema_max_digest_length` | `4096` (Recommended) | Maximum length of digest text on performance schema |
| `performance_schema_max_sql_text_length` | `4096` (Recommended) | Maximum length of sql text |

### Enabling `events_waits_current` for lock-wait duration

The `mysql.events_waits_current.timer_wait` attribute on `db.server.query_sample` events is
populated from `performance_schema.events_waits_current`. That consumer is **disabled by default**
on all supported platforms. Without it, `timer_wait` is always `0`.

#### Required privilege

The database user must have `UPDATE` on `performance_schema.setup_consumers` in addition to the
`SELECT` grant above:

```sql
GRANT SELECT ON performance_schema.* TO '<your-user>'@'%';
GRANT UPDATE ON performance_schema.setup_consumers TO '<your-user>'@'%';
```

#### Enabling the consumer

**Manual server (MySQL 5.7 / 8.x / MariaDB) — persistent across restarts**

Add to `[mysqld]` in `my.cnf` / `my.ini`:

```ini
performance-schema-consumer-events-waits-current=ON
```

**AWS RDS (MySQL 5.7 / 8.x / MariaDB) — runtime only**

AWS RDS does not expose `performance-schema-consumer-events-waits-current` as a parameter group
setting. The consumer must be enabled at runtime and will reset on instance restart or failover:

```sql
UPDATE performance_schema.setup_consumers
SET ENABLED = 'YES'
WHERE NAME = 'events_waits_current';
```

Run this statement after each restart, or grant the receiver user `UPDATE` on
`performance_schema.setup_consumers` so that the receiver can re-enable it automatically on
reconnect.
Loading
Loading