Commit 607b2e33769a11f7b86a1766b6fbc0897e6fd819
1 parent
88bdc7a2
feat: 增加 TiDB 可选测试环境与初始化脚本
Showing
5 changed files
with
164 additions
and
1 deletions
sql/tools/README.md
| @@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
| 6 | 6 | ||
| 7 | ## 1. 测试数据库的快速启动 | 7 | ## 1. 测试数据库的快速启动 |
| 8 | 8 | ||
| 9 | -基于 Docker Compose,快速启动 MySQL、Oracle、PostgreSQL、SQL Server、OceanBase 等数据库。 | 9 | +基于 Docker Compose,快速启动 MySQL、Oracle、PostgreSQL、SQL Server、OceanBase、TiDB 等数据库。 |
| 10 | 10 | ||
| 11 | 注意!使用 Docker Compose 启动完测试数据后,因为会自动导入项目的 SQL 脚本,所以可能需要等待 1-2 分钟。 | 11 | 注意!使用 Docker Compose 启动完测试数据后,因为会自动导入项目的 SQL 脚本,所以可能需要等待 1-2 分钟。 |
| 12 | 12 | ||
| @@ -139,6 +139,34 @@ password: 123456 | @@ -139,6 +139,34 @@ password: 123456 | ||
| 139 | 139 | ||
| 140 | > 注意:`root@test` 连接的是 MySQL 模式的 `test` 租户。配置了多个数据源时,需要同步修改对应配置。数据和部署配置分别保存在 `oceanbase`、`oceanbase_config` 数据卷中,重启不需要重新导入 SQL。镜像说明见 [OceanBase 官方文档](https://github.com/oceanbase/docker-images/blob/main/oceanbase-ce/README_CN.md)。 | 140 | > 注意:`root@test` 连接的是 MySQL 模式的 `test` 租户。配置了多个数据源时,需要同步修改对应配置。数据和部署配置分别保存在 `oceanbase`、`oceanbase_config` 数据卷中,重启不需要重新导入 SQL。镜像说明见 [OceanBase 官方文档](https://github.com/oceanbase/docker-images/blob/main/oceanbase-ce/README_CN.md)。 |
| 141 | 141 | ||
| 142 | +### 1.10 TiDB | ||
| 143 | + | ||
| 144 | +使用 TiDB v8.5.8 官方镜像,启动 PD、TiKV、TiDB 各 1 个节点的测试集群,支持 x86_64 和 MacBook Apple Silicon。相关服务属于 `tidb` profile,执行 `docker compose up -d` 时不会启动。 | ||
| 145 | + | ||
| 146 | +① 启动数据库,等待 TiDB 健康检查通过: | ||
| 147 | + | ||
| 148 | +```Bash | ||
| 149 | +docker compose up -d --wait --wait-timeout 300 tidb | ||
| 150 | +``` | ||
| 151 | + | ||
| 152 | +② 初始化数据库:设置 `root` 密码为 `123456`,创建 `ruoyi-vue-pro` 数据库,并依次导入 `sql/mysql/ruoyi-vue-pro.sql`、`sql/mysql/quartz.sql`: | ||
| 153 | + | ||
| 154 | +```Bash | ||
| 155 | +docker compose run --rm tidb-init | ||
| 156 | +``` | ||
| 157 | + | ||
| 158 | +> 注意:TiDB 直接复用 MySQL 脚本,不需要单独的 TiDB 脚本。初始化只允许创建全新的数据库:数据库已存在(包括空库)或重复执行时,脚本拒绝导入并返回非零状态,避免重建已有的同名表;导入失败时保留数据库便于排查,重新初始化需要删除数据卷。`TIDB_PASSWORD` 只允许字母、数字和 `_ . @ # % + = -` 字符。 | ||
| 159 | + | ||
| 160 | +③ 项目继续使用 MySQL JDBC 驱动,将数据源配置中的地址、账号和密码修改为: | ||
| 161 | + | ||
| 162 | +```yaml | ||
| 163 | +url: jdbc:mysql://127.0.0.1:4000/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true | ||
| 164 | +username: root | ||
| 165 | +password: 123456 | ||
| 166 | +``` | ||
| 167 | + | ||
| 168 | +> 注意:端口只绑定本机 `127.0.0.1:4000`。数据保存在 `tidb_pd`、`tidb_tikv` 数据卷中,重启不需要重新导入 SQL。如需重建,执行 `docker compose down tidb tidb-tikv tidb-pd` 后,删除 `ruoyi-vue-pro_tidb_pd`、`ruoyi-vue-pro_tidb_tikv` 数据卷。该环境仅用于开发测试,生产部署见 [TiDB 官方文档](https://docs.pingcap.com/zh/tidb/v8.5/production-deployment-using-tiup/)。 | ||
| 169 | + | ||
| 142 | ## 1.X 容器的销毁重建 | 170 | ## 1.X 容器的销毁重建 |
| 143 | 171 | ||
| 144 | 开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。 | 172 | 开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。 |
sql/tools/docker-compose.yaml
| @@ -10,6 +10,8 @@ volumes: | @@ -10,6 +10,8 @@ volumes: | ||
| 10 | highgo: { } | 10 | highgo: { } |
| 11 | oceanbase: { } | 11 | oceanbase: { } |
| 12 | oceanbase_config: { } | 12 | oceanbase_config: { } |
| 13 | + tidb_pd: { } | ||
| 14 | + tidb_tikv: { } | ||
| 13 | 15 | ||
| 14 | services: | 16 | services: |
| 15 | mysql: | 17 | mysql: |
| @@ -173,3 +175,79 @@ services: | @@ -173,3 +175,79 @@ services: | ||
| 173 | timeout: 5s | 175 | timeout: 5s |
| 174 | start_period: 120s | 176 | start_period: 120s |
| 175 | retries: 30 | 177 | retries: 30 |
| 178 | + | ||
| 179 | + # TiDB 测试集群:PD、TiKV、TiDB 各 1 个节点,属于 tidb profile,默认不启动 | ||
| 180 | + # 启动:docker compose up -d --wait --wait-timeout 300 tidb | ||
| 181 | + tidb-pd: | ||
| 182 | + image: pingcap/pd:v8.5.8 | ||
| 183 | + profiles: ["tidb"] | ||
| 184 | + restart: unless-stopped | ||
| 185 | + command: | ||
| 186 | + - --name=pd | ||
| 187 | + - --client-urls=http://0.0.0.0:2379 | ||
| 188 | + - --peer-urls=http://0.0.0.0:2380 | ||
| 189 | + - --advertise-client-urls=http://tidb-pd:2379 | ||
| 190 | + - --advertise-peer-urls=http://tidb-pd:2380 | ||
| 191 | + - --initial-cluster=pd=http://tidb-pd:2380 | ||
| 192 | + - --data-dir=/data/pd | ||
| 193 | + - --config=/pd.toml | ||
| 194 | + volumes: | ||
| 195 | + - tidb_pd:/data | ||
| 196 | + - ./tidb/pd.toml:/pd.toml:ro | ||
| 197 | + | ||
| 198 | + tidb-tikv: | ||
| 199 | + image: pingcap/tikv:v8.5.8 | ||
| 200 | + profiles: ["tidb"] | ||
| 201 | + restart: unless-stopped | ||
| 202 | + command: | ||
| 203 | + - --addr=0.0.0.0:20160 | ||
| 204 | + - --advertise-addr=tidb-tikv:20160 | ||
| 205 | + - --status-addr=0.0.0.0:20180 | ||
| 206 | + - --advertise-status-addr=tidb-tikv:20180 | ||
| 207 | + - --data-dir=/data/tikv | ||
| 208 | + - --pd=tidb-pd:2379 | ||
| 209 | + - --config=/tikv.toml | ||
| 210 | + volumes: | ||
| 211 | + - tidb_tikv:/data | ||
| 212 | + - ./tidb/tikv.toml:/tikv.toml:ro | ||
| 213 | + depends_on: | ||
| 214 | + - tidb-pd | ||
| 215 | + | ||
| 216 | + tidb: | ||
| 217 | + image: pingcap/tidb:v8.5.8 | ||
| 218 | + profiles: ["tidb"] | ||
| 219 | + restart: unless-stopped | ||
| 220 | + environment: | ||
| 221 | + TZ: Asia/Shanghai | ||
| 222 | + command: | ||
| 223 | + - --store=tikv | ||
| 224 | + - --path=tidb-pd:2379 | ||
| 225 | + - --advertise-address=tidb | ||
| 226 | + ports: | ||
| 227 | + # 只绑定本机,root 密码由 tidb-init 初始化 | ||
| 228 | + - "127.0.0.1:4000:4000" | ||
| 229 | + depends_on: | ||
| 230 | + - tidb-tikv | ||
| 231 | + healthcheck: | ||
| 232 | + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:10080/status >/dev/null"] | ||
| 233 | + interval: 10s | ||
| 234 | + timeout: 5s | ||
| 235 | + start_period: 60s | ||
| 236 | + retries: 30 | ||
| 237 | + | ||
| 238 | + # TiDB 初始化:设置 root 密码,创建 ruoyi-vue-pro 数据库并导入 MySQL 脚本,只允许创建全新数据库 | ||
| 239 | + # 执行:docker compose run --rm tidb-init | ||
| 240 | + tidb-init: | ||
| 241 | + image: mysql:8.0.33 | ||
| 242 | + profiles: ["tidb-init"] | ||
| 243 | + restart: "no" | ||
| 244 | + environment: | ||
| 245 | + TIDB_HOST: tidb | ||
| 246 | + TIDB_PORT: 4000 | ||
| 247 | + TIDB_DATABASE: ruoyi-vue-pro | ||
| 248 | + TIDB_PASSWORD: "123456" | ||
| 249 | + entrypoint: ["bash", "/tmp/create_schema.sh"] | ||
| 250 | + volumes: | ||
| 251 | + - ../mysql/ruoyi-vue-pro.sql:/tmp/schema.sql:ro | ||
| 252 | + - ../mysql/quartz.sql:/tmp/quartz.sql:ro | ||
| 253 | + - ./tidb/create_schema.sh:/tmp/create_schema.sh:ro |
sql/tools/tidb/create_schema.sh
0 → 100644
| 1 | +#!/bin/bash | ||
| 2 | +# 初始化 TiDB 测试库:只允许创建全新的数据库并导入项目 SQL,数据库已存在(包括空库)时拒绝导入;任一步骤失败都以非零状态退出 | ||
| 3 | +set -euo pipefail | ||
| 4 | + | ||
| 5 | +host="${TIDB_HOST:-tidb}" | ||
| 6 | +port="${TIDB_PORT:-4000}" | ||
| 7 | +database="${TIDB_DATABASE:-ruoyi-vue-pro}" | ||
| 8 | +password="${TIDB_PASSWORD:?TIDB_PASSWORD 未设置}" | ||
| 9 | + | ||
| 10 | +if [[ ! "${database}" =~ ^[A-Za-z0-9_-]+$ ]]; then | ||
| 11 | + echo "数据库名 ${database} 不合法,只允许字母、数字、下划线和中划线" >&2 | ||
| 12 | + exit 1 | ||
| 13 | +fi | ||
| 14 | +# 密码会拼接到 ALTER USER 语句中,只允许不需要转义的字符 | ||
| 15 | +if [[ ! "${password}" =~ ^[A-Za-z0-9_.@#%+=-]+$ ]]; then | ||
| 16 | + echo "TIDB_PASSWORD 不合法,只允许字母、数字和 _ . @ # % + = - 字符" >&2 | ||
| 17 | + exit 1 | ||
| 18 | +fi | ||
| 19 | + | ||
| 20 | +client=(mysql -h"${host}" -P"${port}" -uroot --default-character-set=utf8mb4) | ||
| 21 | + | ||
| 22 | +# 1. 等待 TiDB 可连接(首次启动时 PD、TiKV 需要一段时间完成初始化) | ||
| 23 | +for i in $(seq 1 60); do | ||
| 24 | + if mysqladmin -h"${host}" -P"${port}" -uroot --connect-timeout=3 ping >/dev/null 2>&1; then | ||
| 25 | + break | ||
| 26 | + fi | ||
| 27 | + if [ "${i}" -eq 60 ]; then | ||
| 28 | + echo "等待 TiDB ${host}:${port} 超时,请执行 docker compose logs tidb 检查启动日志" >&2 | ||
| 29 | + exit 1 | ||
| 30 | + fi | ||
| 31 | + sleep 5 | ||
| 32 | +done | ||
| 33 | + | ||
| 34 | +# 2. 新集群的 root 默认没有密码,首次初始化时设置为 TIDB_PASSWORD | ||
| 35 | +export MYSQL_PWD="${password}" | ||
| 36 | +if ! "${client[@]}" -e 'SELECT 1' >/dev/null 2>&1; then | ||
| 37 | + env -u MYSQL_PWD "${client[@]}" -e "ALTER USER 'root'@'%' IDENTIFIED BY '${password}';" | ||
| 38 | +fi | ||
| 39 | + | ||
| 40 | +# 3. 创建全新数据库:不使用 IF NOT EXISTS,数据库已存在时直接失败,避免项目 SQL 中的 DROP TABLE 重建已有的同名表 | ||
| 41 | +if ! "${client[@]}" -e "CREATE DATABASE \`${database}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"; then | ||
| 42 | + echo "创建数据库 ${database} 失败:只允许初始化全新的数据库,数据库已存在(包括空库)时拒绝导入;如需重新初始化,请删除 TiDB 数据卷后重建" >&2 | ||
| 43 | + exit 1 | ||
| 44 | +fi | ||
| 45 | + | ||
| 46 | +# 4. 按 ruoyi-vue-pro、quartz 的顺序导入 MySQL 脚本(mysql 客户端遇到错误会立即退出,失败时保留数据库,便于排查) | ||
| 47 | +"${client[@]}" -D "${database}" < /tmp/schema.sql | ||
| 48 | +"${client[@]}" -D "${database}" < /tmp/quartz.sql | ||
| 49 | + | ||
| 50 | +table_count=$("${client[@]}" -N -B -e "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = '${database}';") | ||
| 51 | +echo "TiDB 初始化完成:数据库 ${database} 共 ${table_count} 张表" |
sql/tools/tidb/pd.toml
0 → 100644
sql/tools/tidb/tikv.toml
0 → 100644