## Module 2: TiDB Cloud Branching and Manual Setup

### 2.1 What TiDB Cloud Branching Is

You can think of TiDB Cloud Branching as: **creating a new database branch on top of a data snapshot from a parent branch**. Branches are isolated from each other, so you can freely run DDL/DML/queries to validate changes. If you do not like the outcome, you can discard the branch; if you do, you can continue evolving from that branch as a new baseline.

For details, see the official docs: [TiDB Cloud Branching Overview](https://docs.pingcap.com/tidbcloud/branch-overview/).

### 2.2 Creating a Branch Manually in the Console

1. Open the [TiDB Cloud console](https://tidbcloud.com/project/clusters) and select the TiDB Cloud cluster prepared for this lab. If you started the lab by choosing `Create New Cluster`, the cluster name will be `${LAB:SERVERLESS_CLUSTER_NAME}`.
2. In the cluster page, locate **Branches**.
   ![image.png 85%](https://lab-static.pingcap.com/images/2025/12/15/c863b787f66c3a0f52fc843d950fa044f4325827.png)
3. Click **Create branch**, and configure:
   - **Parent branch**: select the `main` branch.
   - **Branch name**: choose a clear name, for example `manual_sandbox`.
4. Click **Create** and wait until the branch becomes available (shown as `Active`).
   ![image.png 85%](https://lab-static.pingcap.com/images/2025/12/15/5f4493e908fa1faa0f7d819d7f380d3ee72b7dac.png)

> [!TIP]
> You can treat this manually created branch as a **safe sandbox**: for any risky DDL/DML, test on the branch first, then decide whether to apply changes on the main line.

### 2.3 Verifying Isolation: Create a Table on a Branch Without Affecting `main`

The goal of this section is to **create a table in the branch you just created**, then reconnect to `main` and confirm that it **has not changed**.

#### 2.3.1 Connecting to Your New Branch

1. In the TiDB Cloud cluster page, go to the **Branches** list.
2. Find the branch you created (for example `manual_sandbox`), then click `...` under **Action** on the right.
3. In the pop-up menu/dialog, click **Connect**.
   ![image.png 85%](https://lab-static.pingcap.com/images/2025/12/15/b8b5c24dd97aa25a7649027920c48606da30f2c1.png)
4. You will see a connection panel similar to the one for the main branch (Host, Port, Username, Password, Database, etc.).

- Click `Generate Password` in the pop-up window.

![demo_branch_UI_09.png 85%](https://lab-static.pingcap.com/images/2025/11/27/acda36b4b8b64f0e63910a71ee3a51bca663a969.png)

- After the password is generated, select `Connect with .env` and click `copy` icon.

![env-file-branch-1.jpg 50%](https://lab-static.pingcap.com/images/2025/12/2/d16d8e8bca04b77d597b2df188502031c49dd771.jpg)

- Click [Terminal 1](ssh://monitor1-ssh#1) to launch a terminal session on the Ubuntu machine assigned to you.

- In the terminal, paste the copied `manual_sandbox` connection information to set the environment variable values. The output should resemble the following example:

  ```output
  ~/tidb-lab-branches# DB_HOST=gateway01.us-west-2.prod.aws.tidbcloud.com
  DB_PORT=4000
  DB_USERNAME='3NViMyHWFBkJvQq.root'
  DB_PASSWORD='1Pbcc4CFXTtnZA4C'
  DB_DATABASE='${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}'
  ```

- Execute the following command to save the `manual_sandbox` connection environment variables to `.env-ms` file.

  ```bash
  cat > .env-ms <<EOF
  BRANCH_HOST=$DB_HOST
  BRANCH_PORT=$DB_PORT
  BRANCH_USERNAME=$DB_USERNAME
  BRANCH_PASSWORD=$DB_PASSWORD
  BRANCH_DATABASE=${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}
  EOF
  ```

- Connect to the new branch `manual_sandbox`.

  ```bash
  source .env-ms
  mysql \
   --comments -u $BRANCH_USERNAME -p$BRANCH_PASSWORD \
   -h $BRANCH_HOST -P $BRANCH_PORT \
   --ssl-mode=VERIFY_IDENTITY --ssl-ca=/etc/ssl/certs/ca-certificates.crt \
   -D ${LAB:SERVERLESS_CLUSTER_DATABASE_NAME}
  ```

  ```output
  mysql>
  ```

#### 2.3.2 Creating a Table on the Branch

- After you connect, run any DDL in your SQL client (example):

```sql
CREATE TABLE IF NOT EXISTS branch_only_demo (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  note VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

- Then confirm it exists (example):

  ```sql
  SHOW TABLES;
  ```

  ```output
  +--------------------------------+
  | Tables_in_lab_demo_411_6930301 |
  +--------------------------------+
  | branch_only_demo               |
  +--------------------------------+
  1 row in set (0.01 sec)
  ```

#### 2.3.3 Reconnecting to `main` and Confirming No Changes

- Click [Terminal 2](ssh://monitor1-ssh#2) to open another terminal.

- Connect to the lab database on the main branch.

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

- Run the same check on `main` (example):

  ```sql
  SHOW TABLES;
  ```

  ```output
  Empty set (0.01 sec)
  ```

You should see that `branch_only_demo` **does not appear in `main`**. This is one of the key values of Branching: **isolate changes to enable safe iteration and clean comparison**.

- Close both [Terminal 1](ssh://monitor1-ssh#1) and [Terminal 2](ssh://monitor1-ssh#2).

#### 2.3.4 Deleting the Branch to Free Up Branch Quota

On TiDB Cloud's free tier, you can create up to **5 branches**. The manual branch you created in this module (for example `manual_sandbox`) consumes one slot.

> [!TIP]
> To ensure you can complete the next module (the notebook will use the full quota of 5 branches at once: 3 baseline approaches + 2 child branches based on your selection), delete the manual branch before continuing. Deleting a branch removes only changes within that branch (including the `branch_only_demo` table) and does not affect the `main` branch.

1. Return to [TiDB Cloud console](https://tidbcloud.com/project/clusters), in the **Branches** list and locate `manual_sandbox` (or your branch name).
2. Click `...` under **Action** on the right.
3. Choose **Delete** in the menu/dialog, then confirm by selecting **I understand, delete**.

### 2.4 (Optional) Connection Info and Permissions

In production systems, **branch isolation** typically relies on two things:

- **Each branch has its own access endpoint** (host/port may differ).
- **Each branch ideally uses its own credentials/permissions**, to avoid accidental operations on the wrong branch.

In this lab's code, this is encapsulated as agent tools (you will see this in the next module): after creating a branch, the agent executes `run_sql_on_branch` using branch-level connection info to ensure all DDL/DML runs on the correct branch.

### 2.5 (Optional) GitHub Integration: Using Branches in PR Testing

Beyond manual/agent-created branches, TiDB Cloud also provides a GitHub Integration. You can bind **TiDB Cloud Branches** into your GitHub Pull Request workflow.

   ![image.png 85%](https://lab-static.pingcap.com/images/2025/12/15/262351d482862288176cd45db9c3ed78b583082c.png)

Typical usage:

- Automatically create a dedicated database branch per PR (or reuse/update an existing one);
- Run migrations, regression tests, and validation against real data on that branch in CI / pre-release checks;
- Clean up branches after merge (or keep them based on policy).

When you suspect a PR might introduce data-layer bugs (schema changes, SQL changes, compatibility issues, etc.), this **PR-level real branch testing** is particularly useful.

You can enable it by following the guide of [Branch GitHub Integration](https://docs.pingcap.com/tidbcloud/branch-github-integration/?plan=starter).

### 2.6 (Optional) Branch API: Managing Branches via API

If you want to integrate branching into your own systems (for example, CI pipelines, agents, or internal platforms) to automatically create/list/clean up branches, you can use the TiDB Cloud Serverless API.

See: [BranchService - ListBranches](https://docs.pingcap.com/tidbcloud/api/v1beta1/serverless/#tag/Branch/operation/BranchService_ListBranches).
