项目的mysql数据库版本由5.1.x更换为5.7.x后出现了一些问题,现将其中的一些问题记录一下
其中大部分问题都需要修改数据库的配置文件进行解决,所以先将如何找到mysql配置文件记录下来,如下
1. 执行 which mysql 命令,通过此命令找到mysql的安装位置
比如:/usr/bin/mysql
2. 执行 /usr/bin/mysql --verbose --help | grep -A 1 'Default options' 命令
(其中“/usr/bin/mysql”为上一步中找到的路径),结果类似如下信息:
Default options are read from the following files in the given order:
/etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf
** 这个信息的意思是: 服务器首先读取的是/etc/mysql/my.cnf文件,如果前一个文件不存在
则继续读/etc/my.cnf文件,如若还不存在便会去读~/.my.cnf文件
3. 根据上边的提示,找到对应的配置文件,执行 vim /***/my.cnf 即可进入修改
问题1:项目启动后,一些sql语句报如下错误:
### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column
'xxx.db.xxxxx' which is not functionally dependent on columns in GROUP BY
clause; this is incompatible with sql_mode=only_full_group_by
错误原因为:
MySQL 5.7.5及以上功能依赖检测功能。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引用在GROUP BY子句中既未命名的非集合列,也不在功能上依赖于它们。
解决办法:
① 执行查询 (可在mysql命令行中执行或者通过navcat等工具执行)
select @@global.sql_mode
结果如下:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
② 修改mysql配置文件,在配置文件中增加如下配置:
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
③ 修改后保存退出,然后重启mysql服务即可
service mysql restart
问题二:格式化后的时间比当前时间晚8个小时
问题描述:
代码中用了System.currentTimeMillis()这种方法,前端格式化时间后,显示的时间比当前时间晚8个小时
错误原因:
数据库版本不同,默认使用的时区不同导致的
解决办法:
① 执行查询,查看当前数据库使用的时区:
SHOW VARIABLES LIKE ‘%time_zone%’;
类似结果如下:
② 执行设置,将mysql全局时区修改为北京时间,即我们所在的东8区:
set global time_zone = ‘+8:00’; ##设置
flush privileges; ##使设置生效
注意 此方法修改只是临时起作用,数据库服务重启后会失效
可通过修改数据库配置使设置永久生效,修改数据库配置文件,在配置文件中添加如下内容即可:
default-time_zone = ‘+8:00’
修改后重启数据库服务,时间问题解决
问题三:启动服务时报由于许多连接错误而被阻止
问题描述:
启动后台服务,日志中报如下错误:
ERROR c.a.d.p.DruidDataSource - [run,2471] - create connection SQLException,
url: jdbc:mysql://192.168.x.xxx:3306/xxx-db?useUnicode=true&characterEncoding=utf8
&zeroDateTimeBehavior=convertToNull&useSSL=false, errorCode 1129, state HY000
java.sql.SQLException: null,
message from server: "Host '192.168.x.xxx' is blocked because of many connection errors;
unblock with 'mysqladmin flush-hosts'"
错误原因:
同一个ip在短时间内产生太多(超过mysql数据库max_connect_errors的最大值)中断的数据库连接而导致的阻塞
解决办法:
① 最直接快速的办法是,执行以下命令将max_connect_errors的计数器值清零:
flush hosts ##执行此命令后即可解决以上问题
② 可查看当前数据库max_connect_errors的值,一般默认值是10,如果过小,可以将其设置大:
show variables like ‘max_connect_errors’; ##查询max_connect_errors值
set global max_connect_errors = 100; ##设置 max_connect_errors值(100可以是任意整数,默认值为10)
问题四:启动服务时报某数据库表找不到(区分了表名的大小写)
问题描述:
启动后台服务,日志中报如下错误:
ERROR o.s.s.q.LocalDataSourceJobStore - [manage,3926] - ClusterManager:
Error managing cluster: Failure obtaining db row lock: Table 'xxx-db.AAA_TAB'
doesn't exist
org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock:
Table 'xxx-db.AAA_TAB' doesn't exist
其中xxx-db.AAA_TAB是你对应数据库中的某个表,不过这个表名实际为小写(xxx-db.aaa_tab)
错误原因:
数据库在磁盘中存储的表名为小写,比较的时候区分了大小写
解决办法:
① 先查看当前的读取策略:
SHOW VARIABLES LIKE ‘%case%’; ##执行此查询,根据结果进行查看
lower_case_table_names = 1 表名存储在磁盘是小写的,但是比较的时候不区分大小写
lower_case_table_names = 0 表名存储在磁盘可以是大小写,但是比较的时候区分大小写
lower_case_table_names = 2 表名存储在磁盘可以是大小写,但是比较的时候是小写的
② 修改数据库配置文件,在配置文件中添加 lower_case_table_names=1的配置即可:
lower_case_table_names=1
其他问题待发现后更新…