Compare commits
2 Commits
d7d7c64c01
...
15f058617a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15f058617a | ||
|
|
29ff0a2637 |
28
README.md
28
README.md
@@ -134,6 +134,34 @@ mvn spotless:apply compile
|
|||||||
mvn spotless:apply checkstyle:check compile
|
mvn spotless:apply checkstyle:check compile
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 数据库迁移
|
||||||
|
|
||||||
|
仓库根目录下提供 `flyway/` 配置与 `flyway.sh` 工具脚本,用于在不同环境执行迁移。
|
||||||
|
|
||||||
|
### Profile 与配置
|
||||||
|
|
||||||
|
| Profile | 配置文件 | 用途 |
|
||||||
|
|------------|-----------------------|------------------------------|
|
||||||
|
| `dev` | `flyway/dev.conf` | 本地 `play-with` 开发库 |
|
||||||
|
| `staging` | `flyway/staging.conf` | 生产克隆 / 本地 staging 库 |
|
||||||
|
| `api-test` | `flyway/api-test.conf`| API 集成测试数据库 |
|
||||||
|
| `prod` | `flyway/prod.conf` | 线上生产库 |
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 校验本地 schema
|
||||||
|
./flyway.sh validate --profile dev
|
||||||
|
|
||||||
|
# 对 API 测试库执行迁移
|
||||||
|
./flyway.sh migrate --profile api-test
|
||||||
|
|
||||||
|
# 修复 staging 库
|
||||||
|
./flyway.sh repair --profile staging
|
||||||
|
```
|
||||||
|
|
||||||
|
当对 `prod` profile 执行 `migrate` 或 `repair` 时,脚本会连续两次提示“你备份数据库了吗?”以避免误操作,输入 `yes` 才会继续。
|
||||||
|
|
||||||
## API 集成测试指南
|
## API 集成测试指南
|
||||||
|
|
||||||
在 `play-admin` 模块内提供了基于 `apitest` Profile 的端到端测试套件。为了稳定跑通所有 API 场景,请按以下步骤准备环境:
|
在 `play-admin` 模块内提供了基于 `apitest` Profile 的端到端测试套件。为了稳定跑通所有 API 场景,请按以下步骤准备环境:
|
||||||
|
|||||||
92
flyway.sh
Executable file
92
flyway.sh
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
CONFIG_DIR="$SCRIPT_DIR/flyway"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<USAGE
|
||||||
|
Usage: $(basename "$0") <migrate|validate|repair> --profile <api-test|dev|staging|prod>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
./flyway.sh validate --profile dev
|
||||||
|
./flyway.sh migrate --profile api-test
|
||||||
|
USAGE
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -lt 2 ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
action="$1"
|
||||||
|
shift
|
||||||
|
case "$action" in
|
||||||
|
migrate|validate|repair) ;;
|
||||||
|
*) echo "[ERROR] Unsupported action: $action" >&2; usage ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
profile=""
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--profile|-p)
|
||||||
|
[[ $# -ge 2 ]] || usage
|
||||||
|
profile="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "[ERROR] Unknown argument: $1" >&2
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$profile" ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$profile" in
|
||||||
|
api-test|apitest)
|
||||||
|
profile="api-test"
|
||||||
|
config_file="$CONFIG_DIR/api-test.conf"
|
||||||
|
;;
|
||||||
|
dev)
|
||||||
|
config_file="$CONFIG_DIR/dev.conf"
|
||||||
|
;;
|
||||||
|
staging)
|
||||||
|
config_file="$CONFIG_DIR/staging.conf"
|
||||||
|
;;
|
||||||
|
prod)
|
||||||
|
config_file="$CONFIG_DIR/prod.conf"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "[ERROR] Unknown profile: $profile" >&2
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ ! -f "$config_file" ]]; then
|
||||||
|
echo "[ERROR] Config file not found: $config_file" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
confirm_backup() {
|
||||||
|
local prompt="$1"
|
||||||
|
read -r -p "$prompt (yes/no): " reply
|
||||||
|
if [[ "$reply" != "yes" ]]; then
|
||||||
|
echo "操作已取消"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$profile" == "prod" && ( "$action" == "migrate" || "$action" == "repair" ) ]]; then
|
||||||
|
confirm_backup "你备份数据库了吗?"
|
||||||
|
confirm_backup "你真的备份了吗?"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec mvn \
|
||||||
|
-f "$SCRIPT_DIR/pom.xml" \
|
||||||
|
-pl play-admin \
|
||||||
|
-DskipTests \
|
||||||
|
"flyway:$action" \
|
||||||
|
"-Dflyway.configFiles=$config_file"
|
||||||
10
flyway/api-test.conf
Normal file
10
flyway/api-test.conf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
flyway.url=jdbc:mysql://127.0.0.1:33306/peipei_apitest?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
|
||||||
|
flyway.user=apitest
|
||||||
|
flyway.password=apitest
|
||||||
|
flyway.locations=classpath:db/migration
|
||||||
|
flyway.table=admin_flyway_schema_history
|
||||||
|
flyway.baselineOnMigrate=true
|
||||||
|
flyway.baselineVersion=1
|
||||||
|
flyway.cleanDisabled=true
|
||||||
|
flyway.outOfOrder=false
|
||||||
|
flyway.validateOnMigrate=false
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
flyway.url=jdbc:mysql://122.51.20.105:3306/play-with?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
|
flyway.url=jdbc:mysql://122.51.20.105:3306/play-with?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
|
||||||
flyway.user=root
|
flyway.user=root
|
||||||
flyway.password=KdaKRZ2trpdhNePa
|
flyway.password=KdaKRZ2trpdhNePa
|
||||||
lyway.locations=classpath:db/migration
|
flyway.locations=classpath:db/migration
|
||||||
flyway.table=admin_flyway_schema_history
|
flyway.table=admin_flyway_schema_history
|
||||||
flyway.baselineOnMigrate=true
|
flyway.baselineOnMigrate=true
|
||||||
flyway.baselineVersion=1
|
flyway.baselineVersion=1
|
||||||
10
flyway/staging.conf
Normal file
10
flyway/staging.conf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
flyway.url=jdbc:mysql://127.0.0.1:3307/play-with?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
|
||||||
|
flyway.user=root
|
||||||
|
flyway.password=root
|
||||||
|
flyway.locations=classpath:db/migration
|
||||||
|
flyway.table=admin_flyway_schema_history
|
||||||
|
flyway.baselineOnMigrate=true
|
||||||
|
flyway.baselineVersion=1
|
||||||
|
flyway.cleanDisabled=true
|
||||||
|
flyway.outOfOrder=false
|
||||||
|
flyway.validateOnMigrate=false
|
||||||
@@ -13,13 +13,14 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
driverClassName: com.mysql.cj.jdbc.Driver
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://localhost:33306/peipei_apitest?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
|
url: jdbc:mysql://localhost:33306/peipei_apitest?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&connectionCollation=utf8mb4_general_ci&sessionVariables=collation_connection=utf8mb4_general_ci
|
||||||
username: apitest
|
username: apitest
|
||||||
password: apitest
|
password: apitest
|
||||||
druid:
|
druid:
|
||||||
enable: true
|
enable: true
|
||||||
db-type: mysql
|
db-type: mysql
|
||||||
filters: stat,wall
|
filters: stat,wall
|
||||||
|
connection-init-sqls: SET NAMES utf8mb4 COLLATE utf8mb4_general_ci
|
||||||
max-active: 20
|
max-active: 20
|
||||||
initial-size: 1
|
initial-size: 1
|
||||||
max-wait: 60000
|
max-wait: 60000
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
-- Align legacy tables with production: ensure core order/earnings tables use utf8mb4_general_ci.
|
||||||
|
-- Safe to run multiple times; already-general_ci tables will simply rebuild without data changes.
|
||||||
|
|
||||||
|
-- Some historical tables (e.g. sys_tenant_recharge_info) still rely on zero-datetime
|
||||||
|
-- defaults. MySQL 8 with NO_ZERO_DATE / NO_ZERO_IN_DATE rejects those definitions
|
||||||
|
-- when the engine rebuilds the table. Temporarily drop those sql_mode flags so the
|
||||||
|
-- table structure matches production before/after this migration.
|
||||||
|
SET @OLD_SQL_MODE = @@sql_mode;
|
||||||
|
SET SESSION sql_mode = REPLACE(REPLACE(@OLD_SQL_MODE, 'NO_ZERO_IN_DATE', ''), 'NO_ZERO_DATE', '');
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_log_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_random_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_refund_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_continue_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_demand_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_evaluate_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_user_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_gift_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_article_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_follow_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_leave_msg`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_level_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_user_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_user_review_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_level_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_gift_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_classification_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_type_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_type_user_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_personnel_group_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_personnel_admin_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_personnel_waiter_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_coupon_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_coupon_details`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_gift_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_user`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_user_role`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_role`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_role_menu`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_role_dept`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_dept`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_menu`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_tenant`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_tenant_package`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_tenant_recharge_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `blind_box_config`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `blind_box_pool`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `blind_box_reward`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `commodity_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `gen_table`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `gen_table_column`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `order_details_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `order_log_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_account info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_avatar_frame_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_balance_details_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_article_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_commodity_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_data_review_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_operation_log`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_pk`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_ranking_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_resource info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_wages_details_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_wages_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_clerk_waiter_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `shop_ui_setting`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_administrative_area_dict_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_dict`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_dict_data`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_login_log`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `sys_operation_log`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
ALTER TABLE `play_shop_article_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_shop_carousel_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_commodity_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_commodity_and_level_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_custom_amount details`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_notice_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
ALTER TABLE `play_order_complaint_info`
|
||||||
|
CONVERT TO CHARACTER SET utf8mb4
|
||||||
|
COLLATE utf8mb4_general_ci;
|
||||||
|
|
||||||
|
-- Restore original sql_mode flags once the rebuilds are done.
|
||||||
|
SET SESSION sql_mode = @OLD_SQL_MODE;
|
||||||
137
recreate-staging.sh
Executable file
137
recreate-staging.sh
Executable file
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CONTAINER_NAME=${STAGING_MYSQL_CONTAINER:-peipei-mysql-staging}
|
||||||
|
VOLUME_NAME=${STAGING_MYSQL_VOLUME:-peipei-mysql-staging-data}
|
||||||
|
HOST_PORT=${STAGING_MYSQL_PORT:-3307}
|
||||||
|
DB_NAME=${STAGING_MYSQL_DB:-play-with}
|
||||||
|
ROOT_PASSWORD=${STAGING_MYSQL_ROOT_PASSWORD:-root}
|
||||||
|
MYSQL_IMAGE=${STAGING_MYSQL_IMAGE:-mysql:8.0.32}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<USAGE
|
||||||
|
Usage: $0 <path-to-backup.sql[.gz|.xz]>
|
||||||
|
|
||||||
|
Recreates the local staging MySQL container (${CONTAINER_NAME}) and imports the given SQL dump.
|
||||||
|
Environment overrides: STAGING_MYSQL_CONTAINER, STAGING_MYSQL_VOLUME, STAGING_MYSQL_PORT,
|
||||||
|
STAGING_MYSQL_DB, STAGING_MYSQL_ROOT_PASSWORD, STAGING_MYSQL_IMAGE.
|
||||||
|
USAGE
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_path=$1
|
||||||
|
if [[ ! -f "$backup_path" ]]; then
|
||||||
|
echo "[ERROR] Backup file not found: $backup_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
|
echo "[ERROR] docker command not found" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
port_in_use() {
|
||||||
|
if command -v lsof >/dev/null 2>&1; then
|
||||||
|
lsof -iTCP:"$HOST_PORT" -sTCP:LISTEN -Pn >/dev/null 2>&1 && return 0
|
||||||
|
fi
|
||||||
|
if command -v netstat >/dev/null 2>&1; then
|
||||||
|
netstat -an | grep -E "\.$HOST_PORT .*LISTEN" >/dev/null 2>&1 && return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
confirm_remove() {
|
||||||
|
local prompt="$1"
|
||||||
|
read -r -p "$prompt (yes/no): " reply
|
||||||
|
if [[ "$reply" != "yes" ]]; then
|
||||||
|
echo "操作已取消"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
existing_container_id=$(docker ps -a --filter "name=^${CONTAINER_NAME}$" -q)
|
||||||
|
if [[ -n "$existing_container_id" ]]; then
|
||||||
|
echo "[WARN] Container ${CONTAINER_NAME} already exists."
|
||||||
|
confirm_remove "Remove the existing staging container and recreate it?"
|
||||||
|
docker rm -f "$CONTAINER_NAME" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] Removing existing volume (if any): ${VOLUME_NAME}"
|
||||||
|
if docker volume ls -q --filter "name=^${VOLUME_NAME}$" | grep -Fxq "$VOLUME_NAME"; then
|
||||||
|
docker volume rm "$VOLUME_NAME" >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if port_in_use; then
|
||||||
|
containers_on_port=$(docker ps --filter "publish=${HOST_PORT}" --format '{{.ID}}\t{{.Names}}')
|
||||||
|
if [[ -n "$containers_on_port" ]]; then
|
||||||
|
echo "[WARN] Host port ${HOST_PORT} is currently used by the following container(s):"
|
||||||
|
while IFS=$'\t' read -r cid cname; do
|
||||||
|
[[ -z "$cid" ]] && continue
|
||||||
|
echo " - ${cname} (${cid})"
|
||||||
|
done <<<"$containers_on_port"
|
||||||
|
confirm_remove "Stop and remove these container(s)?"
|
||||||
|
while IFS=$'\t' read -r cid cname; do
|
||||||
|
[[ -z "$cid" ]] && continue
|
||||||
|
docker stop "$cid" >/dev/null
|
||||||
|
docker rm "$cid" >/dev/null
|
||||||
|
done <<<"$containers_on_port"
|
||||||
|
else
|
||||||
|
echo "[ERROR] Host port ${HOST_PORT} is already in use. Set STAGING_MYSQL_PORT to an unused port or stop the process using it." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if port_in_use; then
|
||||||
|
echo "[ERROR] Host port ${HOST_PORT} is still in use after stopping containers. Please free the port manually or change STAGING_MYSQL_PORT." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] Starting fresh MySQL container ${CONTAINER_NAME}"
|
||||||
|
docker run -d \
|
||||||
|
--name "$CONTAINER_NAME" \
|
||||||
|
-p "${HOST_PORT}:3306" \
|
||||||
|
-e MYSQL_ROOT_PASSWORD="$ROOT_PASSWORD" \
|
||||||
|
-e MYSQL_DATABASE="$DB_NAME" \
|
||||||
|
-v "$VOLUME_NAME:/var/lib/mysql" \
|
||||||
|
"$MYSQL_IMAGE" \
|
||||||
|
--lower_case_table_names=1 \
|
||||||
|
--explicit_defaults_for_timestamp=1 \
|
||||||
|
--character-set-server=utf8mb4 \
|
||||||
|
--collation-server=utf8mb4_unicode_ci >/dev/null
|
||||||
|
|
||||||
|
echo -n "[INFO] Waiting for MySQL to accept connections"
|
||||||
|
for attempt in {1..60}; do
|
||||||
|
if docker exec "$CONTAINER_NAME" mysqladmin ping -h127.0.0.1 -uroot -p"$ROOT_PASSWORD" --silent >/dev/null 2>&1; then
|
||||||
|
echo " - ready"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
echo -n "."
|
||||||
|
if [[ $attempt -eq 60 ]]; then
|
||||||
|
echo "\n[ERROR] MySQL did not become ready in time" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
case "$backup_path" in
|
||||||
|
*.gz)
|
||||||
|
reader=(gzip -dc -- "$backup_path")
|
||||||
|
;;
|
||||||
|
*.xz)
|
||||||
|
reader=(xz -dc -- "$backup_path")
|
||||||
|
;;
|
||||||
|
*.zip)
|
||||||
|
reader=(unzip -p -- "$backup_path")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
reader=(cat -- "$backup_path")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "[INFO] Importing backup $backup_path into ${DB_NAME}"
|
||||||
|
"${reader[@]}" | docker exec -i "$CONTAINER_NAME" mysql -uroot -p"$ROOT_PASSWORD" --default-character-set=utf8mb4 "$DB_NAME"
|
||||||
|
|
||||||
|
echo "[INFO] Staging database restored. Container ${CONTAINER_NAME} is listening on port ${HOST_PORT}."
|
||||||
Reference in New Issue
Block a user