ShardingSphere 启动报错 “Unknown table ‘keywords‘ in information_schema“ 完整解决方案

甄选推荐系统:

Pocket Bookmarks。 口袋书签

谷歌浏览器插件:立即安装 Pocket Bookmarks

edge浏览器插件:立即安装Pocket Bookmarks

为什么你急需这个插件?

3秒极简操作:无需学习成本,清爽界面一键管理

跨设备无缝同步:电脑/手机随时存取重要链接

黑科技AI助手:自动分类+智能推荐,比你自己更懂你的收藏习惯

可视化数据看板:TOP10常用书签、访问趋势一目了然

效率党最爱的功能:

  • 多维度分类:支持标签+文件夹双重管理
  • 智能排序:按访问频率/创建时间快速筛选
  • 团队协作:分类书签一键共享给同事
  • 个性展示:九宫格/列表/时间轴多种视图

问题背景

在使用 Spring Boot 2.6.8 + ShardingSphere 4.1.1 的项目中,启动应用时遇到如下错误:

复制代码
java.sql.SQLSyntaxErrorException: Unknown table 'keywords' in information_schema
    at com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema.getSQLKeywords(DatabaseMetaDataUsingInfoSchema.java:1193)

完整的错误堆栈显示,这个错误发生在 Spring Boot Actuator 的健康检查阶段,导致整个应用无法启动。

技术栈环境

  • Spring Boot: 2.6.8
  • ShardingSphere: 4.1.1
  • MySQL: 8.0.x (低于 8.0.13)
  • MySQL Connector: mysql-connector-java
  • 数据源: Dynamic DataSource + ShardingSphere

问题原因深度分析

为什么会报这个错?

这个问题的发生链路如下:

复制代码
Spring Boot 启动
    ↓
Spring Boot Actuator 健康检查
    ↓
检查 shardingDataSource 健康状态
    ↓
ShardingSphere 初始化数据源
    ↓
MySQL JDBC 驱动查询元数据
    ↓
调用 DatabaseMetaDataUsingInfoSchema.getSQLKeywords()
    ↓
执行 SQL: SELECT * FROM information_schema.KEYWORDS
    ↓
报错:表不存在 ❌

核心矛盾

information_schema.KEYWORDS 表只在 MySQL 8.0.13+ 版本中存在!

  • 如果你的 MySQL 版本 < 8.0.13,这个表根本不存在
  • MySQL JDBC 驱动(特别是新版本)会默认使用 information_schema 来查询元数据
  • ShardingSphere 在初始化时会触发驱动的元数据查询

三个"罪魁祸首"

  1. Spring Boot Actuator - 启动时主动检查数据库健康状态
  2. ShardingSphere - 启动时会进行表元数据检查
  3. MySQL JDBC 驱动 - 默认使用 information_schema 查询关键字列表

解决方案(三管齐下)

我们需要从三个层面同时解决问题,确保万无一失。

方案一:禁用 Spring Boot Actuator 的数据库健康检查

为什么这样做?

从源头上阻止健康检查触发数据源初始化,避免问题发生。

配置方法:

application.ymlapplication-{profile}.yml 中添加:

复制代码
management:
  health:
    db:
      enabled: false

优点:

  • 立竿见影,直接阻止健康检查
  • 不影响应用正常使用数据库

缺点:

  • 失去了数据库健康检查的功能(可用其他监控方案补充)

方案二:禁用 ShardingSphere 的表元数据检查

为什么这样做?

即使数据源被初始化,也跳过不必要的元数据校验。

配置方法:

在 ShardingSphere 配置中添加 props 节点:

复制代码
spring:
  sharding-sphere:
    datasource:
      names: hotel-resource-supplier
      hotel-resource-supplier:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: jdbc:mysql://your-host:3306/your_db?serverTimezone=Asia/Shanghai
        username: your_username
        password: your_password
    sharding:
      tables:
        your_table:
          actual-data-nodes: ds.your_table$->{0..7}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: your_table$->{id % 8}
    # 关键配置:禁用表元数据检查
    props:
      sql.show: false
      check-table-metadata-enabled: false

