vitessio/vitess · error

unexpected number of rows received - %v

Error message

unexpected number of rows received - %v

What it means

IsSemiSyncBlocked reads a semi-sync status variable via a super query and expects exactly one row with one column. A result of any other shape yields this error because the blocked status cannot be determined.

Source

Thrown at go/vt/mysqlctl/replication.go:1362

		return false, err
	}
	defer conn.Recycle()

	// Execute the query to check if the primary is blocked on semi-sync.
	semiSyncWaitSessionsRead := "select variable_value from performance_schema.global_status where regexp_like(variable_name, 'Rpl_semi_sync_(source|master)_wait_sessions')"
	res, err := conn.Conn.ExecuteFetch(semiSyncWaitSessionsRead, 1, false)
	if err != nil {
		return false, err
	}
	// If we have no rows, then the primary doesn't have semi-sync enabled.
	// It then follows, that the primary isn't blocked :)
	if len(res.Rows) == 0 {
		return false, nil
	}

	// Read the status value and check if it is non-zero.
	if len(res.Rows) != 1 || len(res.Rows[0]) != 1 {
		return false, fmt.Errorf("unexpected number of rows received - %v", res.Rows)
	}
	value, err := res.Rows[0][0].ToCastInt64()
	return value != 0, err
}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Run the underlying SHOW STATUS query manually and confirm it returns exactly one row/column for the semi-sync blocked variable
  2. Ensure only one semi-sync status variable matches the query pattern on this server flavor
  3. Bypass proxies that reshape SHOW STATUS results
  4. Upgrade/downgrade mysqlctl to match the server flavor in use

Example fix

// before: wildcard pattern matching multiple rows
// after: query the exact variable name
query := "SHOW STATUS LIKE 'Rpl_semi_sync_master_status'"
Defensive patterns

Strategy: type-guard

Validate before calling

res, err := mysqld.FetchSuperQuery(ctx, "SHOW STATUS LIKE 'Rpl_semi_sync_master_status'")
if err == nil && (len(res.Rows) != 1 || len(res.Rows[0]) != 1) {
    log.Warn("unexpected semi-sync status shape")
}

Type guard

func validSingleValueRow(res *sqltypes.Result) bool {
    return res != nil && len(res.Rows) == 1 && len(res.Rows[0]) == 1
}

Try / catch

blocked, err := mysqld.IsSemiSyncBlocked(ctx)
if err != nil && strings.Contains(err.Error(), "unexpected number of rows") {
    log.Warn("semi-sync status unreadable; assuming not blocked")
    blocked = false
}

Prevention

When it happens

Trigger: Calling mysqld.IsSemiSyncBlocked when the SHOW STATUS query returns more than one row or the single row has multiple columns — usually due to a wildcard pattern matching several variables or an incompatible server/proxy response.

Common situations: MariaDB vs MySQL naming differences causing multiple matching status variables; proxied connections that alter SHOW STATUS shape; plugin loaded under names that create multiple rows.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/43b96e7ea4279daf. Report an issue: GitHub.