## モジュール 3: Laravel アプリケーションを Aurora (MySQL) から TiDB Cloud に移行する

このモジュールでは、Aurora (MySQL) データベースから TiDB Cloud Starter データベースへのテーブル定義とデータの移行を完了します。

### 手順 1. `.env` ファイルの TiDB Cloud Starter 接続パラメータを更新する

ラボの開始時に TiDB Cloud Starter を認証済みであり、その接続パラメータは既に `.env` ファイルに保存されています。ここでは `.env` ファイルを更新して、TiDB Cloud Starter の接続パラメータを使用するようにします。

+ `.env` ファイルに以下の変更を行います:
  - ローカル Aurora (MySQL) 接続パラメータを削除する
  - TiDB Cloud クラスター接続パラメータのコメントを解除する
  - ファイルを保存する

  ```properties
  # tidb cloud cluster
  DB_CONNECTION=mysql
  DB_PORT=${LAB:SERVERLESS_CLUSTER_PORT}
  DB_HOST=${LAB:SERVERLESS_CLUSTER_HOST}
  DB_USERNAME='${LAB:SERVERLESS_CLUSTER_USERNAME}'
  DB_PASSWORD='${LAB:SERVERLESS_CLUSTER_PASSWORD}'
  DB_DATABASE=${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}
  MYSQL_ATTR_SSL_CA="/etc/ssl/certs/ca-certificates.crt"
  ...
  ```

### 手順 2. TiDB Cloud にテーブル定義を準備する

+ VS Code ターミナルで、`php artisan migrate` コマンドを使用して TiDB Cloud に必要なテーブルを作成します。

   ```bash
   php artisan migrate
   ```

   ```output
   INFO  Preparing database.

   Creating migration table ........................................................................................................... 843.87ms DONE

   INFO  Running migrations.

   0001_01_01_000000_create_users_table .................................................................................................... 15s DONE
   0001_01_01_000001_create_cache_table ..................................................................................................... 1s DONE
   0001_01_01_000002_create_jobs_table ...................................................................................................... 8s DONE
   2025_12_20_112907_create_transactions_table .............................................................................................. 7s DONE
   2025_12_20_120002_create_products_table .................................................................................................. 3s DONE
   2026_01_03_040247_create_product_type_table ........................................................................................ 547.59ms DONE
   2026_01_03_040331_create_pay_types_table ........................................................................................... 651.96ms DONE
   ```

### 手順 3. テーブルの `AUTO_INCREMENT` 属性を `AUTO_RANDOM` に変更してデータホットスポットを防止する

+ VS Code ターミナルで、MySQL クライアントを使用して TiDB Cloud に接続します。

   ```bash
   mysql --comments -u ${LAB:SERVERLESS_CLUSTER_USERNAME} \
   -h ${LAB:SERVERLESS_CLUSTER_HOST} -P ${LAB:SERVERLESS_CLUSTER_PORT} \
   --ssl \
   --ssl-ca=/etc/ssl/certs/ca-certificates.crt \
   --ssl-verify-server-cert \
   -p${LAB:SERVERLESS_CLUSTER_PASSWORD} \
   ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}
   ```

   ```output
   Your MySQL connection id is 61317775
   Server version: 8.0.11-TiDB-v7.5.2-serverless TiDB Server (Apache License 2.0) Community Edition, MySQL 8.0 compatible

   Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

   Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]>
   ```

