vitessio/vitess · error

empty create database statement for %v

Error message

empty create database statement for %v

What it means

GetSchema runs `SHOW CREATE DATABASE` to capture the database creation statement. If MySQL returns no rows for that statement (no create command available), this error is thrown and schema export aborts.

Source

Thrown at go/vt/mysqlctl/schema.go:96

		encodedTables[i] = sqltypes.EncodeStringSQL(tableName)
	}

	return "(" + strings.Join(encodedTables, ", ") + ")", nil
}

// GetSchema returns the schema for database for tables listed in
// tables. If tables is empty, return the schema for all tables.
func (mysqld *Mysqld) GetSchema(ctx context.Context, dbName string, request *tabletmanagerdatapb.GetSchemaRequest) (*tabletmanagerdatapb.SchemaDefinition, error) {
	sd := &tabletmanagerdatapb.SchemaDefinition{}
	backtickDBName := sqlescape.EscapeID(dbName)

	// get the database creation command
	qr, fetchErr := mysqld.FetchSuperQuery(ctx, "SHOW CREATE DATABASE IF NOT EXISTS "+backtickDBName)
	if fetchErr != nil {
		return nil, fetchErr
	}
	if len(qr.Rows) == 0 {
		return nil, fmt.Errorf("empty create database statement for %v", dbName)
	}
	sd.DatabaseSchema = strings.Replace(qr.Rows[0][1].ToString(), backtickDBName, "{{.DatabaseName}}", 1)

	tds, err := mysqld.collectBasicTableData(ctx, dbName, request.Tables, request.ExcludeTables, request.IncludeViews)
	if err != nil {
		return nil, err
	}

	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	allErrors := &concurrency.AllErrorRecorder{}

	eg, ctx := errgroup.WithContext(ctx)
	eg.SetLimit(getSchemaConcurrency)

	// Get per-table schema concurrently.
	tableNames := make([]string, 0, len(tds))

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Verify the database exists: run `SHOW CREATE DATABASE <name>` manually with the exact name
  2. Confirm the keyspace/db name spelling and case matches what MySQL knows
  3. Re-fetch after any concurrent DROP/CREATE migration finishes
  4. Check the MySQL variant/proxy implements SHOW CREATE DATABASE with rows

Example fix

// before: GetSchema(ctx, "VtData", ...) for a dropped db
// after: ensure db exists first
// CREATE DATABASE IF NOT EXISTS `VtData`; then retry GetSchema
Defensive patterns

Strategy: try-catch

Validate before calling

qr, err := mysqld.FetchSuperQuery(ctx, "SHOW DATABASES LIKE '"+dbName+"'")
if err == nil && len(qr.Rows) == 0 {
    return fmt.Errorf("database %s does not exist", dbName)
}

Try / catch

sd, err := mysqld.GetSchema(ctx, dbName, nil, nil, false)
if err != nil && strings.Contains(err.Error(), "empty create database statement") {
    log.Warn("database missing or unreportable; recreating before retry", slog.String("db", dbName))
    return retryAfterCreateDatabase(dbName)
}

Prevention

When it happens

Trigger: Calling mysqld.GetSchema for a database where SHOW CREATE DATABASE returns zero rows — e.g. the database was dropped concurrently, an unusual empty/nonexistent db name, or a server not returning the create statement.

Common situations: Race between database drop and schema fetch; querying a db name with case/charset mismatch so MySQL resolves nothing; against proxies that don't implement SHOW CREATE DATABASE rows properly.

Related errors


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