Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix mysql_slave_hosts_info for mysql 5.5 and mariadb 10.5, add unit test #577

Merged
merged 1 commit into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions collector/slave_hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,42 @@ func (ScrapeSlaveHosts) Scrape(ctx context.Context, db *sql.DB, ch chan<- promet
var masterId string
var slaveUuid string

columnNames, err := slaveHostsRows.Columns()
if err != nil {
return err
}

for slaveHostsRows.Next() {
// Newer versions of mysql have the following
// Server_id, Host, Port, Master_id, Slave_UUID
// Older versions of mysql have the following
// Server_id, Host, Port, Rpl_recovery_rank, Master_id
err := slaveHostsRows.Scan(&serverId, &host, &port, &rrrOrMasterId, &slaveUuidOrMasterId)
// MySQL 5.5 and MariaDB 10.5 have the following
// Server_id, Host, Port, Master_id
if len(columnNames) == 5 {
err = slaveHostsRows.Scan(&serverId, &host, &port, &rrrOrMasterId, &slaveUuidOrMasterId)
} else {
err = slaveHostsRows.Scan(&serverId, &host, &port, &rrrOrMasterId)
}
if err != nil {
return err
}

// Check to see if slaveUuidOrMasterId resembles a UUID or not
// to find out if we are using an old version of MySQL
if _, err = uuid.FromString(slaveUuidOrMasterId); err != nil {
// We are running an older version of MySQL with no slave UUID
slaveUuid = ""
masterId = slaveUuidOrMasterId
// if a Slave_UUID or Rpl_recovery_rank field is present
if len(columnNames) == 5 {
// Check to see if slaveUuidOrMasterId resembles a UUID or not
// to find out if we are using an old version of MySQL
if _, err = uuid.FromString(slaveUuidOrMasterId); err != nil {
// We are running an older version of MySQL with no slave UUID
slaveUuid = ""
masterId = slaveUuidOrMasterId
} else {
// We are running a more recent version of MySQL
slaveUuid = slaveUuidOrMasterId
masterId = rrrOrMasterId
}
} else {
// We are running a more recent version of MySQL
slaveUuid = slaveUuidOrMasterId
slaveUuid = ""
masterId = rrrOrMasterId
}

Expand Down
38 changes: 38 additions & 0 deletions collector/slave_hosts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,41 @@ func TestScrapeSlaveHostsNewFormat(t *testing.T) {
t.Errorf("there were unfulfilled exceptions: %s", err)
}
}

func TestScrapeSlaveHostsWithoutSlaveUuid(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("error opening a stub database connection: %s", err)
}
defer db.Close()

columns := []string{"Server_id", "Host", "Port", "Master_id"}
rows := sqlmock.NewRows(columns).
AddRow("192168010", "iconnect2", "3306", "192168012").
AddRow("1921680101", "athena", "3306", "192168012")
mock.ExpectQuery(sanitizeQuery("SHOW SLAVE HOSTS")).WillReturnRows(rows)

ch := make(chan prometheus.Metric)
go func() {
if err = (ScrapeSlaveHosts{}).Scrape(context.Background(), db, ch, log.NewNopLogger()); err != nil {
t.Errorf("error calling function on test: %s", err)
}
close(ch)
}()

counterExpected := []MetricResult{
{labels: labelMap{"server_id": "192168010", "slave_host": "iconnect2", "port": "3306", "master_id": "192168012", "slave_uuid": ""}, value: 1, metricType: dto.MetricType_GAUGE},
{labels: labelMap{"server_id": "1921680101", "slave_host": "athena", "port": "3306", "master_id": "192168012", "slave_uuid": ""}, value: 1, metricType: dto.MetricType_GAUGE},
}
convey.Convey("Metrics comparison", t, func() {
for _, expect := range counterExpected {
got := readMetric(<-ch)
convey.So(got, convey.ShouldResemble, expect)
}
})

// Ensure all SQL queries were executed
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled exceptions: %s", err)
}
}