> ## Documentation Index
> Fetch the complete documentation index at: https://otel.fyi/llms.txt
> Use this file to discover all available pages before exploring further.

# Mysql

> OpenTelemetry receiver for Mysql

# Mysql Receiver

![Status](https://img.shields.io/badge/status-beta-yellow)

**Available in:** `contrib`

**Maintainers:** [@antonblock](https://github.com/antonblock), [@ishleenk17](https://github.com/ishleenk17), [@ebrdarSplunk](https://github.com/ebrdarSplunk), [@XSAM](https://github.com/XSAM), [@akshays-19](https://github.com/akshays-19), [@sv-splunk](https://github.com/sv-splunk), [@splunk-shanu](https://github.com/splunk-shanu)

**Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver)

## Supported Telemetry

![Logs](https://img.shields.io/badge/logs-development-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green)

## Overview

This receiver queries MySQL's global status and InnoDB tables.

Some metrics will not appear if their corresponding feature is inactive.\
There are also optional metrics that you must specify in your configuration to collect, listed in [documentation.md](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/documentation.md)

## Prerequisites

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](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/COMPATIBILITY.md) for full details on version-gated behavior and fallbacks.

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

Collecting query samples requires the `performance_schema` to be enabled:

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

Collecting disabled-by-default InnoDB redo-log LSN and checkpoint-age metrics requires
MySQL 8.0.11 or later. For MySQL 8.0.11 through 8.0.29, grant the receiver user
`SELECT` on `performance_schema` and the `BACKUP_ADMIN` dynamic privilege:

```sql theme={null}
GRANT SELECT ON performance_schema.* TO '<your-user>'@'%';
GRANT BACKUP_ADMIN ON *.* TO '<your-user>'@'%';
```

MySQL 8.0.30 and later versions do not require `BACKUP_ADMIN` for these metrics.

## Configuration

The following settings are optional:

* `endpoint`: (default = `localhost:3306`)
* `tls`: Defines the TLS configuration to use. If `tls` is not set, the default is to disable TLS connections.
  * `insecure`: (default = `false`) Set this to `true` to disable TLS connections.
  * `insecure_skip_verify`: (default = `false`) Set this to `true` to enable TLS but not verify the certificate.
  * `server_name_override`: This sets the ServerName in the TLSConfig.
* `username`: (default = `root`)
* `password`: A static MySQL password.
* `db_auth`: Component ID of a `dbauth` provider extension (for example `aws_iam_db_auth`). Mutually exclusive with `password`. Requires TLS (`tls.insecure: false`). RDS MySQL/Aurora MySQL only. Cleartext password auth (`mysql_clear_password`) is enabled automatically for IAM tokens over TLS.

```yaml theme={null}
extensions:
  aws_iam_db_auth:
    region: us-east-2

receivers:
  mysql:
    endpoint: my-database.example.com:3306
    username: monitor
    db_auth: aws_iam_db_auth
    tls:
      insecure: false

service:
  extensions: [aws_iam_db_auth]
```

* `allow_native_passwords`: (default = `true`)

* `database`: The database name. If not specified, metrics will be collected for all databases.

* `collection_interval` (default = `10s`): This receiver collects metrics on an interval. This value must be a string readable by Golang's [time.ParseDuration](https://pkg.go.dev/time#ParseDuration). Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`.

* `initial_delay` (default = `1s`): defines how long this receiver waits before starting.

* `transport`: (default = `tcp`): Defines the network to use for connecting to the server.

* `statement_events`: Additional configuration for query to build `mysql.statement_events.count` and `mysql.statement_events.wait.time` metrics:
  * `digest_text_limit` - maximum length of `digest_text`. Longer text will be truncated (default=`120`)
  * `time_limit` - maximum time from since the statements have been observed last time (default=`24h`)
  * `limit` - limit of records, which is maximum number of generated metrics (default=`250`)

* `query_sample_collection`: Additional configuration for query sample collection(`db.server.query_sample` event):
  * `max_rows_per_query` - maximum number of rows to collect per scrape (default=`100`)

* `top_query_collection`: Additional configuration for top queries collection (`db.server.top_query` event):
  * `lookback_time` (optional, example = `60`, default = `2 * collection_interval`): The time window (in seconds) in which to query for top queries.
    * Queries that finished execution outside the lookback window are not included in the collection. Increasing the lookback window will be useful for capturing long-running queries.
  * `max_query_sample_count` (optional, example = `5000`, default = `1000`): The maximum number of records to fetch in a single run.
  * `top_query_count`: (optional, example = `100`, default = `200`): The maximum number of active queries to report (to the next consumer) in a single run.
  * `collection_interval`: (optional, default = `60s`): The interval at which top queries should be emitted by this receiver.
    * This value can only guarantee that the top queries are collected at most once in this interval.
      * For instance, you have global `collection_interval` set to `10s` and `top_query_collection.collection_interval` set to `60s`.
        * In this case, the default receiver scraper will still run every 10 seconds.
        * However, the top queries collection will only run after 60 seconds have passed since the last collection.
      * For instance, you have global `collection_interval` set to `10s` and `top_query_collection.collection_interval` set to `5s`.
        * In this case, `top_query_collection.collection_interval` will have no impact on the collection frequency, which will run every 10s.
  * `query_plan_cache_size`: (optional, default = `1000`). The query plan cache size. Once we got query plan results from explain queries, we will store them in the cache.
    This defines the cache's size for query plan.
  * `query_plan_cache_ttl`: (optional, example = `1m`, default = `1h`). How long until a query plan expires in the cache. The receiver will run an explain query to MySQL to get the query plan after it expires.

### Example Configuration

```yaml theme={null}
receivers:
  mysql:
    endpoint: localhost:3306
    username: otel
    password: ${env:MYSQL_PASSWORD}
    database: otel
    collection_interval: 10s
    initial_delay: 1s
    statement_events:
      digest_text_limit: 120
      time_limit: 24h
      limit: 250
```

The full list of settings exposed for this receiver are documented in [config.go](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/config.go) with detailed sample configurations in [testdata/config.yaml](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/testdata/config.yaml).

### Resource attributes

The receiver reports the network location of the monitored instance as the `server.address` and
`server.port` resource attributes.

When `endpoint` is a loopback address (for example `localhost:3306` or `127.0.0.1:3306`),
`server.address` reports the host name of the machine running the collector rather than the
configured host. A loopback endpoint is only reachable when the instance is co-located with the
collector, so the collector host's name is the instance's real network identity; reported verbatim,
every monitored host would emit the same address. A non-loopback endpoint is reported as configured.
With `transport: unix`, `server.address` is the socket path and `server.port` is not reported.

Both attributes are enabled by default and can be turned off individually:

```yaml theme={null}
receivers:
  mysql:
    resource_attributes:
      server.address:
        enabled: false
      server.port:
        enabled: false
```

## Metrics

Details about the metrics produced by this receiver can be found in [metadata.yaml](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/metadata.yaml)

## Logs

Details about the logs produced by this receiver can be found in [documentation.md](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/mysqlreceiver/documentation.md)

**Trace propagation:** Query sample log records carry a TraceID and SpanID only when
a MySQL session sets the `@traceparent` user variable (W3C TraceContext format,
lowercase name). The collector extracts the TraceID and SpanID from that value and
stamps the application's trace context onto the corresponding log record. Log records
without a `@traceparent` will have empty TraceID and SpanID fields. This allows
application transactions to be correlated with query samples collected by this receiver.

> **Note:** MySQL stores user variable names in lowercase in
> `performance_schema.user_variables_by_thread` regardless of how the client
> 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.

### Splitting the execution plan onto its own event

`db.server.top_query` and `db.server.query_sample` each carry the statement's execution plan in their
`mysql.query_plan` attribute. The plan is the output of `EXPLAIN FORMAT=json`, a nested document with
one object per table access, so it can dominate the record it travels on.

Enabling `db.server.query_plan` reports the plan on a record of its own, where it can be filtered,
routed or dropped independently of the query statistics and the session activity, and where an
oversized plan does not take those with it when a batcher splits by size.

It is disabled by default. It reports plans that `db.server.top_query` and `db.server.query_sample`
already collect, so it adds no queries and needs no grants of its own, and enabling it without either
of those events is a configuration error. Each of them contributes plans only while it is itself
enabled.

```yaml theme={null}
events:
  db.server.top_query:
    enabled: true
  db.server.query_sample:
    enabled: true
  db.server.query_plan:   # both events above lose their mysql.query_plan
    enabled: true
```

Both source events are then emitted **without** their `mysql.query_plan` attribute, and the plan is
reported on `db.server.query_plan`, joined back via `mysql.query_plan.hash` and `db.namespace`. A
statement with no plan available produces no record.

`mysql.query_plan.source` holds the name of the event each plan was reported for, so one literal
matches both the attribute and the record's event name in a routing rule, and plans from one source
can be routed or dropped without touching the other. The two differ in cadence and volume: top query
plans follow `top_query_collection.collection_interval` and are bounded by `top_query_count`, while
sample plans follow the receiver's `collection_interval`.

Several sessions can be running one statement when a sample scrape fires, and they share a plan, so
sample plans are reported once per scrape rather than once per sample. Plans are identified by
`db.namespace` and `mysql.query_plan.hash`, which means:

* One digest executed in several databases produces one record per database, since the plan is
  collected per database. `performance_schema.events_statements_summary_by_digest` is keyed on schema
  and digest, so such a digest also produces one `db.server.top_query` record per database, and
  `db.namespace` is what pairs each of those with its own plan.
* `db.server.top_query` reports the database as the `schema_name` the statement was summarized under,
  while `db.server.query_sample` reports the session's current database. For one statement these can
  differ, so the same plan can appear under two `db.namespace` values across the two events.

On MySQL 5.7 and MariaDB there is no `query_sample_text` to explain, so `db.server.top_query` has no
plan to report on those versions (see the table under [Supported database
versions](#supported-database-versions)) and enabling `db.server.query_plan` there reports sample
plans only.

### MySQL Requirements to enable log collection

| Parameter | Value | Description |
| - | - | - |
| `performance_schema` | Enabled (Required) | Enable performance schema |
| `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 theme={null}
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 theme={null}
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 theme={null}
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.

## Metrics

| Metric Name | Description | Unit | Type | Attributes |
| - | - | - | - | - |
| ✅ `mysql.buffer_pool.data_pages` | The number of data pages in the InnoDB buffer pool. | 1 | UpDownCounter | buffer\_pool\_data |
| ✅ `mysql.buffer_pool.limit` | The configured size of the InnoDB buffer pool. | By | UpDownCounter | |
| ✅ `mysql.buffer_pool.operations` | The number of operations on the InnoDB buffer pool. | 1 | Counter | buffer\_pool\_operations |
| ✅ `mysql.buffer_pool.page_flushes` | The number of requests to flush pages from the InnoDB buffer pool. | 1 | Counter | |
| ✅ `mysql.buffer_pool.pages` | The number of pages in the InnoDB buffer pool. | 1 | UpDownCounter | buffer\_pool\_pages |
| ✅ `mysql.buffer_pool.usage` | The number of bytes in the InnoDB buffer pool. | By | UpDownCounter | buffer\_pool\_data |
| ❌ `mysql.client.network.io` | The number of transmitted bytes between server and clients. | By | Counter | direction |
| ❌ `mysql.commands` | The number of times each type of command has been executed. | 1 | Counter | command |
| ❌ `mysql.connection.count` | The number of connection attempts (successful or not) to the MySQL server. | 1 | Counter | |
| ❌ `mysql.connection.errors` | Errors that occur during the client connection process. | 1 | Counter | connection\_error |
| ✅ `mysql.double_writes` | The number of writes to the InnoDB doublewrite buffer. | 1 | Counter | double\_writes |
| ❌ `mysql.file.open` | The number of currently open files. | 1 | Gauge | |
| ✅ `mysql.handlers` | The number of requests to various MySQL handlers. | 1 | Counter | handler |
| ✅ `mysql.index.io.wait.count` | The total count of I/O wait events for an index. | 1 | Counter | io\_waits\_operations, table\_name, schema, index\_name |
| ✅ `mysql.index.io.wait.time` | The total time of I/O wait events for an index. | ns | Counter | io\_waits\_operations, table\_name, schema, index\_name |
| ❌ `mysql.innodb.data_file.io` | The total bytes read from and written to InnoDB data files. | By | Counter | disk.io.direction |
| ❌ `mysql.innodb.history_list.length` | The length of the InnoDB history list. | \{transactions} | Gauge | |
| ❌ `mysql.innodb.operation.pending` | The number of pending InnoDB data file operations. | 1 | UpDownCounter | operations |
| ❌ `mysql.innodb.redo_log.checkpoint.age` | The difference, in bytes, between the current InnoDB redo log sequence number and the most recent checkpoint log sequence number. | By | Gauge | |
| ❌ `mysql.innodb.redo_log.lsn.checkpoint` | The InnoDB redo log sequence number of the most recent checkpoint. | By | Gauge | |
| ❌ `mysql.innodb.redo_log.lsn.current` | The current InnoDB redo log sequence number. | By | Gauge | |
| ❌ `mysql.innodb.row_lock.wait.count` | The number of InnoDB row lock waits currently pending. | \{wait} | Gauge | |
| ❌ `mysql.innodb.row_lock.wait.duration.avg` | The average InnoDB row lock wait duration since server startup or last status reset. | s | Gauge | |
| ❌ `mysql.innodb.row_lock.wait.duration.max` | The maximum InnoDB row lock wait duration since server startup or last status reset. | s | Gauge | |
| ❌ `mysql.innodb.transaction.active.count` | The number of active InnoDB transactions. | \{transaction} | Gauge | |
| ❌ `mysql.innodb.transaction.active.duration.max` | The duration of the longest running active InnoDB transaction. | s | Gauge | |
| ❌ `mysql.joins` | The number of joins that perform table scans. | 1 | Counter | join\_kind |
| ✅ `mysql.locks` | The number of MySQL locks. | 1 | Counter | locks |
| ✅ `mysql.log_operations` | The number of InnoDB log operations. | 1 | Counter | log\_operations |
| ❌ `mysql.max_used_connections` | Maximum number of connections used simultaneously since the server started. | 1 | UpDownCounter | |
| ❌ `mysql.myisam.key_cache.block.unused` | The number of unused MyISAM key cache blocks. | \{block} | Gauge | |
| ❌ `mysql.myisam.key_cache.block.used.max` | The maximum number of MyISAM key cache blocks simultaneously in use since the server started or status counters were reset. | \{block} | Gauge | |
| ❌ `mysql.myisam.key_cache.disk.operation` | The number of physical MyISAM key cache disk operations. | \{operation} | Counter | mysql.myisam.key\_cache.operation.type |
| ❌ `mysql.myisam.key_cache.request` | The number of logical MyISAM key cache requests. | \{request} | Counter | mysql.myisam.key\_cache.operation.type |
| ✅ `mysql.mysqlx_connections` | The number of mysqlx connections. | 1 | Counter | connection\_status |
| ❌ `mysql.mysqlx_worker_threads` | The number of worker threads available. | 1 | UpDownCounter | mysqlx\_threads |
| ✅ `mysql.opened_resources` | The number of opened resources. | 1 | Counter | opened\_resources |
| ✅ `mysql.operations` | The number of InnoDB operations. | 1 | Counter | operations |
| ✅ `mysql.page_operations` | The number of InnoDB page operations. | 1 | Counter | page\_operations |
| ❌ `mysql.page_size` | InnoDB page size. | By | UpDownCounter | |
| ✅ `mysql.prepared_statements` | The number of times each type of prepared statement command has been issued. | 1 | Counter | prepared\_statements\_command |
| ❌ `mysql.query.client.count` | The number of statements executed by the server. This includes only statements sent to the server by clients. | 1 | Counter | |
| ❌ `mysql.query.count` | The number of statements executed by the server. | 1 | Counter | |
| ❌ `mysql.query.execution.time` | The total execution time of SQL statements tracked by the server. | s | Counter | |
| ❌ `mysql.query.slow.count` | The number of slow queries. | 1 | Counter | |
| ❌ `mysql.replica.sql_delay` | The number of seconds that the replica must lag the source. | s | UpDownCounter | |
| ❌ `mysql.replica.temp_table.open` | The number of temporary tables currently open by the replica while applying replicated events. | \{table} | Gauge | |
| ❌ `mysql.replica.thread.running` | Whether the replica IO and SQL threads report a running status. A value of 1 means the thread reports Yes; 0 means any other status, including No or Connecting. | 1 | Gauge | mysql.replica.thread.type, mysql.replica.channel.name |
| ❌ `mysql.replica.time_behind_source` | This field is an indication of how “late” the replica is. | s | UpDownCounter | |
| ✅ `mysql.row_locks` | The number of InnoDB row locks. | 1 | Counter | row\_locks |
| ✅ `mysql.row_operations` | The number of InnoDB row operations. | 1 | Counter | row\_operations |
| ❌ `mysql.server.healthy` | The health status of the MySQL server. | 1 | Gauge | |
| ❌ `mysql.session.active.count` | The number of active MySQL sessions with query text and state. | \{session} | Gauge | |
| ✅ `mysql.sorts` | The number of MySQL sorts. | 1 | Counter | sorts |
| ❌ `mysql.statement_event.count` | Summary of current and recent statement events. | 1 | UpDownCounter | schema, digest, digest\_text, event\_state |
| ❌ `mysql.statement_event.wait.time` | The total wait time of the summarized timed events. | ns | UpDownCounter | schema, digest, digest\_text |
| ❌ `mysql.table.average_row_length` | The average row length in bytes for a given table. | By | UpDownCounter | table\_name, schema |
| ✅ `mysql.table.io.wait.count` | The total count of I/O wait events for a table. | 1 | Counter | io\_waits\_operations, table\_name, schema |
| ✅ `mysql.table.io.wait.time` | The total time of I/O wait events for a table. | ns | Counter | io\_waits\_operations, table\_name, schema |
| ❌ `mysql.table.lock_wait.read.count` | The total table lock wait read events. | 1 | UpDownCounter | schema, table\_name, read\_lock\_type |
| ❌ `mysql.table.lock_wait.read.time` | The total table lock wait read events times. | ns | UpDownCounter | schema, table\_name, read\_lock\_type |
| ❌ `mysql.table.lock_wait.write.count` | The total table lock wait write events. | 1 | UpDownCounter | schema, table\_name, write\_lock\_type |
| ❌ `mysql.table.lock_wait.write.time` | The total table lock wait write events times. | ns | UpDownCounter | schema, table\_name, write\_lock\_type |
| ❌ `mysql.table.open` | The number of currently open tables. | 1 | Gauge | |
| ❌ `mysql.table.rows` | The number of rows for a given table. | 1 | UpDownCounter | table\_name, schema |
| ❌ `mysql.table.size` | The table size in bytes for a given table. | By | UpDownCounter | table\_name, schema, table\_size\_type |
| ❌ `mysql.table_open_cache` | The number of hits, misses or overflows for open tables cache lookups. | 1 | Counter | cache\_status |
| ❌ `mysql.thread.slow_launch` | The number of threads that have taken more than slow\_launch\_time seconds to create. | 1 | Counter | |
| ✅ `mysql.threads` | The state of MySQL threads. | 1 | UpDownCounter | threads |
| ✅ `mysql.tmp_resources` | The number of created temporary resources. | 1 | Counter | tmp\_resource |
| ✅ `mysql.uptime` | The number of seconds that the server has been up. | s | Counter | |

## Attributes

| Attribute Name | Description | Type | Values |
| - | - | - | - |
| `status` | The status of buffer pool data. | string | `dirty`, `clean` |
| `operation` | The buffer pool operations types. | string | `read_ahead_rnd`, `read_ahead`, `read_ahead_evicted`, `read_requests`, `reads`, `wait_free`, `write_requests` |
| `kind` | The buffer pool pages types. | string | `data`, `free`, `misc`, `total` |
| `status` | The status of cache access. | string | `hit`, `miss`, `overflow` |
| `client.address` | Hostname or address of the client. | string | |
| `client.port` | TCP port used by the client. | int | |
| `command` | The command types. | string | `alter_table`, `create_index`, `create_table`, `delete`, `delete_multi`, `insert`, `optimize`, `select`, `update`, `update_multi` |
| `error` | The connection error type. | string | `accept`, `internal`, `max_connections`, `peer_address`, `select`, `tcpwrap`, `aborted`, `aborted_clients`, `locked` |
| `status` | The connection status. | string | `accepted`, `closed`, `rejected` |
| `db.namespace` | The database the statement ran in, or empty if none is known. | string | |
| `db.query.text` | The SQL statement text for the event. | string | |
| `db.system.name` | The name of the database system. | string | `mysql` |
| `digest` | Digest. | string | |
| `digest_text` | Text before digestion. | string | |
| `kind` | The name of the transmission direction. | string | `received`, `sent` |
| `disk.io.direction` | The disk IO operation direction. | string | `read`, `write` |
| `kind` | The doublewrite types. | string | `pages_written`, `writes` |
| `kind` | Possible event states. | string | `errors`, `warnings`, `rows_affected`, `rows_sent`, `rows_examined`, `created_tmp_disk_tables`, `created_tmp_tables`, `sort_merge_passes`, `sort_rows`, `no_index_used` |
| `kind` | The handler types. | string | `commit`, `delete`, `discover`, `external_lock`, `mrr_init`, `prepare`, `read_first`, `read_key`, `read_last`, `read_next`, `read_prev`, `read_rnd`, `read_rnd_next`, `rollback`, `savepoint`, `savepoint_rollback`, `update`, `write` |
| `index` | The name of the index. | string | |
| `operation` | The io\_waits operation type. | string | `delete`, `fetch`, `insert`, `update` |
| `kind` | The kind of join. | string | `full`, `full_range`, `range`, `range_check`, `scan` |
| `kind` | The table locks type. | string | `immediate`, `waited` |
| `operation` | The log operation types. 'fsyncs' aren't available in MariaDB 10.8 or later. | string | `waits`, `write_requests`, `writes`, `fsyncs` |
| `mysql.event_id` | The thread associated with the event and the thread current event number when the event starts. | int | |
| `mysql.events_statements_current.digest` | The statement digest SHA-256 value as a string of 64 hexadecimal characters, or empty if the statements\_digest consumer is no. | string | |
| `mysql.events_statements_current.timer_wait` | Elapsed time the current statement has been executing, in seconds. | double | |
| `mysql.events_statements_summary_by_digest.count_star` | The number of times the statement was executed, report in delta value. | int | |
| `mysql.events_statements_summary_by_digest.digest` | The statement digest SHA-256 value as a string of 64 hexadecimal characters, or empty if the statements\_digest consumer is no. | string | |
| `mysql.events_statements_summary_by_digest.sum_timer_wait` | The total time spent executing the statement, report in delta seconds. | double | |
| `mysql.events_waits_current.timer_wait` | Timing information for the event, indicating elapsed time the event waited in seconds. | double | |
| `operation` | The MyISAM key cache operation type. | string | `read`, `write` |
| `mysql.query_plan` | The query plan for the statement, if available. | string | |
| `mysql.query_plan.hash` | This attribute is set to the same value as mysql.events\_statements\_summary\_by\_digest.digest (query digest) by design. | string | |
| `mysql.query_plan.source` | The event the plan was reported for, so plans can be routed or dropped per source event. | string | `db.server.top_query`, `db.server.query_sample` |
| `mysql.replica.channel.name` | The replication channel name. | string | |
| `mysql.replica.thread.type` | The replica thread type. | string | `io`, `sql` |
| `mysql.session.id` | The unique identifier for the session associated with the event. | int | |
| `mysql.session.status` | Simplified session status, either 'waiting', 'running' or 'other'. | string | |
| `mysql.threads.processlist_command` | The type of command the thread is executing on behalf of the client for foreground threads, or `Sleep` if the session is idle. | string | |
| `mysql.threads.processlist_state` | An action, event, or state that indicates what the thread is doing. | string | |
| `mysql.threads.thread_id` | The unique identifier for the thread executing the statement. | int | |
| `mysql.wait_type` | The name of the instrument that produced the event. | string | |
| `kind` | The worker thread count kind. | string | `available`, `active` |
| `network.peer.address` | IP address of the peer client. | string | |
| `network.peer.port` | TCP port used by the peer client. | int | |
| `kind` | The kind of the resource. | string | `file`, `table_definition`, `table` |
| `operation` | The operation types. | string | `fsyncs`, `reads`, `writes` |
| `operation` | The page operation types. | string | `created`, `read`, `written` |
| `command` | The prepare statement command types. | string | `execute`, `close`, `fetch`, `prepare`, `reset`, `send_long_data` |
| `kind` | Read operation types. | string | `normal`, `with_shared_locks`, `high_priority`, `no_insert`, `external` |
| `kind` | The row lock type. | string | `waits`, `time` |
| `operation` | The row operation type. | string | `deleted`, `inserted`, `read`, `updated` |
| `schema` | The schema of the object. | string | |
| `kind` | The sort count type. | string | `merge_passes`, `range`, `rows`, `scan` |
| `table` | Table name for event or process. | string | |
| `kind` | The table size types. | string | `data`, `index` |
| `kind` | The thread count type. | string | `cached`, `connected`, `created`, `running` |
| `resource` | The kind of temporary resources. | string | `disk_tables`, `files`, `tables` |
| `user.name` | The user associated with a foreground thread, empty for a background thread (originally processlist\_user). | string | |
| `kind` | Write operation types. | string | `allow_write`, `concurrent_insert`, `low_priority`, `normal`, `external` |

## Resource Attributes

| Attribute Name | Description | Type | Enabled |
| - | - | - | - |
| `db.system.name` | The database product of the instance. Examples include "mysql" and "mariadb". | string | ❌ |
| `db.system.version` | The database version of the instance. Examples include "8.0.34" and "10.11.7-MariaDB". | string | ❌ |
| `mysql.instance.endpoint` | Endpoint of the MySQL instance. | string | ✅ |
| `server.address` | The address of the monitored MySQL instance. A loopback endpoint (for example localhost or 127.0.0.1) is reported as the host name of the machine running the collector, since the instance is co-located with it. With a Unix socket transport this is the socket path. | string | ✅ |
| `server.port` | The port of the monitored MySQL instance. Not reported with a Unix socket transport. | int | ✅ |
| `service.instance.id` | A unique identifier of the MySQL instance as a UUID v5, derived from the endpoint using the OTel namespace. | string | ✅ |
| `service.name` | Logical name of the service. When enabled, defaults to unknown\_service:mysql. | string | ❌ |
| `service.namespace` | Logical namespace for the service (for example team or environment). When enabled, defaults to an empty string until set via configuration. | string | ❌ |

## Configuration

### Example Configuration

```yaml theme={null}
mysql:
  endpoint: localhost:3306
  username: otel
  password: ${env:MYSQL_PASSWORD}
  database: otel
  collection_interval: 10s
mysql/default_tls:
  endpoint: localhost:3306
  username: otel
  password: ${env:MYSQL_PASSWORD}
  database: otel
  collection_interval: 10s
  tls: # specified, but use default values
    server_name_override: localhost
```

***

*Last generated: 2026-10-05*
