From e6083b50b2e199d40eacfcb07db1ba85a83ac949 Mon Sep 17 00:00:00 2001
From: Adam Boguszewski <108867528+aboguszewski-sumo@users.noreply.github.com>
Date: Fri, 23 Sep 2022 15:09:53 +0200
Subject: [PATCH] [receiver/mysql]: add scraping io_waits metrics (#14328)
---
receiver/mysqlreceiver/client.go | 79 +++
receiver/mysqlreceiver/documentation.md | 8 +
.../internal/metadata/generated_metrics.go | 304 +++++++++++
receiver/mysqlreceiver/metadata.yaml | 49 ++
receiver/mysqlreceiver/scraper.go | 72 +++
receiver/mysqlreceiver/scraper_test.go | 77 ++-
.../testdata/integration/expected.5_7.json | 492 ++++++++++++++++++
.../testdata/integration/expected.8_0.json | 492 ++++++++++++++++++
.../testdata/integration/scripts/setup.sh | 16 +-
.../testdata/scraper/expected.json | 492 ++++++++++++++++++
.../testdata/scraper/index_io_waits_stats.txt | 1 +
.../scraper/index_io_waits_stats_empty.txt | 0
.../testdata/scraper/table_io_waits_stats.txt | 1 +
.../scraper/table_io_waits_stats_empty.txt | 0
.../mysql-receiver-add-perf-io-waits.yaml | 5 +
15 files changed, 2081 insertions(+), 7 deletions(-)
create mode 100644 receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats.txt
create mode 100644 receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats_empty.txt
create mode 100644 receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats.txt
create mode 100644 receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats_empty.txt
create mode 100644 unreleased/mysql-receiver-add-perf-io-waits.yaml
diff --git a/receiver/mysqlreceiver/client.go b/receiver/mysqlreceiver/client.go
index 72336777e6ad..e53eb2b22a5b 100644
--- a/receiver/mysqlreceiver/client.go
+++ b/receiver/mysqlreceiver/client.go
@@ -26,6 +26,8 @@ type client interface {
Connect() error
getGlobalStats() (map[string]string, error)
getInnodbStats() (map[string]string, error)
+ getTableIoWaitsStats() ([]TableIoWaitsStats, error)
+ getIndexIoWaitsStats() ([]IndexIoWaitsStats, error)
Close() error
}
@@ -34,6 +36,28 @@ type mySQLClient struct {
client *sql.DB
}
+type IoWaitsStats struct {
+ schema string
+ name string
+ countDelete int64
+ countFetch int64
+ countInsert int64
+ countUpdate int64
+ timeDelete int64
+ timeFetch int64
+ timeInsert int64
+ timeUpdate int64
+}
+
+type TableIoWaitsStats struct {
+ IoWaitsStats
+}
+
+type IndexIoWaitsStats struct {
+ IoWaitsStats
+ index string
+}
+
var _ client = (*mySQLClient)(nil)
func newMySQLClient(conf *Config) client {
@@ -73,6 +97,61 @@ func (c *mySQLClient) getInnodbStats() (map[string]string, error) {
return Query(*c, query)
}
+// getTableIoWaitsStats queries the db for table_io_waits metrics.
+func (c *mySQLClient) getTableIoWaitsStats() ([]TableIoWaitsStats, error) {
+ query := "SELECT OBJECT_SCHEMA, OBJECT_NAME, " +
+ "COUNT_DELETE, COUNT_FETCH, COUNT_INSERT, COUNT_UPDATE," +
+ "SUM_TIMER_DELETE, SUM_TIMER_FETCH, SUM_TIMER_INSERT, SUM_TIMER_UPDATE" +
+ "FROM performance_schema.table_io_waits_summary_by_table" +
+ "WHERE OBJECT_SCHEMA NOT IN ('mysql', 'performance_schema');"
+ rows, err := c.client.Query(query)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var stats []TableIoWaitsStats
+ for rows.Next() {
+ var s TableIoWaitsStats
+ err := rows.Scan(&s.schema, &s.name,
+ &s.countDelete, &s.countFetch, &s.countInsert, &s.countUpdate,
+ &s.timeDelete, &s.timeFetch, &s.timeInsert, &s.timeUpdate)
+ if err != nil {
+ return nil, err
+ }
+ stats = append(stats, s)
+ }
+
+ return stats, nil
+}
+
+// getIndexIoWaitsStats queries the db for index_io_waits metrics.
+func (c *mySQLClient) getIndexIoWaitsStats() ([]IndexIoWaitsStats, error) {
+ query := "SELECT OBJECT_SCHEMA, OBJECT_NAME, ifnull(INDEX_NAME, 'NONE') as INDEX_NAME," +
+ "COUNT_FETCH, COUNT_INSERT, COUNT_UPDATE, COUNT_DELETE," +
+ "SUM_TIMER_FETCH, SUM_TIMER_INSERT, SUM_TIMER_UPDATE, SUM_TIMER_DELETE" +
+ "FROM performance_schema.table_io_waits_summary_by_index_usage" +
+ "WHERE OBJECT_SCHEMA NOT IN ('mysql', 'performance_schema');"
+
+ rows, err := c.client.Query(query)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var stats []IndexIoWaitsStats
+ for rows.Next() {
+ var s IndexIoWaitsStats
+ err := rows.Scan(&s.schema, &s.name, &s.index,
+ &s.countDelete, &s.countFetch, &s.countInsert, &s.countUpdate,
+ &s.timeDelete, &s.timeFetch, &s.timeInsert, &s.timeUpdate)
+ if err != nil {
+ return nil, err
+ }
+ stats = append(stats, s)
+ }
+
+ return stats, nil
+}
+
func Query(c mySQLClient, query string) (map[string]string, error) {
rows, err := c.client.Query(query)
if err != nil {
diff --git a/receiver/mysqlreceiver/documentation.md b/receiver/mysqlreceiver/documentation.md
index 6b59418bf883..d5d9216cf649 100644
--- a/receiver/mysqlreceiver/documentation.md
+++ b/receiver/mysqlreceiver/documentation.md
@@ -17,6 +17,8 @@ These are the metrics available for this scraper.
| **mysql.commands** | The number of times each type of command has been executed. | 1 | Sum(Int) |
|
| **mysql.double_writes** | The number of writes to the InnoDB doublewrite buffer. | 1 | Sum(Int) | |
| **mysql.handlers** | The number of requests to various MySQL handlers. | 1 | Sum(Int) | |
+| **mysql.index.io.wait.count** | The total count of I/O wait events for an index. | 1 | Sum(Int) | - 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 | Sum(Int) | - io_waits_operations
- table_name
- schema
- index_name
|
| **mysql.locks** | The number of MySQL locks. | 1 | Sum(Int) | |
| **mysql.log_operations** | The number of InnoDB log operations. | 1 | Sum(Int) | |
| **mysql.operations** | The number of InnoDB operations. | 1 | Sum(Int) | |
@@ -24,6 +26,8 @@ These are the metrics available for this scraper.
| **mysql.row_locks** | The number of InnoDB row locks. | 1 | Sum(Int) | |
| **mysql.row_operations** | The number of InnoDB row operations. | 1 | Sum(Int) | |
| **mysql.sorts** | The number of MySQL sorts. | 1 | Sum(Int) | |
+| **mysql.table.io.wait.count** | The total count of I/O wait events for a table. | 1 | Sum(Int) | - io_waits_operations
- table_name
- schema
|
+| **mysql.table.io.wait.time** | The total time of I/O wait events for a table. | ns | Sum(Int) | - io_waits_operations
- table_name
- schema
|
| **mysql.threads** | The state of MySQL threads. | 1 | Sum(Int) | |
**Highlighted metrics** are emitted by default. Other metrics are optional and not emitted by default.
@@ -51,11 +55,15 @@ metrics:
| command (command) | The command types. | execute, close, fetch, prepare, reset, send_long_data |
| double_writes (kind) | The doublewrite types. | pages_written, writes |
| handler (kind) | The handler types. | 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_name (index) | The name of the index. | |
+| io_waits_operations (operation) | The io_waits operation type. | delete, fetch, insert, update |
| locks (kind) | The table locks type. | immediate, waited |
| log_operations (operation) | The log operation types. | waits, write_requests, writes |
| operations (operation) | The operation types. | fsyncs, reads, writes |
| page_operations (operation) | The page operation types. | created, read, written |
| row_locks (kind) | The row lock type. | waits, time |
| row_operations (operation) | The row operation type. | deleted, inserted, read, updated |
+| schema (schema) | The schema of the object. | |
| sorts (kind) | The sort count type. | merge_passes, range, rows, scan |
+| table_name (table) | Table name for event or process. | |
| threads (kind) | The thread count type. | cached, connected, created, running |
diff --git a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
index cd7d1b13e4ab..f6e456542cbd 100644
--- a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
+++ b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go
@@ -28,6 +28,8 @@ type MetricsSettings struct {
MysqlCommands MetricSettings `mapstructure:"mysql.commands"`
MysqlDoubleWrites MetricSettings `mapstructure:"mysql.double_writes"`
MysqlHandlers MetricSettings `mapstructure:"mysql.handlers"`
+ MysqlIndexIoWaitCount MetricSettings `mapstructure:"mysql.index.io.wait.count"`
+ MysqlIndexIoWaitTime MetricSettings `mapstructure:"mysql.index.io.wait.time"`
MysqlLocks MetricSettings `mapstructure:"mysql.locks"`
MysqlLogOperations MetricSettings `mapstructure:"mysql.log_operations"`
MysqlOperations MetricSettings `mapstructure:"mysql.operations"`
@@ -35,6 +37,8 @@ type MetricsSettings struct {
MysqlRowLocks MetricSettings `mapstructure:"mysql.row_locks"`
MysqlRowOperations MetricSettings `mapstructure:"mysql.row_operations"`
MysqlSorts MetricSettings `mapstructure:"mysql.sorts"`
+ MysqlTableIoWaitCount MetricSettings `mapstructure:"mysql.table.io.wait.count"`
+ MysqlTableIoWaitTime MetricSettings `mapstructure:"mysql.table.io.wait.time"`
MysqlThreads MetricSettings `mapstructure:"mysql.threads"`
}
@@ -67,6 +71,12 @@ func DefaultMetricsSettings() MetricsSettings {
MysqlHandlers: MetricSettings{
Enabled: true,
},
+ MysqlIndexIoWaitCount: MetricSettings{
+ Enabled: true,
+ },
+ MysqlIndexIoWaitTime: MetricSettings{
+ Enabled: true,
+ },
MysqlLocks: MetricSettings{
Enabled: true,
},
@@ -88,6 +98,12 @@ func DefaultMetricsSettings() MetricsSettings {
MysqlSorts: MetricSettings{
Enabled: true,
},
+ MysqlTableIoWaitCount: MetricSettings{
+ Enabled: true,
+ },
+ MysqlTableIoWaitTime: MetricSettings{
+ Enabled: true,
+ },
MysqlThreads: MetricSettings{
Enabled: true,
},
@@ -354,6 +370,40 @@ var MapAttributeHandler = map[string]AttributeHandler{
"write": AttributeHandlerWrite,
}
+// AttributeIoWaitsOperations specifies the a value io_waits_operations attribute.
+type AttributeIoWaitsOperations int
+
+const (
+ _ AttributeIoWaitsOperations = iota
+ AttributeIoWaitsOperationsDelete
+ AttributeIoWaitsOperationsFetch
+ AttributeIoWaitsOperationsInsert
+ AttributeIoWaitsOperationsUpdate
+)
+
+// String returns the string representation of the AttributeIoWaitsOperations.
+func (av AttributeIoWaitsOperations) String() string {
+ switch av {
+ case AttributeIoWaitsOperationsDelete:
+ return "delete"
+ case AttributeIoWaitsOperationsFetch:
+ return "fetch"
+ case AttributeIoWaitsOperationsInsert:
+ return "insert"
+ case AttributeIoWaitsOperationsUpdate:
+ return "update"
+ }
+ return ""
+}
+
+// MapAttributeIoWaitsOperations is a helper map of string to AttributeIoWaitsOperations attribute value.
+var MapAttributeIoWaitsOperations = map[string]AttributeIoWaitsOperations{
+ "delete": AttributeIoWaitsOperationsDelete,
+ "fetch": AttributeIoWaitsOperationsFetch,
+ "insert": AttributeIoWaitsOperationsInsert,
+ "update": AttributeIoWaitsOperationsUpdate,
+}
+
// AttributeLocks specifies the a value locks attribute.
type AttributeLocks int
@@ -1071,6 +1121,118 @@ func newMetricMysqlHandlers(settings MetricSettings) metricMysqlHandlers {
return m
}
+type metricMysqlIndexIoWaitCount struct {
+ data pmetric.Metric // data buffer for generated metric.
+ settings MetricSettings // metric settings provided by user.
+ capacity int // max observed number of data points added to the metric.
+}
+
+// init fills mysql.index.io.wait.count metric with initial data.
+func (m *metricMysqlIndexIoWaitCount) init() {
+ m.data.SetName("mysql.index.io.wait.count")
+ m.data.SetDescription("The total count of I/O wait events for an index.")
+ m.data.SetUnit("1")
+ m.data.SetEmptySum()
+ m.data.Sum().SetIsMonotonic(true)
+ m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative)
+ m.data.Sum().DataPoints().EnsureCapacity(m.capacity)
+}
+
+func (m *metricMysqlIndexIoWaitCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue string, tableNameAttributeValue string, schemaAttributeValue string, indexNameAttributeValue string) {
+ if !m.settings.Enabled {
+ return
+ }
+ dp := m.data.Sum().DataPoints().AppendEmpty()
+ dp.SetStartTimestamp(start)
+ dp.SetTimestamp(ts)
+ dp.SetIntVal(val)
+ dp.Attributes().PutString("operation", ioWaitsOperationsAttributeValue)
+ dp.Attributes().PutString("table", tableNameAttributeValue)
+ dp.Attributes().PutString("schema", schemaAttributeValue)
+ dp.Attributes().PutString("index", indexNameAttributeValue)
+}
+
+// updateCapacity saves max length of data point slices that will be used for the slice capacity.
+func (m *metricMysqlIndexIoWaitCount) updateCapacity() {
+ if m.data.Sum().DataPoints().Len() > m.capacity {
+ m.capacity = m.data.Sum().DataPoints().Len()
+ }
+}
+
+// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points.
+func (m *metricMysqlIndexIoWaitCount) emit(metrics pmetric.MetricSlice) {
+ if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 {
+ m.updateCapacity()
+ m.data.MoveTo(metrics.AppendEmpty())
+ m.init()
+ }
+}
+
+func newMetricMysqlIndexIoWaitCount(settings MetricSettings) metricMysqlIndexIoWaitCount {
+ m := metricMysqlIndexIoWaitCount{settings: settings}
+ if settings.Enabled {
+ m.data = pmetric.NewMetric()
+ m.init()
+ }
+ return m
+}
+
+type metricMysqlIndexIoWaitTime struct {
+ data pmetric.Metric // data buffer for generated metric.
+ settings MetricSettings // metric settings provided by user.
+ capacity int // max observed number of data points added to the metric.
+}
+
+// init fills mysql.index.io.wait.time metric with initial data.
+func (m *metricMysqlIndexIoWaitTime) init() {
+ m.data.SetName("mysql.index.io.wait.time")
+ m.data.SetDescription("The total time of I/O wait events for an index.")
+ m.data.SetUnit("ns")
+ m.data.SetEmptySum()
+ m.data.Sum().SetIsMonotonic(true)
+ m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative)
+ m.data.Sum().DataPoints().EnsureCapacity(m.capacity)
+}
+
+func (m *metricMysqlIndexIoWaitTime) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue string, tableNameAttributeValue string, schemaAttributeValue string, indexNameAttributeValue string) {
+ if !m.settings.Enabled {
+ return
+ }
+ dp := m.data.Sum().DataPoints().AppendEmpty()
+ dp.SetStartTimestamp(start)
+ dp.SetTimestamp(ts)
+ dp.SetIntVal(val)
+ dp.Attributes().PutString("operation", ioWaitsOperationsAttributeValue)
+ dp.Attributes().PutString("table", tableNameAttributeValue)
+ dp.Attributes().PutString("schema", schemaAttributeValue)
+ dp.Attributes().PutString("index", indexNameAttributeValue)
+}
+
+// updateCapacity saves max length of data point slices that will be used for the slice capacity.
+func (m *metricMysqlIndexIoWaitTime) updateCapacity() {
+ if m.data.Sum().DataPoints().Len() > m.capacity {
+ m.capacity = m.data.Sum().DataPoints().Len()
+ }
+}
+
+// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points.
+func (m *metricMysqlIndexIoWaitTime) emit(metrics pmetric.MetricSlice) {
+ if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 {
+ m.updateCapacity()
+ m.data.MoveTo(metrics.AppendEmpty())
+ m.init()
+ }
+}
+
+func newMetricMysqlIndexIoWaitTime(settings MetricSettings) metricMysqlIndexIoWaitTime {
+ m := metricMysqlIndexIoWaitTime{settings: settings}
+ if settings.Enabled {
+ m.data = pmetric.NewMetric()
+ m.init()
+ }
+ return m
+}
+
type metricMysqlLocks struct {
data pmetric.Metric // data buffer for generated metric.
settings MetricSettings // metric settings provided by user.
@@ -1442,6 +1604,116 @@ func newMetricMysqlSorts(settings MetricSettings) metricMysqlSorts {
return m
}
+type metricMysqlTableIoWaitCount struct {
+ data pmetric.Metric // data buffer for generated metric.
+ settings MetricSettings // metric settings provided by user.
+ capacity int // max observed number of data points added to the metric.
+}
+
+// init fills mysql.table.io.wait.count metric with initial data.
+func (m *metricMysqlTableIoWaitCount) init() {
+ m.data.SetName("mysql.table.io.wait.count")
+ m.data.SetDescription("The total count of I/O wait events for a table.")
+ m.data.SetUnit("1")
+ m.data.SetEmptySum()
+ m.data.Sum().SetIsMonotonic(true)
+ m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative)
+ m.data.Sum().DataPoints().EnsureCapacity(m.capacity)
+}
+
+func (m *metricMysqlTableIoWaitCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue string, tableNameAttributeValue string, schemaAttributeValue string) {
+ if !m.settings.Enabled {
+ return
+ }
+ dp := m.data.Sum().DataPoints().AppendEmpty()
+ dp.SetStartTimestamp(start)
+ dp.SetTimestamp(ts)
+ dp.SetIntVal(val)
+ dp.Attributes().PutString("operation", ioWaitsOperationsAttributeValue)
+ dp.Attributes().PutString("table", tableNameAttributeValue)
+ dp.Attributes().PutString("schema", schemaAttributeValue)
+}
+
+// updateCapacity saves max length of data point slices that will be used for the slice capacity.
+func (m *metricMysqlTableIoWaitCount) updateCapacity() {
+ if m.data.Sum().DataPoints().Len() > m.capacity {
+ m.capacity = m.data.Sum().DataPoints().Len()
+ }
+}
+
+// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points.
+func (m *metricMysqlTableIoWaitCount) emit(metrics pmetric.MetricSlice) {
+ if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 {
+ m.updateCapacity()
+ m.data.MoveTo(metrics.AppendEmpty())
+ m.init()
+ }
+}
+
+func newMetricMysqlTableIoWaitCount(settings MetricSettings) metricMysqlTableIoWaitCount {
+ m := metricMysqlTableIoWaitCount{settings: settings}
+ if settings.Enabled {
+ m.data = pmetric.NewMetric()
+ m.init()
+ }
+ return m
+}
+
+type metricMysqlTableIoWaitTime struct {
+ data pmetric.Metric // data buffer for generated metric.
+ settings MetricSettings // metric settings provided by user.
+ capacity int // max observed number of data points added to the metric.
+}
+
+// init fills mysql.table.io.wait.time metric with initial data.
+func (m *metricMysqlTableIoWaitTime) init() {
+ m.data.SetName("mysql.table.io.wait.time")
+ m.data.SetDescription("The total time of I/O wait events for a table.")
+ m.data.SetUnit("ns")
+ m.data.SetEmptySum()
+ m.data.Sum().SetIsMonotonic(true)
+ m.data.Sum().SetAggregationTemporality(pmetric.MetricAggregationTemporalityCumulative)
+ m.data.Sum().DataPoints().EnsureCapacity(m.capacity)
+}
+
+func (m *metricMysqlTableIoWaitTime) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue string, tableNameAttributeValue string, schemaAttributeValue string) {
+ if !m.settings.Enabled {
+ return
+ }
+ dp := m.data.Sum().DataPoints().AppendEmpty()
+ dp.SetStartTimestamp(start)
+ dp.SetTimestamp(ts)
+ dp.SetIntVal(val)
+ dp.Attributes().PutString("operation", ioWaitsOperationsAttributeValue)
+ dp.Attributes().PutString("table", tableNameAttributeValue)
+ dp.Attributes().PutString("schema", schemaAttributeValue)
+}
+
+// updateCapacity saves max length of data point slices that will be used for the slice capacity.
+func (m *metricMysqlTableIoWaitTime) updateCapacity() {
+ if m.data.Sum().DataPoints().Len() > m.capacity {
+ m.capacity = m.data.Sum().DataPoints().Len()
+ }
+}
+
+// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points.
+func (m *metricMysqlTableIoWaitTime) emit(metrics pmetric.MetricSlice) {
+ if m.settings.Enabled && m.data.Sum().DataPoints().Len() > 0 {
+ m.updateCapacity()
+ m.data.MoveTo(metrics.AppendEmpty())
+ m.init()
+ }
+}
+
+func newMetricMysqlTableIoWaitTime(settings MetricSettings) metricMysqlTableIoWaitTime {
+ m := metricMysqlTableIoWaitTime{settings: settings}
+ if settings.Enabled {
+ m.data = pmetric.NewMetric()
+ m.init()
+ }
+ return m
+}
+
type metricMysqlThreads struct {
data pmetric.Metric // data buffer for generated metric.
settings MetricSettings // metric settings provided by user.
@@ -1512,6 +1784,8 @@ type MetricsBuilder struct {
metricMysqlCommands metricMysqlCommands
metricMysqlDoubleWrites metricMysqlDoubleWrites
metricMysqlHandlers metricMysqlHandlers
+ metricMysqlIndexIoWaitCount metricMysqlIndexIoWaitCount
+ metricMysqlIndexIoWaitTime metricMysqlIndexIoWaitTime
metricMysqlLocks metricMysqlLocks
metricMysqlLogOperations metricMysqlLogOperations
metricMysqlOperations metricMysqlOperations
@@ -1519,6 +1793,8 @@ type MetricsBuilder struct {
metricMysqlRowLocks metricMysqlRowLocks
metricMysqlRowOperations metricMysqlRowOperations
metricMysqlSorts metricMysqlSorts
+ metricMysqlTableIoWaitCount metricMysqlTableIoWaitCount
+ metricMysqlTableIoWaitTime metricMysqlTableIoWaitTime
metricMysqlThreads metricMysqlThreads
}
@@ -1546,6 +1822,8 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo,
metricMysqlCommands: newMetricMysqlCommands(settings.MysqlCommands),
metricMysqlDoubleWrites: newMetricMysqlDoubleWrites(settings.MysqlDoubleWrites),
metricMysqlHandlers: newMetricMysqlHandlers(settings.MysqlHandlers),
+ metricMysqlIndexIoWaitCount: newMetricMysqlIndexIoWaitCount(settings.MysqlIndexIoWaitCount),
+ metricMysqlIndexIoWaitTime: newMetricMysqlIndexIoWaitTime(settings.MysqlIndexIoWaitTime),
metricMysqlLocks: newMetricMysqlLocks(settings.MysqlLocks),
metricMysqlLogOperations: newMetricMysqlLogOperations(settings.MysqlLogOperations),
metricMysqlOperations: newMetricMysqlOperations(settings.MysqlOperations),
@@ -1553,6 +1831,8 @@ func NewMetricsBuilder(settings MetricsSettings, buildInfo component.BuildInfo,
metricMysqlRowLocks: newMetricMysqlRowLocks(settings.MysqlRowLocks),
metricMysqlRowOperations: newMetricMysqlRowOperations(settings.MysqlRowOperations),
metricMysqlSorts: newMetricMysqlSorts(settings.MysqlSorts),
+ metricMysqlTableIoWaitCount: newMetricMysqlTableIoWaitCount(settings.MysqlTableIoWaitCount),
+ metricMysqlTableIoWaitTime: newMetricMysqlTableIoWaitTime(settings.MysqlTableIoWaitTime),
metricMysqlThreads: newMetricMysqlThreads(settings.MysqlThreads),
}
for _, op := range options {
@@ -1622,6 +1902,8 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) {
mb.metricMysqlCommands.emit(ils.Metrics())
mb.metricMysqlDoubleWrites.emit(ils.Metrics())
mb.metricMysqlHandlers.emit(ils.Metrics())
+ mb.metricMysqlIndexIoWaitCount.emit(ils.Metrics())
+ mb.metricMysqlIndexIoWaitTime.emit(ils.Metrics())
mb.metricMysqlLocks.emit(ils.Metrics())
mb.metricMysqlLogOperations.emit(ils.Metrics())
mb.metricMysqlOperations.emit(ils.Metrics())
@@ -1629,6 +1911,8 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) {
mb.metricMysqlRowLocks.emit(ils.Metrics())
mb.metricMysqlRowOperations.emit(ils.Metrics())
mb.metricMysqlSorts.emit(ils.Metrics())
+ mb.metricMysqlTableIoWaitCount.emit(ils.Metrics())
+ mb.metricMysqlTableIoWaitTime.emit(ils.Metrics())
mb.metricMysqlThreads.emit(ils.Metrics())
for _, op := range rmo {
op(rm)
@@ -1729,6 +2013,16 @@ func (mb *MetricsBuilder) RecordMysqlHandlersDataPoint(ts pcommon.Timestamp, inp
return nil
}
+// RecordMysqlIndexIoWaitCountDataPoint adds a data point to mysql.index.io.wait.count metric.
+func (mb *MetricsBuilder) RecordMysqlIndexIoWaitCountDataPoint(ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue AttributeIoWaitsOperations, tableNameAttributeValue string, schemaAttributeValue string, indexNameAttributeValue string) {
+ mb.metricMysqlIndexIoWaitCount.recordDataPoint(mb.startTime, ts, val, ioWaitsOperationsAttributeValue.String(), tableNameAttributeValue, schemaAttributeValue, indexNameAttributeValue)
+}
+
+// RecordMysqlIndexIoWaitTimeDataPoint adds a data point to mysql.index.io.wait.time metric.
+func (mb *MetricsBuilder) RecordMysqlIndexIoWaitTimeDataPoint(ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue AttributeIoWaitsOperations, tableNameAttributeValue string, schemaAttributeValue string, indexNameAttributeValue string) {
+ mb.metricMysqlIndexIoWaitTime.recordDataPoint(mb.startTime, ts, val, ioWaitsOperationsAttributeValue.String(), tableNameAttributeValue, schemaAttributeValue, indexNameAttributeValue)
+}
+
// RecordMysqlLocksDataPoint adds a data point to mysql.locks metric.
func (mb *MetricsBuilder) RecordMysqlLocksDataPoint(ts pcommon.Timestamp, inputVal string, locksAttributeValue AttributeLocks) error {
val, err := strconv.ParseInt(inputVal, 10, 64)
@@ -1799,6 +2093,16 @@ func (mb *MetricsBuilder) RecordMysqlSortsDataPoint(ts pcommon.Timestamp, inputV
return nil
}
+// RecordMysqlTableIoWaitCountDataPoint adds a data point to mysql.table.io.wait.count metric.
+func (mb *MetricsBuilder) RecordMysqlTableIoWaitCountDataPoint(ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue AttributeIoWaitsOperations, tableNameAttributeValue string, schemaAttributeValue string) {
+ mb.metricMysqlTableIoWaitCount.recordDataPoint(mb.startTime, ts, val, ioWaitsOperationsAttributeValue.String(), tableNameAttributeValue, schemaAttributeValue)
+}
+
+// RecordMysqlTableIoWaitTimeDataPoint adds a data point to mysql.table.io.wait.time metric.
+func (mb *MetricsBuilder) RecordMysqlTableIoWaitTimeDataPoint(ts pcommon.Timestamp, val int64, ioWaitsOperationsAttributeValue AttributeIoWaitsOperations, tableNameAttributeValue string, schemaAttributeValue string) {
+ mb.metricMysqlTableIoWaitTime.recordDataPoint(mb.startTime, ts, val, ioWaitsOperationsAttributeValue.String(), tableNameAttributeValue, schemaAttributeValue)
+}
+
// RecordMysqlThreadsDataPoint adds a data point to mysql.threads metric.
func (mb *MetricsBuilder) RecordMysqlThreadsDataPoint(ts pcommon.Timestamp, inputVal string, threadsAttributeValue AttributeThreads) error {
val, err := strconv.ParseInt(inputVal, 10, 64)
diff --git a/receiver/mysqlreceiver/metadata.yaml b/receiver/mysqlreceiver/metadata.yaml
index 5d8a9f24c67e..65e5fa79780e 100644
--- a/receiver/mysqlreceiver/metadata.yaml
+++ b/receiver/mysqlreceiver/metadata.yaml
@@ -62,6 +62,19 @@ attributes:
value: kind
description: The thread count type.
enum: [cached, connected, created, running]
+ schema:
+ value: schema
+ description: The schema of the object.
+ io_waits_operations:
+ value: operation
+ description: The io_waits operation type.
+ enum: [delete, fetch, insert, update]
+ table_name:
+ value: table
+ description: Table name for event or process.
+ index_name:
+ value: index
+ description: The name of the index.
metrics:
mysql.buffer_pool.pages:
@@ -180,6 +193,42 @@ metrics:
monotonic: true
aggregation: cumulative
attributes: [page_operations]
+ mysql.table.io.wait.count:
+ enabled: true
+ description: The total count of I/O wait events for a table.
+ unit: 1
+ sum:
+ value_type: int
+ monotonic: true
+ aggregation: cumulative
+ attributes: [io_waits_operations, table_name, schema]
+ mysql.table.io.wait.time:
+ enabled: true
+ description: The total time of I/O wait events for a table.
+ unit: ns
+ sum:
+ value_type: int
+ monotonic: true
+ aggregation: cumulative
+ attributes: [io_waits_operations, table_name, schema]
+ mysql.index.io.wait.count:
+ enabled: true
+ description: The total count of I/O wait events for an index.
+ unit: 1
+ sum:
+ value_type: int
+ monotonic: true
+ aggregation: cumulative
+ attributes: [io_waits_operations, table_name, schema, index_name]
+ mysql.index.io.wait.time:
+ enabled: true
+ description: The total time of I/O wait events for an index.
+ unit: ns
+ sum:
+ value_type: int
+ monotonic: true
+ aggregation: cumulative
+ attributes: [io_waits_operations, table_name, schema, index_name]
mysql.row_locks:
enabled: true
description: The number of InnoDB row locks.
diff --git a/receiver/mysqlreceiver/scraper.go b/receiver/mysqlreceiver/scraper.go
index cb133fa28fb1..b2c744acf845 100644
--- a/receiver/mysqlreceiver/scraper.go
+++ b/receiver/mysqlreceiver/scraper.go
@@ -29,6 +29,10 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver/internal/metadata"
)
+const (
+ picosecondsInNanoseconds int64 = 1000
+)
+
type mySQLScraper struct {
sqlclient client
logger *zap.Logger
@@ -90,6 +94,10 @@ func (m *mySQLScraper) scrape(context.Context) (pmetric.Metrics, error) {
addPartialIfError(errs, m.mb.RecordMysqlBufferPoolLimitDataPoint(now, v))
}
+ // collect io_waits metrics.
+ m.scrapeTableIoWaitsStats(now, errs)
+ m.scrapeIndexIoWaitsStats(now, errs)
+
// collect global status metrics.
globalStats, err := m.sqlclient.getGlobalStats()
if err != nil {
@@ -276,6 +284,70 @@ func (m *mySQLScraper) scrape(context.Context) (pmetric.Metrics, error) {
return m.mb.Emit(), errs.Combine()
}
+func (m *mySQLScraper) scrapeTableIoWaitsStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
+ tableIoWaitsStats, err := m.sqlclient.getTableIoWaitsStats()
+ if err != nil {
+ m.logger.Error("Failed to fetch table io_waits stats", zap.Error(err))
+ errs.AddPartial(8, err)
+ return
+ }
+
+ for i := 0; i < len(tableIoWaitsStats); i++ {
+ s := tableIoWaitsStats[i]
+ // counts
+ m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countDelete, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema)
+ m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countFetch, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema)
+ m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countInsert, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema)
+ m.mb.RecordMysqlTableIoWaitCountDataPoint(now, s.countUpdate, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema)
+
+ // times
+ m.mb.RecordMysqlTableIoWaitTimeDataPoint(
+ now, s.timeDelete/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema,
+ )
+ m.mb.RecordMysqlTableIoWaitTimeDataPoint(
+ now, s.timeFetch/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema,
+ )
+ m.mb.RecordMysqlTableIoWaitTimeDataPoint(
+ now, s.timeInsert/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema,
+ )
+ m.mb.RecordMysqlTableIoWaitTimeDataPoint(
+ now, s.timeUpdate/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema,
+ )
+ }
+}
+
+func (m *mySQLScraper) scrapeIndexIoWaitsStats(now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) {
+ indexIoWaitsStats, err := m.sqlclient.getIndexIoWaitsStats()
+ if err != nil {
+ m.logger.Error("Failed to fetch index io_waits stats", zap.Error(err))
+ errs.AddPartial(8, err)
+ return
+ }
+
+ for i := 0; i < len(indexIoWaitsStats); i++ {
+ s := indexIoWaitsStats[i]
+ // counts
+ m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countDelete, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema, s.index)
+ m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countFetch, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema, s.index)
+ m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countInsert, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema, s.index)
+ m.mb.RecordMysqlIndexIoWaitCountDataPoint(now, s.countUpdate, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema, s.index)
+
+ // times
+ m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
+ now, s.timeDelete/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsDelete, s.name, s.schema, s.index,
+ )
+ m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
+ now, s.timeFetch/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsFetch, s.name, s.schema, s.index,
+ )
+ m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
+ now, s.timeInsert/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsInsert, s.name, s.schema, s.index,
+ )
+ m.mb.RecordMysqlIndexIoWaitTimeDataPoint(
+ now, s.timeUpdate/picosecondsInNanoseconds, metadata.AttributeIoWaitsOperationsUpdate, s.name, s.schema, s.index,
+ )
+ }
+}
+
func addPartialIfError(errors *scrapererror.ScrapeErrors, err error) {
if err != nil {
errors.AddPartial(1, err)
diff --git a/receiver/mysqlreceiver/scraper_test.go b/receiver/mysqlreceiver/scraper_test.go
index d881fdfaf64d..b6a940d7436b 100644
--- a/receiver/mysqlreceiver/scraper_test.go
+++ b/receiver/mysqlreceiver/scraper_test.go
@@ -42,8 +42,10 @@ func TestScrape(t *testing.T) {
scraper := newMySQLScraper(componenttest.NewNopReceiverCreateSettings(), cfg)
scraper.sqlclient = &mockClient{
- globalStatsFile: "global_stats",
- innodbStatsFile: "innodb_stats",
+ globalStatsFile: "global_stats",
+ innodbStatsFile: "innodb_stats",
+ tableIoWaitsFile: "table_io_waits_stats",
+ indexIoWaitsFile: "index_io_waits_stats",
}
actualMetrics, err := scraper.scrape(context.Background())
@@ -64,8 +66,10 @@ func TestScrape(t *testing.T) {
scraper := newMySQLScraper(componenttest.NewNopReceiverCreateSettings(), cfg)
scraper.sqlclient = &mockClient{
- globalStatsFile: "global_stats_partial",
- innodbStatsFile: "innodb_stats_empty",
+ globalStatsFile: "global_stats_partial",
+ innodbStatsFile: "innodb_stats_empty",
+ tableIoWaitsFile: "table_io_waits_stats_empty",
+ indexIoWaitsFile: "index_io_waits_stats_empty",
}
actualMetrics, scrapeErr := scraper.scrape(context.Background())
@@ -88,8 +92,10 @@ func TestScrape(t *testing.T) {
var _ client = (*mockClient)(nil)
type mockClient struct {
- globalStatsFile string
- innodbStatsFile string
+ globalStatsFile string
+ innodbStatsFile string
+ tableIoWaitsFile string
+ indexIoWaitsFile string
}
func readFile(fname string) (map[string]string, error) {
@@ -120,6 +126,65 @@ func (c *mockClient) getInnodbStats() (map[string]string, error) {
return readFile(c.innodbStatsFile)
}
+func (c *mockClient) getTableIoWaitsStats() ([]TableIoWaitsStats, error) {
+ var stats []TableIoWaitsStats
+ file, err := os.Open(filepath.Join("testdata", "scraper", c.tableIoWaitsFile+".txt"))
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ var s TableIoWaitsStats
+ text := strings.Split(scanner.Text(), "\t")
+
+ s.schema = text[0]
+ s.name = text[1]
+ s.countDelete, _ = parseInt(text[2])
+ s.countFetch, _ = parseInt(text[3])
+ s.countInsert, _ = parseInt(text[4])
+ s.countUpdate, _ = parseInt(text[5])
+ s.timeDelete, _ = parseInt(text[6])
+ s.timeFetch, _ = parseInt(text[7])
+ s.timeInsert, _ = parseInt(text[8])
+ s.timeUpdate, _ = parseInt(text[9])
+
+ stats = append(stats, s)
+ }
+ return stats, nil
+}
+
+func (c *mockClient) getIndexIoWaitsStats() ([]IndexIoWaitsStats, error) {
+ var stats []IndexIoWaitsStats
+ file, err := os.Open(filepath.Join("testdata", "scraper", c.indexIoWaitsFile+".txt"))
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ var s IndexIoWaitsStats
+ text := strings.Split(scanner.Text(), "\t")
+
+ s.schema = text[0]
+ s.name = text[1]
+ s.index = text[2]
+ s.countDelete, _ = parseInt(text[3])
+ s.countFetch, _ = parseInt(text[4])
+ s.countInsert, _ = parseInt(text[5])
+ s.countUpdate, _ = parseInt(text[6])
+ s.timeDelete, _ = parseInt(text[7])
+ s.timeFetch, _ = parseInt(text[8])
+ s.timeInsert, _ = parseInt(text[9])
+ s.timeUpdate, _ = parseInt(text[10])
+
+ stats = append(stats, s)
+ }
+ return stats, nil
+}
+
func (c *mockClient) Close() error {
return nil
}
diff --git a/receiver/mysqlreceiver/testdata/integration/expected.5_7.json b/receiver/mysqlreceiver/testdata/integration/expected.5_7.json
index d3bfeb2a9674..2a54ddb586df 100644
--- a/receiver/mysqlreceiver/testdata/integration/expected.5_7.json
+++ b/receiver/mysqlreceiver/testdata/integration/expected.5_7.json
@@ -1044,6 +1044,498 @@
]
},
"unit": "1"
+ },
+ {
+ "description": "The total count of I/O wait events for a table.",
+ "name": "mysql.table.io.waits.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "1",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "2",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "3",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "4",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for a table.",
+ "name": "mysql.table.io.waits.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "5",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "6",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "7",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "8",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
+ },
+ {
+ "description": "The total count of I/O wait events for an index.",
+ "name": "mysql.index.io.waits.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "9",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "10",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "11",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "12",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for an index.",
+ "name": "mysql.index.io.waits.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "13",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "14",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "15",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "16",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
}
]
}
diff --git a/receiver/mysqlreceiver/testdata/integration/expected.8_0.json b/receiver/mysqlreceiver/testdata/integration/expected.8_0.json
index d3bfeb2a9674..2a54ddb586df 100644
--- a/receiver/mysqlreceiver/testdata/integration/expected.8_0.json
+++ b/receiver/mysqlreceiver/testdata/integration/expected.8_0.json
@@ -1044,6 +1044,498 @@
]
},
"unit": "1"
+ },
+ {
+ "description": "The total count of I/O wait events for a table.",
+ "name": "mysql.table.io.waits.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "1",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "2",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "3",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "4",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for a table.",
+ "name": "mysql.table.io.waits.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "5",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "6",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "7",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "8",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
+ },
+ {
+ "description": "The total count of I/O wait events for an index.",
+ "name": "mysql.index.io.waits.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "9",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "10",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "11",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "12",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for an index.",
+ "name": "mysql.index.io.waits.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "13",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "14",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "15",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "16",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
}
]
}
diff --git a/receiver/mysqlreceiver/testdata/integration/scripts/setup.sh b/receiver/mysqlreceiver/testdata/integration/scripts/setup.sh
index 0afe41c6d3d5..3632beeecd95 100644
--- a/receiver/mysqlreceiver/testdata/integration/scripts/setup.sh
+++ b/receiver/mysqlreceiver/testdata/integration/scripts/setup.sh
@@ -14,13 +14,27 @@ setup_permissions() {
mysql -u root -p"${ROOT_PASS}" -e "FLUSH PRIVILEGES" > /dev/null
}
+setup_data() {
+ mysql -u root -p"${ROOT_PASS}" -e "CREATE DATABASE a_schema" > /dev/null
+ mysql -u root -p"${ROOT_PASS}" -e "CREATE TABLE a_schema.a_table (k int, v int)" > /dev/null
+ mysql -u root -p"${ROOT_PASS}" -e "CREATE INDEX an_index ON a_schema.a_table ((k + v))" > /dev/null
+}
+
echo "Configuring ${USER} permissions. . ."
end=$((SECONDS+60))
while [ $SECONDS -lt $end ]; do
result="$?"
if setup_permissions; then
echo "Permissions configured!"
- exit 0
+ while [ $SECONDS -lt $end ]; do
+ result="$?"
+ if setup_data; then
+ echo "Data created!"
+ exit 0
+ fi
+ echo "Trying again in 5 seconds. . ."
+ sleep 5
+ done
fi
echo "Trying again in 5 seconds. . ."
sleep 5
diff --git a/receiver/mysqlreceiver/testdata/scraper/expected.json b/receiver/mysqlreceiver/testdata/scraper/expected.json
index a77203ea7f6b..74d262e04c72 100644
--- a/receiver/mysqlreceiver/testdata/scraper/expected.json
+++ b/receiver/mysqlreceiver/testdata/scraper/expected.json
@@ -1044,6 +1044,498 @@
]
},
"unit": "1"
+ },
+ {
+ "description": "The total count of I/O wait events for a table.",
+ "name": "mysql.table.io.wait.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "1",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "2",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "3",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "4",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for a table.",
+ "name": "mysql.table.io.wait.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "5",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "6",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "7",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "8",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
+ },
+ {
+ "description": "The total count of I/O wait events for an index.",
+ "name": "mysql.index.io.wait.count",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "9",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "10",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "11",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "12",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "1"
+ },
+ {
+ "description": "The total time of I/O wait events for an index.",
+ "name": "mysql.index.io.wait.time",
+ "sum": {
+ "aggregationTemporality": "AGGREGATION_TEMPORALITY_CUMULATIVE",
+ "isMonotonic": true,
+ "dataPoints": [
+ {
+ "asInt": "13",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "delete"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "14",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "fetch"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "15",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "insert"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ },
+ {
+ "asInt": "16",
+ "attributes": [
+ {
+ "key": "operation",
+ "value": {
+ "stringValue": "update"
+ }
+ },
+ {
+ "key": "table",
+ "value": {
+ "stringValue": "a_table"
+ }
+ },
+ {
+ "key": "schema",
+ "value": {
+ "stringValue": "a_schema"
+ }
+ },
+ {
+ "key": "index",
+ "value": {
+ "stringValue": "an_index"
+ }
+ }
+ ],
+ "startTimeUnixNano": "1644862687825728000",
+ "timeUnixNano": "1644862687825772000"
+ }
+ ]
+ },
+ "unit": "ns"
}
]
}
diff --git a/receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats.txt b/receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats.txt
new file mode 100644
index 000000000000..a9a654474d05
--- /dev/null
+++ b/receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats.txt
@@ -0,0 +1 @@
+a_schema a_table an_index 9 10 11 12 13000 14000 15000 16000
diff --git a/receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats_empty.txt b/receiver/mysqlreceiver/testdata/scraper/index_io_waits_stats_empty.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats.txt b/receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats.txt
new file mode 100644
index 000000000000..4cd424c899e1
--- /dev/null
+++ b/receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats.txt
@@ -0,0 +1 @@
+a_schema a_table 1 2 3 4 5000 6000 7000 8000
diff --git a/receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats_empty.txt b/receiver/mysqlreceiver/testdata/scraper/table_io_waits_stats_empty.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/unreleased/mysql-receiver-add-perf-io-waits.yaml b/unreleased/mysql-receiver-add-perf-io-waits.yaml
new file mode 100644
index 000000000000..c383db7df73e
--- /dev/null
+++ b/unreleased/mysql-receiver-add-perf-io-waits.yaml
@@ -0,0 +1,5 @@
+change_type: enhancement
+component: mysqlreceiver
+note: The receiver now scraper 16 new metrics related to io_waits.
+issues: [14138]
+subtext: