|
| 1 | +--- |
| 2 | +title: Multi Tenant Migrations |
| 3 | +description: Importing multiple tenant databases into a single Vitess cluster |
| 4 | +weight: 120 |
| 5 | +aliases: [ '/docs/reference/vreplication/v2/multitenant-migrations/' ] |
| 6 | +--- |
| 7 | + |
| 8 | +## Description |
| 9 | + |
| 10 | +{{< warning >}} |
| 11 | +This feature is an **experimental** variant of |
| 12 | +the [`MoveTables`](../../../reference/programs/vtctldclient/vtctldclient_movetables/) command that |
| 13 | +allows you to migrate from a multi-tenant architecture, with one database per tenant, into a single Vitess cluster. |
| 14 | +Please be sure to understand the limitations and requirements below. |
| 15 | +{{< /warning >}} |
| 16 | + |
| 17 | +The full set of options for the `MoveTables` |
| 18 | +command [can be found here](../../../reference/programs/vtctldclient/vtctldclient_movetables/). |
| 19 | +The options and other aspects specific to multi-tenant migrations will be covered here. |
| 20 | + |
| 21 | +## Use Case |
| 22 | + |
| 23 | +The user has a multi-tenant database architecture. They have several separate MySQL databases, with common schemas, |
| 24 | +one per tenant. This design has several disadvantages, including the need to manage multiple databases, needing to |
| 25 | +update the schema on all databases before the app can start using the new schema, inability to run cross-tenant |
| 26 | +queries, etc. |
| 27 | + |
| 28 | +This system maps well to a sharded Vitess cluster, providing a single logical database where tenants are mapped to |
| 29 | +specific shards. |
| 30 | + |
| 31 | +## Assumptions |
| 32 | + |
| 33 | +- The target keyspace has its schema already initialized. |
| 34 | +- Each table in the target keyspace has a tenant id column with the same name and type on both source and target, and it |
| 35 | + should be part of the primary key of each table. |
| 36 | +- If the target keyspace is sharded, the vindex should be a multicolumn vindex with the tenant id column |
| 37 | + as the first column. |
| 38 | + |
| 39 | +## Design |
| 40 | + |
| 41 | +### VSchema |
| 42 | +A new vschema object is required which defines the column name which defines the tenant id. The actual tenant id is |
| 43 | +specified for each migration. It should be added at the root level (like `tables`, `vindexes`) |
| 44 | +``` |
| 45 | +"multi_tenant_spec": { |
| 46 | +"tenant_id_column_name": "app_id", |
| 47 | +"tenant_id_column_type": "INT64" |
| 48 | +} |
| 49 | +``` |
| 50 | + |
| 51 | + |
| 52 | +## Key Parameter |
| 53 | + |
| 54 | +#### --source-shards |
| 55 | + |
| 56 | +**mandatory** (for shard level migrations) |
| 57 | +<div class="cmd"> |
| 58 | + |
| 59 | +A list of one or more shards that you want to migrate from the source keyspace |
| 60 | +to the target keyspace. |
| 61 | + |
| 62 | +</div> |
| 63 | + |
| 64 | +## Sample Flow |
| 65 | + |
| 66 | +### Create unmanaged keyspace |
| 67 | + |
| 68 | +Create a source keyspace, say `import_1234` with unmanaged tablets pointing to one tenant's database, whose tenant |
| 69 | +id is 1234. (https://vitess.io/docs/user-guides/configuration-advanced/unmanaged-tablet/) |
| 70 | + |
| 71 | + |
| 72 | +### Create MoveTables Workflow |
| 73 | + |
| 74 | +`MoveTables --workflow=wf_1234 --target-keyspace=vitess_sharded Create --source-keyspace=import_1234 --all-tables --tenant-id=1234` |
| 75 | + |
| 76 | +Like other vreplication workflows, once this workflow starts, it will first run the Copy phase. Once it is in the |
| 77 | +Running phase with a low VReplication lag, ideally a second or so, you can switch traffic. |
| 78 | + |
| 79 | +### Monitor Workflow |
| 80 | + |
| 81 | +`Workflow --keyspace=vitess_sharded Show –workflow=wf_1234 --include-logs=false` |
| 82 | + |
| 83 | +### Switch Traffic |
| 84 | + |
| 85 | +`MoveTables --workflow=wf_1234 --target-keyspace=vitess_sharded SwitchTraffic` |
| 86 | + |
| 87 | +### Complete Workflow |
| 88 | + |
| 89 | +`MoveTables --workflow=wf_1234 --target-keyspace=vitess_sharded Complete` |
| 90 | + |
| 91 | +### Migrate all tenants |
| 92 | + |
| 93 | +Multiple tenants can be migrated concurrently. Note that previously migrated tenants will be pointing to the Vitess |
| 94 | +cluster for their production load. So you may want to limit the concurrency so that the imports are not impacting |
| 95 | +live performance. |
| 96 | + |
| 97 | +When all tenants have been imported the migration will be complete and once you are satisfied with the behaviour of |
| 98 | +the Vitess cluster, you can turn off your existing database setup. |
| 99 | + |
| 100 | +Note that, as tenants get migrated, you will have some tenants served by Vitess and others by the existing database |
| 101 | +cluster. A mechanism will be needed for the app to cutover the migrated tenant by pointing the database connection |
| 102 | +to the Vitess cluster. |
| 103 | + |
| 104 | +## Reverse Replication |
| 105 | + |
| 106 | +While reverse replication will run after SwitchTraffic, we cannot run a ReverseTraffic for multi-tenant migrations. |
| 107 | +This is because we cannot stop writes on the target, which will have live traffic for several other tenants. |
| 108 | +Currently, for reversing we will need to perform, several manual reverse steps: |
| 109 | +* manually switch the routing in the app to point to the existing database for the tenant |
| 110 | +* delete the data from the target for that tenant manually |
| 111 | +* drop the external keyspace |
| 112 | +* delete related keyspace routing rules (https://vitess.io/docs/20.0/reference/programs/vtctldclient/vtctldclient_applykeyspaceroutingrules/) |
| 113 | +* delete the vreplication workflow |
| 114 | + |
| 115 | + |
| 116 | +## Optimizations |
| 117 | +The `MoveTables` and `Workflow` commands now take an additional --shards parameter. This ensures that these commands |
| 118 | +only communicate with the primary of that shard instead of all shards. It is strongly recommended to provide this |
| 119 | +while working with large number of shards (say 32 and above), while working with multi-tenant migrations. |
| 120 | + |
| 121 | +Usually a tenant will be mapped to very few shards, (probably one for smaller tenants). If `--shards` is not specified |
| 122 | +then these commands will unnecessarily contact the remaining shards. For larger number of shards this can take |
| 123 | +several seconds and indeed `SwitchTraffic` might end up timing out. |
| 124 | + |
| 125 | +Note that an incorrect shard naming can result in an incorrect migration or reporting of an incorrect status. So you |
| 126 | +would build in some automation if you intend to use it. |
| 127 | + |
| 128 | +One way of finding out the shard to which a tenant will be mapped is by running this query in vtgate: |
| 129 | +`select shard from <your_vindex_name> where id = <tenant_id>;` |
| 130 | + |
| 131 | + |
0 commit comments