vitessio/vitess · error

failed to check innodb_adaptive_hash_index setting: unexpect

Error message

failed to check innodb_adaptive_hash_index setting: unexpected result

What it means

tablegc's adjustLifecycleForFastDrops queries performance_schema.global_variables for innodb_adaptive_hash_index to decide whether fast DROP TABLE can be used. When the query succeeds but returns no rows/columns, it cannot determine the AHI state and fails with this error rather than guessing and potentially skipping PURGE/EVAC unsafely.

Source

Thrown at go/vt/vttablet/tabletserver/gc/tablegc.go:243

		return lifecycleStates, nil
	}

	serverSupportsFastDrops, err := conn.SupportsCapability(capabilities.FastDropTableFlavorCapability)
	if err != nil {
		return lifecycleStates, err
	}
	if !serverSupportsFastDrops {
		return lifecycleStates, nil
	}

	// Unfortunately you can still encounter problems if the Adaptive Hash Indexes are enabled: https://bugs.mysql.com/bug.php?id=113312
	// So if AHI is enabled, we cannot safely skip PURGE and EVAC even on MySQL versions that support fast DROP TABLE.
	res, err := conn.ExecuteFetch("SELECT variable_value FROM performance_schema.global_variables WHERE variable_name = 'innodb_adaptive_hash_index'", 1, false)
	if err != nil {
		return nil, vterrors.Wrap(err, "failed to check innodb_adaptive_hash_index setting")
	}
	if res == nil || len(res.Rows) == 0 || len(res.Rows[0]) == 0 {
		return nil, errors.New("failed to check innodb_adaptive_hash_index setting: unexpected result")
	}
	if strings.ToLower(res.Rows[0][0].ToString()) == "on" {
		return lifecycleStates, nil
	}

	updated := make(map[schema.TableGCState]bool, len(lifecycleStates))
	maps.Copy(updated, lifecycleStates)
	delete(updated, schema.PurgeTableGCState)
	delete(updated, schema.EvacTableGCState)
	return updated, nil
}

// Close frees resources
func (collector *TableGC) Close() {
	log.Info("TableGC - started execution of Close. Acquiring initMutex lock")
	collector.stateMutex.Lock()
	defer collector.stateMutex.Unlock()
	log.Info("TableGC - acquired lock")

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Enable performance_schema on the target mysqld (remove performance_schema=OFF) and restart mysqld
  2. Grant the vttablet MySQL user SELECT on performance_schema.global_variables
  3. If the MySQL flavor/version lacks innodb_adaptive_hash_index, upgrade to a supported version or let tablegc fall back by ensuring the variable is present

Example fix

// before (my.cnf)
[mysqld]
performance_schema=OFF
// after
[mysqld]
performance_schema=ON
Defensive patterns

Strategy: validation

Validate before calling

// Verify performance_schema exposes the variable before enabling tablegc fast drops
qr, err := conn.ExecuteFetch("SELECT variable_value FROM performance_schema.global_variables WHERE variable_name = 'innodb_adaptive_hash_index'", 1, false)
if err != nil || len(qr.Rows) == 0 {
    return fmt.Errorf("performance_schema disabled or variable unavailable")
}

Try / catch

if err := gc.Open(ctx); err != nil {
    if strings.Contains(err.Error(), "innodb_adaptive_hash_index") {
        // enable performance_schema / fix grants, then reopen
        return fmt.Errorf("fix mysqld config (performance_schema=ON, grants) and retry")
    }
    return err
}

Prevention

When it happens

Trigger: SELECT variable_value FROM performance_schema.global_variables WHERE variable_name='innodb_adaptive_hash_index' returns nil result, zero rows, or a zero-column row — e.g. performance_schema disabled or the variable absent.

Common situations: performance_schema disabled in target mysqld config (performance_schema=OFF); MySQL versions where the variable doesn't exist in global_variables; hardened MySQL setups restricting performance_schema access for the vttablet user.

Related errors


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