+ VS Code ターミナルで、MySQL クライアントを使用してテーブル `shop.products` と `shop.transactions` の定義を確認します。VS Code が「Are you sure you want to paste 2 lines of text into the terminal?」というウィンドウをポップアップ表示したら、「Paste」をクリックしてください。

   ![204_3_3_1.png 85%](https://lab-static.pingcap.com/images/2026/2/4/e5c082347f448be9f8db4c13b4952a204feb5346.png)

   ```sql
   SHOW CREATE TABLE products\G
   SHOW CREATE TABLE transactions\G
   ```

   ```output
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> SHOW CREATE TABLE products\G
   *************************** 1. row ***************************
         Table: products
   Create Table: CREATE TABLE `products` (
   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   `status` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'C',
   `name` varchar(80) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
   `introduction` text COLLATE utf8mb4_unicode_ci NOT NULL,
   `photo` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
   `price` decimal(10,2) NOT NULL DEFAULT '0',
   `remain_count` int(11) NOT NULL DEFAULT '0',
   `created_at` timestamp NULL DEFAULT NULL,
   `updated_at` timestamp NULL DEFAULT NULL,
   `product_type` int(11) NOT NULL DEFAULT '1',
   PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
   KEY `idx_name_product` (`name`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
   1 row in set (0.163 sec)

   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]>
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> SHOW CREATE TABLE transactions\G
   *************************** 1. row ***************************
         Table: transactions
   Create Table: CREATE TABLE `transactions` (
   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
   `user_id` bigint(20) unsigned NOT NULL,
   `product_id` bigint(20) unsigned NOT NULL,
   `price` decimal(10,2) NOT NULL,
   `buy_count` int(11) NOT NULL,
   `total_price` decimal(18,2) NOT NULL,
   `created_at` timestamp NULL DEFAULT NULL,
   `updated_at` timestamp NULL DEFAULT NULL,
   `pay_type` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '1',
   PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
   KEY `user_transaction_idx` (`user_id`),
   KEY `product_transaction_idx` (`product_id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
   1 row in set (0.163 sec)
   ```

> [!TIP]
>
> + TiDB Cloud Starter は分散データベースです。ホットスポットを避けるために、テーブル `SHOP`.`PRODUCTS` と `SHOP`.`TRANSACTIONS` の主キー `AUTO_INCREMENT` 属性を `AUTO_RANDOM` に変更することを推奨します。
> + この手順はオプションです。スキップしても移行結果に影響はありません。
> + また、変更を行う場合は、2 つのテーブルを削除して再作成する必要があり、ドキュメントに記載されている `ALTER TABLE t MODIFY COLUMN id BIGINT AUTO_RANDOM(5);` のような方法は使用できません。理由は 2 つあります:
> + まず、id カラムの BIGINT 型の 64 ビットすべてが有効な場合、PHP 言語の `PHP_INT_MAX` による整数の制限により、後のアプリケーションで整数オーバーフローエラーが発生する可能性があります。
> + 次に、id カラムに `AUTO_RANDOM(3, 32)` のように 64 ビット未満の設定を使用すると、`ALTER TABLE t MODIFY COLUMN` コマンドは整数範囲が縮小されたと判断し、データ損失の可能性があるためエラーが発生します。

+ VS Code ターミナルで、MySQL クライアントを使用して空のテーブル `shop.products` と `shop.transactions` を再構築し、テーブル `shop.products` と `shop.transactions` の主キー `AUTO_INCREMENT` 属性を `AUTO_RANDOM` に変更します。VS Code が「Are you sure you want to paste 33 lines of text into the terminal?」というウィンドウをポップアップ表示したら、「Paste」をクリックしてください。

   ![204_3_3_2.png 85%](https://lab-static.pingcap.com/images/2026/2/6/55971cef685fd59926c137c5ebe555f6663fdcb0.png)

   ```sql
   DROP TABLE `products`;

   CREATE TABLE `products` (
   `id` bigint(20) unsigned NOT NULL /*T![auto_rand] AUTO_RANDOM(3, 32) */,
   `status` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'C',
   `name` varchar(80) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
   `introduction` text COLLATE utf8mb4_unicode_ci NOT NULL,
   `photo` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
   `price` decimal(10,2) NOT NULL DEFAULT '0',
   `remain_count` int(11) NOT NULL DEFAULT '0',
   `created_at` timestamp NULL DEFAULT NULL,
   `updated_at` timestamp NULL DEFAULT NULL,
   `product_type` int(11) NOT NULL DEFAULT '1',
   PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
   KEY `idx_name_product` (`name`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

   DROP TABLE `transactions`;

   CREATE TABLE `transactions` (
   `id` bigint(20) unsigned NOT NULL /*T![auto_rand] AUTO_RANDOM(3, 32) */,
   `user_id` bigint(20) unsigned NOT NULL,
   `product_id` bigint(20) unsigned NOT NULL,
   `price` decimal(10,2) NOT NULL,
   `buy_count` int(11) NOT NULL,
   `total_price` decimal(18,2) NOT NULL,
   `created_at` timestamp NULL DEFAULT NULL,
   `updated_at` timestamp NULL DEFAULT NULL,
   `pay_type` bigint(20) unsigned NOT NULL DEFAULT 1,
   PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
   KEY `user_transaction_idx` (`user_id`),
   KEY `product_transaction_idx` (`product_id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
   ```

   ```output
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]>
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> CREATE TABLE `products` (
      -> `id` bigint(20) unsigned NOT NULL /*T![auto_rand] AUTO_RANDOM(3, 32) */,
      -> `status` varchar(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'C',
      -> `name` varchar(80) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      -> `introduction` text COLLATE utf8mb4_unicode_ci NOT NULL,
      -> `photo` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      -> `price` decimal(10,2) NOT NULL DEFAULT '0',
      -> `remain_count` int(11) NOT NULL DEFAULT '0',
      -> `created_at` timestamp NULL DEFAULT NULL,
      -> `updated_at` timestamp NULL DEFAULT NULL,
      -> `product_type` int(11) NOT NULL DEFAULT '1',
      -> PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
      -> KEY `idx_name_product` (`name`)
      -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
   Query OK, 0 rows affected, 1 warning (0.407 sec)

   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]>
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> DROP TABLE `transactions`;
   Query OK, 0 rows affected (0.559 sec)

   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]>
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> CREATE TABLE `transactions` (
      -> `id` bigint(20) unsigned NOT NULL /*T![auto_rand] AUTO_RANDOM(3, 32) */,
      -> `user_id` bigint(20) unsigned NOT NULL,
      -> `product_id` bigint(20) unsigned NOT NULL,
      -> `price` decimal(10,2) NOT NULL,
      -> `buy_count` int(11) NOT NULL,
      -> `total_price` decimal(18,2) NOT NULL,
      -> `created_at` timestamp NULL DEFAULT NULL,
      -> `updated_at` timestamp NULL DEFAULT NULL,
      -> `pay_type` bigint(20) unsigned NOT NULL DEFAULT 1,
      -> PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
      -> KEY `user_transaction_idx` (`user_id`),
      -> KEY `product_transaction_idx` (`product_id`)
      -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
   Query OK, 0 rows affected, 1 warning (0.384 sec)

   ```

+ VS Code ターミナルで、MySQL クライアントを終了してデータ移行の準備をします。

   ```sql
   EXIT
   ```

   ```output
   MySQL [${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}]> EXIT
   Bye
   root@0c2c53eace8f:~/Mshop#
   ```

### 手順 4. データ移行

+ VS Code ターミナルで、dumpling ツールを使用して shop データベース配下の必要なテーブルのデータを SQL ファイルにエクスポートします。

   ```bash
   tiup dumpling -u ${LAB:AWS_AURORA_SERVERLESS_MASTER_USERNAME} -p${LAB:AWS_AURORA_SERVERLESS_MASTER_PASSWORD} -h ${LAB:AWS_AURORA_SERVERLESS_ENDPOINT} -P 3306 -B {SERVERLESS_CLUSTER_DATABASE_NAME} \
   -T ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}.users \
   -T ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}.products \
   -T ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}.transactions \
   -T ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}.product_type \
   -T ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}.pay_type \
   --filetype sql \
   -o ./dumpling_output
   ```

   ```output
   Checking updates for component dumpling... Timedout (after 2s)
   The component `dumpling` version  is not installed; downloading from repository.
   ...
   [2026/01/21 05:10:11.018 +00:00] [INFO] [dump.go:276] ["All the dumping transactions have started. Start to unlock tables"]
   [2026/01/21 05:10:11.048 +00:00] [INFO] [collector.go:264] ["backup success summary"] [total-ranges=11] [ranges-succeed=11] [ranges-failed=0] [total-take=29.166482ms] [total-kv-size=3.933kB] [average-speed=134.8kB/s] [total-rows=35]
   [2026/01/21 05:10:11.049 +00:00] [INFO] [main.go:82] ["dump data successfully, dumpling will exit now"]
   ```

+ VS Code ターミナルで、TiDB Lightning ツールを使用して Aurora (MySQL) データベースからエクスポートしたデータを TiDB Cloud にインポートします。

   ```bash
   cat > .lightning_config <<EOF
   [mydumper]
   data-source-dir = "/root/Mshop/dumpling_output"

   [tidb]
   host = "${LAB:SERVERLESS_CLUSTER_HOST}"
   port = ${LAB:SERVERLESS_CLUSTER_PORT}
   user = "${LAB:SERVERLESS_CLUSTER_USERNAME}"
   password = "${LAB:SERVERLESS_CLUSTER_PASSWORD}"
   tls = "cluster"

   [security]
   ca-path = "/etc/ssl/certs/ca-certificates.crt"
   EOF

   tiup tidb-lightning --backend=tidb --check-requirements=false --config .lightning_config
   ```

   ```output
   Starting component tidb-lightning: /root/.tiup/components/tidb-lightning/v8.5.5/tidb-lightning --backend=tidb --check-requirements=false --config /dev/fd/63
   Verbose debug logs will be written to /tmp/lightning.log.2026-01-18T05.20.02Z

   tidb lightning exit successfully
   ```

### 手順 5. TiDB Cloud ベースの Laravel アプリケーションを起動する

+ VS Code ターミナルで、`composer run dev` コマンドを実行して Laravel アプリケーションを起動します。

  ```bash
  composer run dev
  ```

  ```output
   > Composer\Config::disableProcessTimeout
   > @php artisan serve --host=0.0.0.0

      INFO  Server running on [http://0.0.0.0:8000].

   Press Ctrl+C to stop the server
  ```

+ 「Your application running on port 8000 is available.」というポップアップウィンドウが表示されたら、「Open in Browser」をクリックします。

  ![204_1_port_8000.png 85%](https://lab-static.pingcap.com/images/2026/2/5/4f681e3a7458c7631f2187c53100aa127e5bcaf4.png)

+ 次のモジュールに進んでください。
