vitessio/vitess · error

--batch-size requires 'direct' ddl_strategy

Error message

--batch-size requires 'direct' ddl_strategy

What it means

schemamanager's batch mode (--batch-size > 1) groups multiple SQL statements into one query per batch, which is only safe with the 'direct' DDL strategy that sends raw SQL to tablets. Non-direct strategies (e.g. gh-ost, pt-Online-Schema-Change) migrate one table per migration and cannot accept batched multi-statement SQL, so Execute rejects the combination up front.

Source

Thrown at go/vt/schemamanager/tablet_executor.go:467

					reloadCtx,
					exec.ts,
					exec.tmc,
					exec.logger,
					exec.keyspace,
					result.Shard,
					result.Position,
					concurrency,
					true, /* includePrimary */
				)
			}(result)
		}
		wg.Wait()
	}()

	if exec.batchSize > 1 {
		// Before we proceed to batch, we need to validate there's no conflicts.
		if !exec.isDirectStrategy() {
			return errorExecResult(errors.New("--batch-size requires 'direct' ddl_strategy"))
		}
		if exec.hasProvidedUUIDs() {
			return errorExecResult(errors.New("--batch-size conflicts with --uuid-list. Batching does not support UUIDs."))
		}
		allSQLsAreCreate, err := allSQLsAreCreateQueries(sqls, exec.parser)
		if err != nil {
			return errorExecResult(err)
		}
		if !allSQLsAreCreate {
			return errorExecResult(errors.New("--batch-size only allowed when all queries are CREATE TABLE|VIEW"))
		}

		sqls = batchSQLs(sqls, int(exec.batchSize))
	}
	for index, sql := range sqls {
		// Attempt to renew lease:
		if err := rl.Do(func() error { return topo.CheckKeyspaceLocked(ctx, exec.keyspace) }); err != nil {
			return errorExecResult(vterrors.Wrapf(err, "CheckKeyspaceLocked in ApplySchemaKeyspace %v", exec.keyspace))

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass ddl_strategy=direct (e.g. --ddl-strategy direct) when using --batch-size
  2. Remove --batch-size so each statement runs as its own migration
  3. Split the DDL into CREATE-only statements and keep strategy direct if batching CREATE TABLEs

Example fix

// before
vtctldclient ApplySchema --sql-file d.sql --batch-size 10 --ddl-strategy "gh-ost" ks
// after
vtctldclient ApplySchema --sql-file d.sql --batch-size 10 --ddl-strategy "direct" ks
Defensive patterns

Strategy: validation

Validate before calling

if batchSize > 1 && !strings.Contains(ddlStrategy, "direct") {
    return fmt.Errorf("--batch-size requires 'direct' ddl_strategy, got %q", ddlStrategy)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "--batch-size requires 'direct'") {
    // fall back: drop batch-size or switch strategy to direct
}

Prevention

When it happens

Trigger: Running Execute (or ApplySchema) with --batch-size set greater than 1 while ddl_strategy is anything other than 'direct'.

Common situations: Operators combining --batch-size with gh-ost/pt-osc strategy in vtctld ApplySchema invocations; scripts that set a default batch size without pinning the strategy.

Related errors


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