配置说明:

  • check-table-metadata-enabled: false - 禁用启动时的表结构校验
  • sql.show: false - 关闭 SQL 日志(可选,根据需要调整为 true)

优点:

  • 不影响 ShardingSphere 的分片功能
  • 只是跳过启动时的元数据校验步骤

方案三:JDBC URL 添加参数禁用 information_schema

为什么这样做?

告诉 MySQL JDBC 驱动不要使用 information_schema,改用 SHOW 命令查询元数据。

配置方法:

在 JDBC URL 中添加 useInformationSchema=false 参数:

复制代码
spring:
  sharding-sphere:
    datasource:
      hotel-resource-supplier:
        jdbcUrl: jdbc:mysql://your-host:3306/your_db?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useInformationSchema=false

完整示例:

复制代码
spring:
  sharding-sphere:
    datasource:
      names: hotel-resource-supplier
      hotel-resource-supplier:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        jdbcUrl: jdbc:mysql://jump-hw.xxxcloud.com:33061/hotel_resource_supplier?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true&useInformationSchema=false
        username: ${DB_USER:your_username}
        password: ${DB_PWD:your_password}

优点:

  • 即使需要查询元数据,也使用兼容性更好的 SHOW 命令
  • 适用于所有 MySQL 版本

完整配置示例

application-uat.yml 完整配置

复制代码
spring:
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    dynamic:
      primary: ceekee_hotel_resource
      datasource:
        ceekee_hotel_resource:
          type: com.zaxxer.hikari.HikariDataSource
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://your-host:3306/ceekee_hotel_resource?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
          username: your_username
          password: your_password

  sharding-sphere:
    datasource:
      names: hotel-resource-supplier
      hotel-resource-supplier:
        type: com.zaxxer.hikari.HikariDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        # 方案三:添加 useInformationSchema=false
        jdbcUrl: jdbc:mysql://your-host:3306/hotel_resource_supplier?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&rewriteBatchedStatements=true&useInformationSchema=false
        username: your_username
        password: your_password
    sharding:
      tables:
        international_supplier_hotel_room_type:
          actual-data-nodes: hotel-resource-supplier.international_supplier_hotel_room_type$->{0..7}
          table-strategy:
            inline:
              sharding-column: hotel_id
              algorithm-expression: international_supplier_hotel_room_type$->{hotel_id % 8}
        international_supplier_hotel_room_type_image:
          actual-data-nodes: hotel-resource-supplier.international_supplier_hotel_room_type_image$->{0..7}
          table-strategy:
            inline:
              sharding-column: hotel_id
              algorithm-expression: international_supplier_hotel_room_type_image$->{hotel_id % 8}
    # 方案二:禁用元数据检查
    props:
      sql.show: false
      check-table-metadata-enabled: false

# 方案一:禁用健康检查
management:
  health:
    db:
      enabled: false

方案对比与选择建议

方案 生效层级 推荐指数 适用场景
方案一:禁用健康检查 Spring Boot ⭐⭐⭐⭐⭐ 不需要数据库健康检查功能的项目
方案二:禁用 ShardingSphere 元数据检查 ShardingSphere ⭐⭐⭐⭐ 使用 ShardingSphere 的项目
方案三:JDBC 参数 MySQL JDBC 驱动 ⭐⭐⭐⭐⭐ 所有使用 MySQL 的项目

推荐组合

最佳实践:三个方案同时使用

虽然理论上只需要其中一个方案即可解决问题,但为了确保在各种情况下都不会出错,建议三个方案同时配置:

  1. 方案一 在最外层拦截,避免触发问题
  2. 方案二 在 ShardingSphere 层拦截,即使触发也跳过
  3. 方案三 在 JDBC 层拦截,即使要查询也用兼容方式

这样形成三层防护,确保万无一失。


验证方案是否生效

配置完成后,重新启动应用,观察日志:

成功的日志标志

复制代码
INFO  o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat started on port(s): 16531 (http)
INFO  c.c.h.a.front.TripwiseHotelAbroadFrontApplication - Started TripwiseHotelAbroadFrontApplication in 12.345 seconds

