Skip to content

egg-mysql 迁移 mysql 8.0 charset=utf8mb4 不生效 #5713

@uqeq

Description

@uqeq

在此输入你需要反馈的 Bug 具体信息(Bug in Detail):

由于业务机房调整,数据库从mysql 5.7 迁移到 mysql 8.0.35,迁移数据库后发现数据库查询出现了中文乱码。
(直接在数据库set names utf8 查询中文返回正常,程序读取乱码)

  1. 通过egg-mysql 底层依赖查询,发现依赖的是ali-rds 的底层框架,如果不指定charset则默认为utf8mb4
  2. 迁移到mysql 8.0.35 之后,通过debug日志打点,直接通过sql查询程序的连接charset 发生了改变
class AppBootHook {
  constructor(app) {
    this.app = app;
    console.log(`app pid: ${process.pid}`);
    const requestLogger = this.app.getLogger('requestLogger');
    UTILS.setHttpClientLog(app.httpclient, requestLogger);
  }
  // async didLoad() {
  //   // 请将你的插件项目中 app.beforeStart 中的代码置于此处。
  // }
  async willReady() {
    // 请将你的应用项目中 app.beforeStart 中的代码置于此处。
    const charset = await this.app.mysql.query(`
    SELECT 
      @@character_set_database AS database_charset,
      @@character_set_server AS server_charset,
      @@character_set_connection AS connection_charset,
      @@character_set_client AS client_charset,
      @@character_set_results AS results_charset
    `)
    this.app.coreLogger.info(`mysql charset: ${JSON.stringify(charset[0])}`);
    await this.app.mysql.query(`set names utf8mb4`)
    const charset_after = await this.app.mysql.query(`
    SELECT 
      @@character_set_database AS database_charset,
      @@character_set_server AS server_charset,
      @@character_set_connection AS connection_charset,
      @@character_set_client AS client_charset,
      @@character_set_results AS results_charset
    `)
    this.app.coreLogger.info(`mysql charset: ${JSON.stringify(charset_after[0])}`);
  }
}

print

2025-12-03 20:24:55,813 INFO 60 mysql charset: {"database_charset":"latin1","server_charset":"latin1","connection_charset":"latin1","client_charset":"latin1","results_charset":"latin1"}
2025-12-03 20:24:55,816 INFO 60 mysql charset: {"database_charset":"latin1","server_charset":"latin1","connection_charset":"utf8mb4","client_charset":"utf8mb4","results_charset":"utf8mb4"}
  1. 即默认的编码从 utf8mb4 变成了latin1编码,通过配置强制设置charset = utf8mb4也不生效
  config.mysql = {
    client: {
      // host
      host: process.env.DB_HOST,
      // 端口号
      port: process.env.DB_PORT,
      // 用户名
      user: process.env.DB_USER,
      // 密码
      password: process.env.DB_USER_PASSWORD,
      // 数据库名
      database: process.env.DB_DATABASE,
      // 连接池大小
      connectionLimit: 20,
      // 字符集
      charset: process.env.DB_CHARSET || 'utf8mb4',
    },
  };
  1. 翻越源码得知egg-mysql会创建数据库连接池,如果set names utf8mb4的话,只能对连接池的某一个连接生效,其余的仍然是latin1编码。升级egg-mysql 版本到 5.0.0 问题仍然存在

代码依赖

{
  "name": "unipay-api-manager-server",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "dependencies": {
    "crypto-js": "^3.1.9-1",
    "date-fns": "^2.0.0-alpha.27",
    "date-fns-tz": "^1.0.7",
    "diff-match-patch": "^1.0.4",
    "egg": "^2.25.0",
    "egg-mysql": "^3.0.0",
    "egg-proxy": "^1.0.6",
    "egg-redis": "^2.4.0",
    "egg-scripts": "^2.11.1",
    "egg-validate": "^2.0.1",
    "form-data": "^2.4.0",
    "ioredis": "^4.11.1",
    "jaeger-client": "^3.15.0",
    "lodash": "^4.17.11",
    "md5": "^2.2.1",
    "mysql": "^2.17.1",
    "ncp": "^2.0.0",
    "openid": "^2.0.6",
    "rimraf": "^2.6.3",
    "unidiff": "^1.0.2",
    "unzipper": "^0.10.1",
    "uuid": "^3.3.2"
  },
  "devDependencies": {
    "autod": "^3.1.0",
    "autod-egg": "^1.0.0",
    "cross-env": "^6.0.3",
    "egg-bin": "^4.14.0",
    "egg-ci": "^1.13.1",
    "egg-mock": "^3.24.2",
    "eslint": "^6.0.1",
    "eslint-config-egg": "^7.3.1"
  },
  "engines": {
    "node": ">=8.9.0"
  },
  "scripts": {
    "start": "egg-scripts start --title=unipay-api-manager-server",
    "stop": "egg-scripts stop --title=unipay-api-manager-server",
    "dev": "egg-bin dev",
    "debug": "cross-env EGG_AGENT_DEBUG_PORT=5900 egg-bin debug",
    "test": "egg-bin test",
    "test-lint": "npm run lint -- --fix && npm run test",
    "cov": "egg-bin cov",
    "lint": "eslint .",
    "ci": "npm run lint && npm run cov",
    "autod": "autod"
  },
  "prettier": {
    "printWidth": 150,
    "singleQuote": true,
    "trailingComma": "all",
    "arrowParens": "always",
    "jsxSingleQuote": true,
    "endOfLine": "lf"
  },
  "ci": {
    "version": "8"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "author": "zhoucong",
  "license": "MIT"
}

可复现问题的仓库地址(Reproduction Repo)

nope

Node 版本号:

node12

Eggjs 版本号:

2.25.0

相关插件名称与版本号(PlugIn and Name):

egg-mysql 3.0.0

操作平台与版本号(Platform and Version):

linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions