前言

我们在日常使用ai过程中,需要部署服务器的时候会通过ai给的指令去加快部署进度,但是部署完以后会出现一些小问题,作者今天部署了一套mysql(8.0),部署完以后发现数据库中有表名报错,检查表名后发现没有问题,修改表名后仍然会产生表名称报错,所以可能是由于代码不规范导致的代码中存在表名大小写共存现象,这种问题平时不会影响,但是如果数据库大小写不敏感就会导致报错。

本文核心:

本次后端项目部署过程中,因MySQL配置不当引发了大小写敏感导致程序报错、配置文件编辑权限、服务启动失败、远程连接权限、root密码重置、JDBC连接池初始化失败等一系列连锁问题,均为MySQL部署与远程连接的高频问题。本文按问题排查顺序,梳理每个问题的现象、根因、解决方法,并提炼MySQL 8.0+的核心避坑点,为同类场景排查提供参考。

本次环境:

Linux服务器 + MySQL 8.0.44 + Spring Boot项目(Druid连接池) + Navicat远程连接

## 一、核心问题1:MySQL大小写不区分,导致程序SQL执行报错

### 问题现象

项目执行SQL语句时,因表名/列名大小写不匹配触发报错,MySQL未按程序中的大小写规则识别表名。

### 根因分析

MySQL的大小写敏感由lower_case_table_names参数控制,Linux默认0(区分大小写)、Windows默认1(不区分);且MySQL 8.0+会将该参数值写入数据字典,初始化后直接修改配置值会导致与数据字典记录不一致,进而引发服务启动失败。

### 解决方法

\1. 编辑MySQL系统配置文件/etc/my.cnf,在[mysqld]模块添加/修改参数:

```ini

  [mysqld]

  lower_case_table_names=0 # 区分大小写(0区分大小写,1 不区分大小写)

  datadir=/var/lib/mysql

  socket=/var/lib/mysql/mysql.sock

```

\2. 注意:修改后需保证参数值与数据字典一致,否则直接重启会失败(后续问题2的核心诱因)。

## 二、衍生问题1:vim编辑my.cnf提示只读错误(E45)

### 问题现象

执行vim /etc/my.cnf修改配置后,保存时提示E45: 'readonly' option is set (add ! to override)

### 根因分析

/etc/my.cnf是MySQL系统级配置文件,默认仅root用户拥有写入权限,普通用户打开后为只读模式。

### 解决方法

两种方式任选,推荐方式1(从根源解决)

\1. 提权打开配置文件:sudo vim /etc/my.cnf,修改后直接:wq保存即可;

\2. 强制保存:若已用普通vim打开,按Esc进入命令模式,执行:w!强制覆盖只读限制。

## 三、衍生问题2:修改参数后,重启mysqld.service失败(exit-code)

### 问题现象

执行systemctl restart mysqld提示失败,日志仅显示Job for mysqld.service failed because the control process exited with error codejournalctl -xe | grep mysqld无具体错误原因。

### 根因分析

*MySQL 8.0+核心特性:lower_case_table_names参数会写入数据字典初始化后不可直接修改配置值,若配置文件的参数值与数据字典中记录的旧值不一致,会导致数据字典初始化失败,服务启动失败。
或者说由于 MySQL 8.0+ 会将 lower_case_table_names 的值写入数据字典,一旦初始化后就无法直接修改,必须重新初始化数据目录

### 解决方法

\1. 定位根因:查看MySQL专属错误日志(journalctl无具体信息,需看MySQL自身日志):

```bash

  tail -100 /var/log/mysqld.log *# 核心日志路径*

```

日志中会明确提示Different lower_case_table_names settings for server ('X') and data dictionary ('Y')

\2. 快速恢复:将/etc/my.cnf中的lower_case_table_names改回与数据字典一致的值,执行systemctl restart mysqld即可正常启动;说明由于 MySQL 8.0+ 会将 lower_case_table_names 的值写入数据字典,一旦初始化后就无法直接修改,必须重新初始化数据目录;

如果你确实需要设置 lower_case_table_names=1(不区分大小写)

从你提供的MySQL错误日志中,能明确看到启动失败的核心原因Different lower_case_table_names settings for server ('1') and data dictionary ('0'),也就是你配置文件中设置的 lower_case_table_names=1,但MySQL数据字典中记录的旧参数值是0,两者不一致导致数据字典初始化失败,最终服务启动失败。

解决步骤(优先恢复服务)

第一步:修改配置文件,让参数与数据字典一致

数据字典中记录的是0,所以需要把配置文件的 lower_case_table_names 改回0,匹配数据字典的值:

# 编辑MySQL配置文件
vim /etc/my.cnf

找到 [mysqld] 模块下的 lower_case_table_names 参数,修改为:

[mysqld]
lower_case_table_names=0  # 改回0,和数据字典一致
# 保留其他原有配置(如datadir、socket等)
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

