新北市网站建设_网站建设公司_移动端适配_seo优化
2025/12/17 12:17:35 网站建设 项目流程

甄选推荐系统:

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 项目
  • 防患未然:三层防护确保不会复发

最后的建议

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

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


参考资料

  • MySQL 8.0.13 Release Notes
  • ShardingSphere 官方文档
  • MySQL Connector/J Configuration Properties
  • Spring Boot Actuator Health Indicators


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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询