本文原文链接:https://blog.csdn.net/xzk9381/article/details/114872726
1. MySQL 5.7 线程阻塞的解决办法
1.1 问题说明
在数据库中执行语句报错: ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。
1.2 解决办法
- 查看当前数据库中的线程
show full processlist;
- 如果没有看到正在执行的慢sql记录线程,再查看 innodb的事务表INNODB_TRX,看下里面是否有正在锁定的事务线程,看看trx_mysql_thread_id是否在show full processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit 或者 rollback而是卡住了,我们需要手动kill掉,例如kill 32735
2. MySQL 5.7远程连接数据库时速度慢的解决办法
2.1 问题说明
使用mysql命令远程访问数据库,输入密码后需要等待5s-10s才可完成连接,导致后台服务抛出异常。
2.2 问题原因
每次访问数据库,mysql就会试图去解析来访问的机器的domain name,如果这时无法解析,等一段时间会失败,数据才能被取过来。
2.3 解决办法
在mysql配置文件中[mysqld]下面添加skip-name-resolve配置项来禁止解析域名,重启数据库即可生效
3. MySQL 5.7 二进制安装报错
3.1 问题说明
在centos6.8(最小化安装)中使用二进制安装包安装MySQL 5.7报错:
error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
3.2 解决办法
CentOS最小化安装时默认不安装libaio库,需要手动进行安装
yum install libaio-devel
4. MySQL 5.7中使用group concat函数数据被截断问题的解决方法
4.1 问题说明
调用GROUP_CONCAT函数进行查询时,查询没有停止且没有返回任何数据(也有一种情况是查询出来的数据被截断了,最长长度不超过1024字节)
4.2 问题原因
该问题的原因是由于官方给出的默认group_concat_max_len配置为1024,这个配置会限制GROUP_CONCAT数据的长度。可以使用如下命令查询:
mysql> show variables like 'group_concat_max_len';
+----------------------+--------+
| Variable_name | Value |
+----------------------+--------+
| group_concat_max_len | 1024 |
+----------------------+--------+
1 row in set (0.05 sec)
# 官方手册对该配置的定义是:The maximum permitted result length in bytes for the GROUP_CONCAT() function
4.3 解决办法
可以将group_concat_max_len调整到最大值18446744073709551615(或根据业务实际返回的最大长度进行设置)
- 修改MySQL的配置文件,在[mysqld]下面添加group_concat_max_len = 18446744073709551615(永久生效)
- 在控制台中进行设置(临时生效)
SET GLOBAL group_concat_max_len=18446744073709551615;
SET SESSION group_concat_max_len=18446744073709551615;
5. MySQL 报 ERROR: Packet for query is too large (2034> 1024)
5.1 问题说明
数据存储的时候报错:
ERROR: Packet for query is too large (2034> 1024). You can change this value on the server by setting the max_allowed_packet’ variable.
5.2 解决办法
- 使用如下命令查看当前数据库中的max_allowed_packet设置
mysql> show variables like '%max_allowed_packet%';
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| max_allowed_packet | 1024 |
| slave_max_allowed_packet | 1073741824 |
+--------------------------+------------+
2 rows in set (0.00 sec)
# 这里显示max_allowed_packet的大小只有1M
- 在my.cnf配置文件[mysqld]中添加或修改max_allowed_packet=128M,重启mysql即可生效。如果过一段时间查询max_allowed_packet的值又恢复为1024,则需要查询当前服务器的内存是否不足,这会导致MySQL自动重新设置参数为1024,预留出足够的内存即可解决该问题。
6. MySQL 5.7报错Waiting for table metadata lock的解决办法
6.1 问题说明
在MySQL5.7中执行alt table等DDL操作时,操作被阻塞无法执行,使用 show processlist查看发现对该表的alt table操作显示Waiting for table metadata lock。
6.2 问题原因
在MySQL5.7中执行alt table等DDL操作时,如果该表中有未提交的事务则会出现 Waiting for table metadata lock状态
6.3 解决办法
- 使用如下命令从information_schema.innodb_trx 查看未提交事务, 一般只要kill掉这些线程,DDL操作就不会Waiting for table metadata lock
select trx_state, trx_started, trx_mysql_thread_id, trx_query from information_schema.innodb_trx \G
# 字段说明:
# trx_state: 事务状态,一般为RUNNING
# trx_started: 事务执行的起始时间,若时间较长,则要分析该事务是否合理
# trx_mysql_thread_id: MySQL的线程ID,用于kill
# trx_query: 事务中的sql
- 调整锁超时阈值。lock_wait_timeout 表示获取metadata lock的超时(单位为秒),允许的值范围为1到31536000(1年)。 默认值为31536000,将其调整为30分钟
set session lock_wait_timeout = 1800;
set global lock_wait_timeout = 1800;
本文原文链接:https://blog.csdn.net/xzk9381/article/details/114872726
7. MySQL报错ERROR 1418 (HY000)的解决办法
7.1 问题说明
MySQL开启bin-log后,调用存储过程或者函数以及触发器时会出现错误号为1418的错误:
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)
7.2 问题原因
因为CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE,ALTER FUNCTION,CALL, DROP PROCEDURE, DROP FUNCTION等语句都会被写进二进制日志,然后在从服务器上执行。但是,一个执行更新的不确定子程序(存储过程、函数、触发器)是不可重复的,在从服务器上执行(相对与主服务器是重复执行)可能会造成恢复的数据与原始数据不同,从服务器不同于主服务器的情况。
为了解决这个问题,MySQL强制要求在主服务器上,除非子程序被声明为确定性的或者不更改数据,否则创建或者替换子程序将被拒绝。这意味着当创建一个子程序的时候,必须要么声明它是确定性的,要么它不改变数据。
声明方式有两种:
- 声明是否是确定性的: DETERMINISTIC和NOT DETERMINISTIC指出一个子程序是否对给定的输入总是产生同样的结果。如果没有给定任一特征,默认是NOT DETERMINISTIC,所以必须明确指定DETERMINISTIC来声明一个子程序是确定性的。这里要说明的是:使用NOW() 函数(或它的同义)或者RAND() 函数不会使一个子程序变成非确定性的。对NOW()而言,二进制日志包括时间戳并会被正确的执行。RAND()只要在一个子程序内被调用一次也可以被正确的复制。所以,可以认为时间戳和随机数种子是子程序的确定性输入,它们在主服务器和从服务器上是一样的。
- 声明是否会改变数据:CONTAINS SQL, NO SQL, READS SQL DATA, MODIFIES SQL用来指出子程序是读还是写数据的。
无论NO SQL还是READS SQL DATA都指出,子程序没有改变数据,但是必须明确地指定其中一个,因为如果任何指定,默认的指定是CONTAINS SQL。
也就是说,在开启bin-log的情况下,必须指定创建的函数是否是如下几种类型:
- DETERMINISTIC:不确定的
- NO SQL:没有SQl语句,当然也不会修改数据
- READS SQL DATA:只是读取数据,当然也不会修改数据
- MODIFIES SQL DATA:要修改数据
- CONTAINS SQL:包含了SQL语句
默认情况下,如果允许CREATE PROCEDURE 或CREATE FUNCTION 语句被接受,就必须明确地指定DETERMINISTIC 或 NO SQL与READS SQL DATA 中的一个,否则就会产生1418错误。
7.3 解决办法
解决办法有两种:
- 创建子程序(存储过程、函数、触发器)时,声明为DETERMINISTIC或NO SQL与READS SQL DATA中的一个
CREATE DEFINER = CURRENT_USER PROCEDURE `NewProc`()
DETERMINISTIC
BEGIN
#Routine body goes here...
END;
- 信任子程序的创建者,禁止创建、修改子程序时对SUPER权限的要求,设置log_bin_trust_routine_creators=1
# 方法1,在mysql控制台中直接修改(临时生效)
SET GLOBAL log_bin_trust_function_creators = 1;
# 方法二,在MySQL启动时,加上--log-bin-trust-function-creators选项,参数设置为1
# 方法三,在my.cnf配置文件[mysqld]中添加如下内容,重启后生效
log-bin-trust-function-creators = 1
8. MySQL报错Communications link failure的解决办法
8.1 问题说明
tomcat进程连接数据库后报错:
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.)
8.2 问题原因
根据报错信息可以判断连接池中的连接Connection失效,即超过了有效时间wait_timeout。登录mysql后查看wait_timeout有效时间为28800,即8小时。
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set (0.01 sec)
8.3 解决办法
修改wait_timeout属性,调大数值为31536000(365天,linux最大值为一年)
# 在my.cnf配置文件中,[mysqlId]下添加wati_timeout、interactive_timeout属性,重启mysql
wait_timeout = 31536000
interactive_timeout = 31536000
9. 数据库连接时报错ERROR 1129 (00000)…is blocked because of many connection errors
9.1 问题说明
连接数据库时报错:
ERROR 1129 (00000): #HY000Host ‘192.168.31.242’ is blocked because of many connection errors; unblock with ‘mysqladmin flush-hosts’
9.2 问题原因
连接错误次数过多(尝试连接次数过多),超出配置文件中max_connection_errors配置项次数。
9.3 解决办法
- 在mysql服务器上输入如下命令来清除缓存
mysqladmin flush-hosts -uroot -p
- 在my.cnf配置文件[mysqld]中添加如下配置并重启数据库
max_connection_errors = 1000
10. MySQL5.7查询时报错:[Err] 1055 - Expression #1 of SELECT list is not in GROUP BY clause…this is incompatible with sql_mode=only_full_group_by
10.1 问题说明
将数据库从5.5版本迁移至5.7版本,执行查询语句时详细报错信息如下:
[Err] 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘cdxc.a.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
10.2 问题原因
MySQL5.7中,sql_mode默认设置了ONLY_FULL_GROUP_BY,使用这个就是使用和oracle一样的group 规则, select的列都要在group中,或者本身是聚合列(SUM,AVG,MAX,MIN) 才行。
10.3 解决办法
- 查询当前sql_mode的配置
mysql> select @@sql_mode;
+--------------------------------+
| @@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 |
+--------------------------------+
1 row in set (0.04 sec)
- 将配置中的ONLY_FULL_GROUP_BY去掉,将其余配置写入配置文件中的[mysqld]下面,并重启数据库服务,格式如下
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
- 或者直接在数据库中输入如下内容(需要退出数据库重新进入才能生效)
set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
11. MySQL5.7报错Incorrect datetime value: ‘0000-00-00 00:00:00’ for column
11.1 问题说明
mysql5.7执行sql语句导入时报错:mysql 5.7 Error : Incorrect datetime value: ‘0000-00-00 00:00:00’ for column xxx
11.2 问题原因
mysql从5.7版本开始,datetime不再支持’0000-00-00 00:00:00’ 的格式。
11.3 解决办法
- 将即将导入的sql语句中包含’0000-00-00 00:00:00’ 的替换为’1970-01-01 00:00:01’即可
sed -i 's/0000-00-00 00:00:00/1970-01-01 00:00:01/g' test.sql
- 修改sql_mode,将sql_mode中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除即可
# 查询sql_mode
select @@sql_mode;
# 在控制台中重新设置sql_mode
set global sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,
NO_ENGINE_SUBSTITUTION';
# 在配置文件[mysqld]中添加如下内容重新设置sql_mode
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
12. MySQL 5.7 报错:Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage; increase this mysqld variable and try again
12.1 问题说明
在对 MySQL 批量更新或删除等大事务时,会导致报如下错误:
Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage; increase this mysqld variable and try again
12.2 问题原因
这是由于更新和删除的大事务会写入大量binlog,可能会造成binlog cache过小而导致执行失败。也会遇到主库执行成功而从库不同步的情况。这是因为虽然主从的max_binlog_cache_size参数虽然设置的一样,但是实际使用的binlog cache不一定相同,从而导致binlog cache因为过小而主从复制中断。
12.3 解决办法
首先查看 MySQL 中当前设置的 max_binlog_cache_size 大小:
mysql> show variables like 'max_binlog_cache_size';
+-----------------------+-----------+
| Variable_name | Value |
+-----------------------+-----------+
| max_binlog_cache_size | 134217728 |
+-----------------------+-----------+
查看到该参数设置的值为 134217728,也就是 128M ( 128 * 1024 * 1024 ),将其设置为合适的大小,例如 256M:
# 在控制台中设置
mysql> set global max_binlog_cache_size=268435456;
Query OK, 0 rows affected (0.05 sec)
# 在配置文件 [mysqld] 中添加如下内容进行设置
max_binlog_cache_size = 256M
本文原文链接:https://blog.csdn.net/xzk9381/article/details/114872726