Metadata-Version: 2.4
Name: tidbchange
Version: 1.0.1
Summary: TiDB schema migration and governance tool — part of Schemashifts
Author: Schemashifts
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Database
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: pymysql>=1.1.0
Requires-Dist: pyyaml>=6.0
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# tidbchange

**TiDB schema migration and governance tool** — part of the [Schemashifts](https://schemashifts.io) platform.

> Other migration tools treat TiDB as MySQL. They handle CREATE TABLE and ALTER TABLE just fine. But the features that make TiDB worth adopting — TiFlash columnar replicas, placement policies, resource groups, HTAP workload isolation — are completely outside what either tool can express or track.

tidbchange fills that gap.

## What tidbchange does that other tools cannot

| Feature | Other tools | tidbchange |
|---|---|---|
| TiFlash replica management | Raw SQL only, no async monitoring | Full lifecycle with replication progress polling |
| TiFlash backfill wait | Fires DDL and moves on — AVAILABLE=0 silently | Polls `INFORMATION_SCHEMA.TIFLASH_REPLICA` until PROGRESS=1.0 |
| Placement policies | Not expressible | Full create/attach/detach/drop lifecycle in YAML |
| Resource groups | Not expressible | Full create/alter/drop + priority/burstable in YAML |
| Drift detection | Schema only | Tables + TiFlash replicas + placement policies + resource groups |
| HTAP governance | None | 12 analyser rules + policy-as-code contracts |
| Baseline generation | Basic DDL | Full cluster state including TiDB-native features |

## Quick start

```bash
pip install tidbchange        # or: pip install -e .
tidbchange deploy --profile local
```

## tidbchange.yml

```yaml
default_profile: local

profiles:
  local:
    host:     127.0.0.1
    port:     4000            # TiDB default port
    user:     root
    password: ""
    database: ecommerce
    root_folder: ./migrations
    tiflash_timeout: 120

  dev:
    host:     ${TIDB_DEV_HOST}
    port:     4000
    user:     tidbchange
    password: ${TIDB_DEV_PASSWORD}
    database: ecommerce
    ssl:      true
    tiflash_timeout: 1800
    environment: dev
```

## Migration script formats

### SQL (`.sql`) — standard MySQL-compatible DDL

```sql
-- V1.0.0__create_users.sql
CREATE TABLE `users` (
    `id`    BIGINT NOT NULL AUTO_RANDOM,  -- AUTO_RANDOM avoids hot spots
    `email` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_email` (`email`)
) ENGINE=InnoDB;
```

### YAML (`.yaml`) — TiDB-native features

```yaml
# V1.2.0__add_tiflash_replicas.yaml
tiflash_replicas:
  - table: order_analytics
    replicas: 1
  - table: orders
    replicas: 1

# V1.3.0__resource_groups.yaml
resource_groups:
  - name: analytics_rg
    ru_per_sec: 5000
    priority: LOW
    burstable: false

# V1.4.0__placement.yaml
placement_policies:
  - name: eu_policy
    primary_region: eu-west-1
    regions: [eu-west-1, eu-central-1]
    schedule: EVEN

attach_placement:
  - table: users
    policy: eu_policy
```

## Commands

```bash
tidbchange deploy   --profile local               # apply all pending migrations
tidbchange deploy   --profile local --target-version 1.2.0  # deploy up to V1.2.0
tidbchange rollback --profile local --tag release-2.0       # undo a tagged release
tidbchange status   --profile local               # show migration history
tidbchange validate                               # lint scripts offline (no connection)
tidbchange baseline --profile local               # generate V0.0.0 from live cluster
tidbchange audit    --profile local               # compliance audit log
```

## TiFlash backfill monitoring

The key feature of tidbchange over other tools for TiDB:

```
[INFO] SET TiFlash REPLICA 1  on  order_analytics
[INFO] Waiting for TiFlash replicas on 'ecommerce.order_analytics' to be AVAILABLE (timeout=1800s)...
[INFO] TiFlash replication progress: 0.0%  (elapsed 0s)
[INFO] ⏳ TiFlash replication 23.4%  (elapsed 30s, timeout in 1770s)
[INFO] ⏳ TiFlash replication 61.8%  (elapsed 60s, timeout in 1740s)
[INFO] TiFlash replication progress: 100.0%  (elapsed 82s)
[INFO] ✓ TiFlash replicas AVAILABLE for 'ecommerce.order_analytics'  (took 82s)
```

Other tools fire `ALTER TABLE SET TIFLASH REPLICA 1` and immediately moves to the next script. The replica is left in `AVAILABLE=0` state, and any OLAP queries silently fall back to TiKV rowstore. tidbchange waits until `AVAILABLE=1` and `PROGRESS=1.0` before proceeding.

## Requirements

- Python 3.9+
- TiDB 5.0+ (for TiFlash) or TiDB 6.0+ (for placement policies and resource groups)
- TiDB Cloud or self-hosted TiDB

## License

Apache 2.0
