#!/bin/bash # 恢复 game_enter_server 数据 # 依赖: mysql 命令行、mongosh(或 mongo) # 运行: bash recover_enter_server.sh > recover.sql # ========== 配置 ========== MYSQL_HOST="127.0.0.1" MYSQL_PORT="3306" MYSQL_USER="root" MYSQL_PASS="wch123.com" MYSQL_DB="sdk" MONGO_HOST="127.0.0.1" MONGO_PORT="27017" # ========================== # 判断用 mongosh 还是旧版 mongo if command -v mongosh &>/dev/null; then MONGO_CMD="mongosh --quiet" elif command -v mongo &>/dev/null; then MONGO_CMD="mongo --quiet" else echo "-- 错误: 未找到 mongosh 或 mongo 命令" >&2 exit 1 fi MYSQL_CLI="mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} ${MYSQL_DB} -N -s" echo "-- 恢复 game_enter_server (game_server.tag=11)" echo "-- 生成时间: $(date '+%Y-%m-%d %H:%M:%S')" echo "" # 查询 tag=11 的区服列表: id|sid|db_name|tag|open_time|megre_server # megre_server>0 表示已合服,值为主服 id SERVERS=$($MYSQL_CLI 2>/dev/null <<'EOF' SELECT CONCAT(id,'|',IFNULL(sid,''),'|',IFNULL(db_name,''),'|',tag,'|',open_time,'|',megre_server) FROM game_server WHERE tag=11; EOF ) if [ -z "$SERVERS" ]; then echo "-- 未查询到 tag=11 的区服" >&2 exit 1 fi SERVER_COUNT=$(echo "$SERVERS" | wc -l | tr -d ' ') echo "-- 共找到 ${SERVER_COUNT} 个 tag=11 区服" >&2 TOTAL=0 # 记录已查询过的 db_name,避免重复查同一个 mongo 库 declare -A QUERIED_DB while IFS='|' read -r SERVER_ID SID DB_NAME TAG OPEN_TIME MEGRE_SERVER; do # 判断是否合服 if [ -n "$MEGRE_SERVER" ] && [ "$MEGRE_SERVER" -gt 0 ] 2>/dev/null; then # 合服:查主服的 db_name MAIN_DB=$($MYSQL_CLI 2>/dev/null <&2 continue fi QUERY_DB="$MAIN_DB" echo "-- server_id=${SERVER_ID} 已合服到主服 id=${MEGRE_SERVER},使用库 ${QUERY_DB}" >&2 else # 未合服:用自己的 db_name if [ -z "$DB_NAME" ]; then echo "-- [SKIP] server_id=${SERVER_ID} db_name 为空" >&2 continue fi QUERY_DB="$DB_NAME" fi # 该 db 已查询过,跳过 if [ "${QUERIED_DB[$QUERY_DB]+isset}" ]; then echo "-- [SKIP] server_id=${SERVER_ID} 库 ${QUERY_DB} 已查询过,跳过" >&2 continue fi QUERIED_DB[$QUERY_DB]=1 if [ -n "$OPEN_TIME" ] && [ "$OPEN_TIME" -gt 0 ] 2>/dev/null; then CREATE_TIME="FROM_UNIXTIME(${OPEN_TIME})" else CREATE_TIME="NOW()" fi # 从 MongoDB 查询 char 集合,取 uid(newUniqueTag 最后一段) UIDS=$($MONGO_CMD --host ${MONGO_HOST} --port ${MONGO_PORT} </dev/null db = db.getSiblingDB('${QUERY_DB}'); db.char.find({newUniqueTag: {\$exists: true, \$ne: ""}}, {newUniqueTag:1, _id:0}).forEach(function(doc){ var parts = doc.newUniqueTag.split('|'); var uid = parts[parts.length - 1]; if(uid && /^\d+$/.test(uid)) { print('OK|' + uid); } else { print('WARN|' + doc.newUniqueTag); } }); EOF ) COUNT=$(echo "$UIDS" | grep -c . 2>/dev/null || echo 0) echo "-- [${QUERY_DB}] server_id=${SERVER_ID} 角色数=${COUNT}" >&2 if [ -z "$UIDS" ]; then continue; fi BATCH=() while IFS= read -r LINE; do [ -z "$LINE" ] && continue PREFIX="${LINE%%|*}" UID_VAL="${LINE#*|}" if [ "$PREFIX" = "WARN" ]; then echo "-- [WARN] 异常 newUniqueTag: ${UID_VAL}" >&2 continue fi if [ "$PREFIX" != "OK" ]; then echo "-- [SKIP] 非预期输出: ${LINE}" >&2 continue fi SAFE_UID=$(echo "$UID_VAL" | sed "s/'/\\\\'/g") BATCH+=("('${SAFE_UID}', '${SID}', ${CREATE_TIME}, '${SID}', ${TAG})") TOTAL=$((TOTAL + 1)) if [ ${#BATCH[@]} -ge 500 ]; then echo "INSERT INTO \`game_enter_server\` (\`uid\`, \`server_id\`, \`create_time\`, \`first_server_id\`, \`tag\`) VALUES" IFS=','; echo "${BATCH[*]};"|sed 's/),(/),\n(/g'; unset IFS echo "" BATCH=() fi done <<< "$UIDS" if [ ${#BATCH[@]} -gt 0 ]; then echo "INSERT INTO \`game_enter_server\` (\`uid\`, \`server_id\`, \`create_time\`, \`first_server_id\`, \`tag\`) VALUES" IFS=','; echo "${BATCH[*]};"|sed 's/),(/),\n(/g'; unset IFS echo "" BATCH=() fi done <<< "$SERVERS" echo "-- 完成,共生成 ${TOTAL} 条记录" >&2