vitessio/vitess · error

partial row image encountered: ensure binlog_row_image is se

Error message

partial row image encountered: ensure binlog_row_image is set to 'full'

What it means

A binlog row event arrived with a partial row image (some columns missing from the BINLOG row), which vstreamer cannot decode into full row values unless the experimental no-blob row image flag is enabled. MySQL's binlog_row_image=MINIMAL emits only changed/PK columns, leaving getValues unable to reconstruct the complete row. The error tells the operator to switch the source to binlog_row_image=FULL.

Source

Thrown at go/vt/vttablet/tabletserver/vstreamer/vstreamer.go:1334

	return nil
}

func (vs *vstreamer) getValues(plan *streamerPlan, data []byte,
	dataColumns, nullColumns mysql.Bitmap, jsonPartialValues mysql.Bitmap,
) ([]sqltypes.Value, []collations.ID, bool, error) {
	if len(data) == 0 {
		return nil, nil, false, nil
	}
	values := make([]sqltypes.Value, dataColumns.Count())
	charsets := make([]collations.ID, len(values))
	valueIndex := 0
	jsonIndex := 0
	pos := 0
	partial := false
	for colNum := 0; colNum < dataColumns.Count(); colNum++ {
		if !dataColumns.Bit(colNum) {
			if vs.config.ExperimentalFlags /**/ & /**/ vttablet.VReplicationExperimentalFlagAllowNoBlobBinlogRowImage == 0 {
				return nil, nil, false, errors.New("partial row image encountered: ensure binlog_row_image is set to 'full'")
			} else {
				partial = true
			}
			continue
		}
		if nullColumns.Bit(valueIndex) {
			valueIndex++
			if plan.Table.Fields[colNum].Type == querypb.Type_JSON {
				jsonIndex++
			}
			continue
		}
		partialJSON := false
		if jsonPartialValues.Count() > 0 && plan.Table.Fields[colNum].Type == querypb.Type_JSON {
			partialJSON = jsonPartialValues.Bit(jsonIndex)
			jsonIndex++
		}
		value, l, err := mysqlbinlog.CellValue(data, pos, plan.TableMap.Types[colNum], plan.TableMap.Metadata[colNum], plan.Table.Fields[colNum], partialJSON)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Set binlog_row_image=FULL on the source MySQL and restart the stream (SET GLOBAL binlog_row_image='FULL' then RESET/refresh the workflow)
  2. Enable the experimental flag VReplicationExperimentalFlagAllowNoBlobBinlogRowImage on vttablet if partial images are acceptable
  3. Verify with SELECT @@binlog_row_image on the source before starting vreplication workflows

Example fix

-- before
SHOW VARIABLES LIKE 'binlog_row_image'; -- MINIMAL
-- after
SET GLOBAL binlog_row_image = 'FULL';
-- then restart the workflow
vtctldclient Workflow --keyspace ks moveTables --workflow mt1 start
Defensive patterns

Strategy: validation

Validate before calling

-- run before starting any vreplication workflow against this source
SHOW VARIABLES LIKE 'binlog_row_image'; -- must be FULL

Try / catch

if _, _, _, err := vs.getValues(...); err != nil {
	if strings.Contains(err.Error(), "partial row image") {
		// alert operator to set binlog_row_image=FULL on the source
	}
	return err
}

Prevention

When it happens

Trigger: Source MySQL is configured with binlog_row_image=MINIMAL or NOBLOB while a VReplication stream processes row events on tables where not all columns are present in the binlog, and VReplicationExperimentalFlagAllowNoBlobBinlogRowImage is not set in vttablet.

Common situations: Operators minimizing binlog disk usage on the source; replication setups inherited from non-Vitess tooling with MINIMAL row image defaults; moving tables whose blobs were trimmed from the row image.

Related errors


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