不应该再出现的错误

复制代码
❌ java.sql.SQLSyntaxErrorException: Unknown table 'keywords' in information_schema
❌ Error creating bean with name 'shardingDataSource'
❌ Error creating bean with name 'healthEndpoint'

常见问题 FAQ

Q1: 禁用健康检查会影响生产监控吗?

A: 不会。你可以通过以下方式补充监控:

  • 使用独立的数据库监控工具(如 Prometheus + Grafana)
  • 在业务代码中自定义健康检查逻辑
  • 使用数据库自带的监控功能

Q2: 为什么不直接升级 MySQL 到 8.0.13+?

A: 升级数据库涉及以下风险:

  • 需要停机维护
  • 可能存在兼容性问题
  • 需要充分的测试
  • 不是所有环境都能随意升级

使用配置解决是最低风险的方案。

Q3: 这个配置会影响 ShardingSphere 的分片功能吗?

A: 完全不会。这些配置只是:

  • 跳过启动时的健康检查
  • 跳过元数据校验
  • 改变元数据查询方式

分片规则、路由策略、SQL 解析等核心功能完全不受影响。

Q4: 如果只配置其中一个方案可以吗?

A: 可以,但不推荐。建议三个方案都配置,原因:

  • 配置成本极低(只需要几行配置)
  • 三层防护更可靠
  • 避免因环境差异导致的问题

扩展:其他类似问题

如果你遇到以下类似错误,也可以使用相同的解决方案:

复制代码
Unknown table 'CHECK_CONSTRAINTS' in information_schema
Unknown table 'TABLESPACES' in information_schema
Unknown table 'ST_GEOMETRY_COLUMNS' in information_schema

这些都是因为 MySQL 版本差异导致的 information_schema 表不存在问题,使用 useInformationSchema=false 即可解决。


总结

问题本质

MySQL 8.0.13 版本引入了新的系统表 information_schema.KEYWORDS,但老版本 MySQL 没有这个表。当新版本的 MySQL JDBC 驱动尝试查询这个表时,就会报错导致应用无法启动。

解决思路

从三个层面同时阻断问题发生的路径:

  1. 应用层:禁用不必要的健康检查
  2. 中间件层:跳过 ShardingSphere 的元数据校验
  3. 驱动层:让 JDBC 使用兼容性更好的查询方式

核心价值

  • 快速解决:无需升级 MySQL,几分钟配置即可解决
  • 零风险:不影响任何业务功能
  • 通用性强:适用于所有 ShardingSphere + MySQL 项目
  • 防患未然:三层防护确保不会复发

最后的建议

虽然这个问题看起来很棘手,但本质上是版本兼容性问题。在无法立即升级数据库的情况下,通过合理的配置可以完美解决。

记住:最好的解决方案不是最复杂的,而是最稳定、最容易理解和维护的。


参考资料

创建时间: 2025-12-16
适用版本: Spring Boot 2.x + ShardingSphere 4.x + MySQL 5.7/8.0
关键词: ShardingSphere, MySQL, information_schema, KEYWORDS, 启动报错

相关推荐
月明长歌2 小时前
【码道初阶】【LeetCode 102】二叉树层序遍历:如何利用队列实现“一层一层切蛋糕”?
java·数据结构·算法·leetcode·职场和发展·队列
codingPower2 小时前
制作ftl文件通过FreeMarke生成PDF文件(含图片处理)
java·开发语言·pdf
R.lin2 小时前
Spring AI Alibaba 1.1 正式发布!
java·后端·spring
程序员阿明2 小时前
spring security 6的知识点总结
java·后端·spring
李子园的李2 小时前
Java函数式接口——渐进式学习
java
running up3 小时前
Spring Bean生命周期- BeanDefinition 加载与 BeanFactoryPostProcessor BeanPostProcessor
java·后端·spring
222you3 小时前
Java线程的三种创建方式
java·开发语言
脸大是真的好~3 小时前
计算机408基础相关面试题-备用,不推荐
java
小费的部落3 小时前
Excel 在Sheet3中 匹配Sheet1的A列和Sheet2的A列并处理空内容
java·前端·excel