保存并退出vim(按Esc,输入 :wq)。

第二步:重启MySQL服务
systemctl restart mysqld

此时服务应该能正常启动,因为参数和数据字典的值匹配了。

第三步:验证服务状态
# 查看服务状态
systemctl status mysqld.service
# 若显示 "active (running)" 则启动成功

# 登录MySQL验证参数
mysql -u root -p
show variables like 'lower_case_table_names';
# 输出的Value列应该是0,和配置一致

如果你确实需要设置 lower_case_table_names=1(不区分大小写)

由于MySQL 8.0+ 会将 lower_case_table_names 的值写入数据字典,一旦初始化后就无法直接修改,必须重新初始化数据目录(需先备份数据!),步骤如下:

1. 备份所有数据库(重要!避免数据丢失)
# 导出所有数据库到备份文件
mysqldump -u root -p --all-databases > /root/mysql_full_backup.sql

输入MySQL root密码后等待备份完成。

2. 停止MySQL服务
systemctl stop mysqld
3. 清空数据目录(默认/var/lib/mysql)
# 先确认数据目录路径(避免删错)
grep datadir /etc/my.cnf
# 清空数据目录(仅在备份完成后执行!)
rm -rf /var/lib/mysql/*
4. 修改配置文件为 lower_case_table_names=1
vim /etc/my.cnf

修改参数:

[mysqld]
lower_case_table_names=1  # 设置为1(不区分大小写)
5. 重新初始化MySQL
# MySQL 8.0+ 初始化命令(生成空的数据字典,记录lower_case_table_names=1)
mysqld --initialize-insecure --user=mysql

--initialize-insecure 表示初始化后root用户无密码,方便后续操作。

6. 启动MySQL并重置root密码
# 启动服务
systemctl start mysqld

# 免密码登录MySQL
mysql -u root --skip-password

# 重置root密码(替换为你的新密码)
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的root密码';
FLUSH PRIVILEGES;
exit;
7. 重新导入备份的数据库
# 导入之前备份的数据
mysql -u root -p < /root/mysql_full_backup.sql

导入完成后,你的数据库会恢复,且MySQL会以 lower_case_table_names=1 运行(不区分大小写)。

总结

  1. 启动失败的核心原因:lower_case_table_names 配置值(1)与数据字典中记录的旧值(0)不一致,MySQL 8.0+ 严格校验该参数。
  2. 快速恢复:将配置文件的参数改回0,与数据字典匹配,即可重启成功。
  3. 若需设置为1:必须先备份数据、清空数据目录、重新初始化MySQL,才能修改该参数(8.0+ 特性限制)。

## 四、衍生问题3:Navicat远程连接MySQL,提示1130权限错误

### 问题现象

Navicat连接报错1130 - Host 'XXX.XXX.XXX.XXX' is not allowed to connect to this MySQL server,远程IP无访问权限。

### 根因分析

\1. 数据库用户tmg_base仅配置了localhost本地访问权限,无远程IP访问权限;

\2. MySQL 8.0+语法变更:废弃了GRANT ... IDENTIFIED BY ...的“授权+设密码”合并语法,需拆分为创建/修改用户授权两个独立操作,直接执行合并语法会触发1064语法错误。

### 解决方法

MySQL 8.0+按以下步骤配置远程权限(需在MySQL服务器端执行):

\1. 登录MySQL:

mysql -u root -p;

\2. 检查用户现有权限:

SELECT user, host FROM mysql.user WHERE user = 'tmg_base'*;

\3. 创建/修改远程用户(指定host为%,代表所有IP,也可指定具体Navicat IP):

```sql

– 不存在则创建,存在则修改密码

  CREATE USER IF NOT EXISTS 'tmg_base'@'%' IDENTIFIED BY '密码';

```

\4. 单独授权(按需授权,最小权限原则推荐仅授权业务库):

```sql

  GRANT ALL PRIVILEGES ON tmg_base.* TO 'tmg_base'@'%'*; -- 仅授权tmg_base库

– 若需所有库权限:GRANT ALL PRIVILEGES ON . TO ‘tmg_base’@‘%’ WITH GRANT OPTION*;*

  FLUSH PRIVILEGES;

```

## 五、衍生问题4:MySQL root用户本地登录报错1045(Access denied)

### 问题现象

执行mysql -u root -p,输入密码后提示ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

### 根因分析

root密码错误或权限配置异常,无法通过常规方式登录。

### 解决方法

通过MySQL安全模式跳过权限验证,重置root密码(MySQL 8.0+适配):

\1. 停止MySQL服务:`

systemctl stop mysqld;

\2. 启动安全模式(跳过权限验证,禁止远程连接防风险):

```bash

  mysqld_safe --skip-grant-tables --skip-networking &

```

\3. 无密码登录MySQL:

mysql -u root;

\4. 刷新权限并修改密码:

```sql

  FLUSH PRIVILEGES;
  ALTER USER 'root'@'localhost' IDENTIFIED BY '新root密码';

```

\5. 停止安全模式进程,正常启动MySQL:

pkill -f mysqld_safe

  systemctl start mysqld

\6. 验证:mysql -u root -p输入新密码,正常登录即完成重置。

## 六、最终问题:Spring Boot Jar包启动,Druid连接池初始化失败

### 问题现象

启动Jar包时提示DruidDataSource init datasource error,核心报错java.sql.SQLNonTransientConnectionException: Could not create connection to database serverping通MySQL服务器IP,但JDBC无法建立连接

### 根因分析

ping通IP仅代表网络层可达,不代表3306端口可访问,核心诱因包含4点:

\1. MySQL绑定地址为127.0.0.1,仅监听本地,拒绝远程连接;

\2. 服务器防火墙/云安全组未放行3306端口;

\3. 远程用户tmg_base的密码/权限配置错误;

\4. JDBC URL缺少MySQL 8.0+必备的时区参数,导致连接时时区不匹配。

### 解决方法

按**「网络端口→MySQL配置→用户权限→JDBC参数」** 顺序排查,逐一验证:

#### 1. 检查MySQL绑定地址,确保监听所有IP

编辑/etc/my.cnf,在[mysqld]模块添加:

```ini

bind-address = 0.0.0.0 # 监听所有IP,允许远程连接

port = 3306 # 确认端口为3306

```

重启MySQL:systemctl restart mysqld,验证监听状态:

```bash

netstat -tnlp | grep 3306 # 输出需包含0.0.0.0:3306,而非仅127.0.0.1:3306

```

#### 2. 放行服务器3306端口(防火墙+云安全组)

```bash

# Linux防火墙放行3306端口(CentOS示例)

firewall-cmd --add-port=3306/tcp --permanent

firewall-cmd --reload

# 验证端口是否开放

firewall-cmd --query-port=3306/tcp

```

云服务器需额外配置安全组:在云控制台添加入站规则,放行3306端口(允许Jar包服务器IP访问,或临时允许所有IP)。

#### 3. 验证远程用户密码&权限

运行Jar包的服务器上,安装MySQL客户端并手动测试连接,排除程序代码问题:

```bash

# 安装客户端(CentOS)

yum install mysql -y

# 测试远程连接

mysql -u tmg_base -p’新密码’ -h MySQL服务器IP -P 3306 tmg_base

```

能正常登录→用户权限/密码无问题;登录失败→根据报错重新配置用户(如密码错误、host限制)。

#### 4. 修正JDBC URL,添加MySQL 8.0+必备参数

MySQL 8.0+连接时必须指定时区,否则会因时区不匹配导致连接失败,修改项目配置文件中的JDBC URL,新增serverTimezone=Asia/Shanghai等参数:

```yaml

url: jdbc:mysql://172.x.x.x:3306/xxxx?characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false

username: xxx

password:xxx

type: com.alibaba.druid.pool.DruidDataSource

```

## 七、核心避坑点(MySQL 8.0+专属,本次问题的核心坑)

\1. lower_case_table_names参数不可随意修改:8.0+会将该参数写入数据字典,初始化后直接修改配置值会导致服务启动失败,需与数据字典值一致;若需修改,必须先备份数据、清空数据目录,重新初始化MySQL。

\2. 权限操作语法变更:废弃GRANT ... IDENTIFIED BY ...合并语法,需拆分为创建/修改用户授权两步,且操作后需执行FLUSH PRIVILEGES

\3. JDBC连接必备参数:必须添加serverTimezone=Asia/Shanghai,否则会因时区不匹配触发连接失败。

\4. 远程连接的核心三要素:MySQL绑定地址为0.0.0.0 + 3306端口放行(防火墙+安全组) + 远程用户host%/指定IP。

\5. 日志排查优先级:MySQL服务启动失败时,journalctl无具体信息,需优先查看MySQL专属错误日志/var/log/mysqld.log,根因均在其中。

## 八、排查思路总结

本次系列问题均为配置类问题,排查遵循**「从日志入手、先本地后远程、先网络后配置」** 的核心思路:

\1. 所有服务启动/连接失败,先查专属日志(如MySQL的/var/log/mysqld.log、程序的启动日志),日志会明确标注根因,避免盲目排查;

\2. 远程连接问题,先验证本地连接(MySQL服务器端本地登录),本地正常则聚焦网络/权限配置;

\3. 网络连接问题,先ping通IP,再验证端口(telnet/nc命令),ping通≠端口通,端口放行是远程连接的基础;

\4. 配置文件修改,先提权再编辑(sudo),避免只读错误,且修改系统配置后需重启服务生效。

按以上思路,可快速定位MySQL部署与远程连接的绝大多数高频问题,提升排查效率。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