# RestoreOverride: Component Image Tags and TiKV Additional IOPS

**Date:** 2026-06-28
**Status:** Approved
**Branch:** `feat/restore-dedicated-with-more-params` in `tidb-management-service`

---

## Objective

Extend the existing `RestoreOverride` configuration to support:
1. Per-component image tag overrides (TiDB, TiKV, PD, TiFlash, TiProxy)
2. TiKV DATA disk additional IOPS setting

These overrides are applied when constructing the `RestoreDedicatedClusterRequest` sent to `tidb-management-service`.

---

## Background

The `tidb-management-service` branch `feat/restore-dedicated-with-more-params` adds two new fields to `RestoreDedicatedClusterRequest`:

1. `ClusterConfiguration cluster_configuration` - for per-component image tag overrides
2. `int32 additional_iops` in `StorageComp` - for TiKV DATA disk IOPS customization (Final IOPS = SKU base IOPS + additional_iops)

The `dataflow-service` needs to support configuring these fields via the existing `RestoreOverride` config structure.

---

## Design

### 1. Config Structure Changes

**File: `internal/config/config.go`**

Add the following fields to `RestoreOverride`:

```go
type RestoreOverride struct {
    Gate FeatureGate `mapstructure:"gate"`

    // Existing fields
    CompactionAcceleratedPiTR bool   `mapstructure:"compactionAcceleratedPiTR" default:"false"`
    AllowConcurrentPiTR       bool   `mapstructure:"allowConcurrentPiTR" default:"false"`
    BRImageTag                string `mapstructure:"brImageTag"`

    // New fields for component image tags
    // Valid keys: "tidb", "tikv", "pd", "tiflash", "tiproxy"
    ComponentImageTags map[string]string `mapstructure:"componentImageTags"`

    // New field for TiKV DATA disk additional IOPS
    // Final IOPS = SKU base IOPS + tikvDataAdditionalIops
    TiKVDataAdditionalIops int32 `mapstructure:"tikvDataAdditionalIops"`

    // UseSameImageTags copies image tags from the source cluster for the specified components.
    // Valid items: "tidb", "tikv", "pd", "tiflash", "tiproxy"
    // Priority: ComponentImageTags > UseSameImageTags
    // Example: ["tidb", "tikv"] - use the same image tags as the source cluster for TiDB and TiKV
    UseSameImageTags []string `mapstructure:"useSameImageTags"`

    // UseSameAdditionalIops copies additional IOPS from the source cluster for the specified components.
    // Valid items: "tikv", "tiflash" (only storage components have additional IOPS)
    // Priority: TiKVDataAdditionalIops > UseSameAdditionalIops for TiKV
    // Example: ["tikv"] - use the same additional IOPS as the source cluster for TiKV
    UseSameAdditionalIops []string `mapstructure:"useSameAdditionalIops"`
}
```

### 2. Usage Flow

When building `RestoreDedicatedClusterRequest`:

1. **Match the override**: Call `RestoreOverrides.GetMatched()` with tenant/project/cluster ID and cloud provider/region
2. **Apply component image tags**: If `ComponentImageTags` is not empty, populate `ClusterConfiguration` in the request
3. **Apply TiKV additional IOPS**: If `TiKVDataAdditionalIops > 0`, set `AdditionalIops` field in `TikvComp`

### 3. Integration Point

Apply overrides in `buildCreateClusterReqFor3LayerArch()` or the param builder when constructing `RestoreDedicatedClusterRequest`:

```go
if override, ok := config.Global().BackupConfig.RestoreOverrides.GetMatched(
    tenantID, projectID, clusterID, cloudProvider, region,
); ok {
    // Apply component image tags
    if len(override.ComponentImageTags) > 0 {
        createClusterReq.ClusterConfiguration = buildClusterConfiguration(override.ComponentImageTags)
    }

    // Apply TiKV additional IOPS
    if override.TiKVDataAdditionalIops > 0 {
        createClusterReq.TikvComp.AdditionalIops = override.TiKVDataAdditionalIops
    }
}
```

### 4. Example Configuration

```yaml
backup:
  restoreOverrides:
    - gate:
        all: true
      componentImageTags:
        tidb: "v8.5.0-custom"
        tikv: "v8.5.0-custom"
        pd: "v8.5.0-custom"
      tikvDataAdditionalIops: 1000
      useSameImageTags:
        - "tiflash"
        - "tiproxy"
      useSameAdditionalIops:
        - "tikv"
```

---

## Risks and Considerations

1. **API Compatibility**: The `tidb-management-service` branch must be merged before deploying this change
2. **Validation**: Consider validating that component keys are valid ("tidb", "tikv", "pd", "tiflash", "tiproxy")
3. **Default Values**: Zero value for IOPS field means "no override" (consistent with existing behavior)
4. **Backward Compatibility**: New fields are optional; existing configurations continue to work unchanged
