Mysql常见故障汇总与优化!! 从大佬手中偷学整理!!

案例前置知识点

要学习如何优化,首先要对 MySQL 的逻辑架构深入的了解。图 8.1 是 MySQL 逻辑架 构图,可以让我们更清晰了解 MySQL 的运行原理
在这里插入图片描述
最上层是一些客户端和连接服务,包含本地 sock 通信和大多数基于客户端/ 服务器端工具实现的 TCP/IP 通信。主要完成一些连接处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上 可以实现基于 SSL 的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作 权限

第二层架构主要完成大多数的核心服务功能,如 SQL 接口、缓存的查询、SQL 的分析 和优化以及部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如过程、函数等。 在该层上服务器会解析查询并创建相应的内部解析树,并对其完成相应的优化,如确定查询 表的顺序,是否利用索引等,最后生成相应的执行操作。如果是 select 语句,服务器还会 查询内部的缓存。如果缓存空间足够大,这样在解决大量读操作的环境中能够很好的提升系 统的性能。

存储引擎层,存储引擎真正的负责了 MySQL 中数据的存储和提取,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,可以根据自己的实际需要进行选取

数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的 交互

MySQL 单实例故障排查

(1) 故障现象

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysql/mysql.sock' (2)

问题分析:以上这种情况一般都是数据库未启动或者数据库端口被防火墙拦截导致。 解决方法:启动数据库或者防火墙开放数据库监听端口

(2)故障现象

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

问题分析:密码不正确或者没有权限访问。 解决方法: 1 修改 my.cnf 主配置文件,在[mysqld]下添加 skip-grant-tables,重启数据库。最后 修改密码命令如下

mysql>use mysql; 
mysql> update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; 
mysql> flush privileges;

再删除刚刚添加的 skip-grant-tables 参数,重启数据库,使用新密码即可登录。

(3)故障现象
在使用远程连接数据库时偶尔会发生远程连接数据库很慢的问题。

问题分析:如果 MySQL 主机查询 DNS 很慢或是有很多客户端主机时会导致连接很慢. 由于开发机器是不能够连接外网的,在进行 MySQL 连接时,DNS 解析是不可能完成的, 从而也就明白了为什么连接那么慢了。

解决方法:修改 my.cnf 主配置文件,在[mysqld]下添加 skip-name-resolve,重启数据 库可以解决。注意在以后授权里面不能再使用主机名授权

(4)故障现象

Can't open file: 'xxx_forums.MYI'. (errno: 145)

问题分析:
服务器非正常关机,数据库所在空间已满,或一些其它未知的原因,对数据库表造成了损坏。
可能是操作系统下直接将数据库文件拷贝移动,会因为文件的属组问题而产生这个 错误。

解决方法: 以下两种修复方式在执行前一定要备份数据库
可以使用下面的两种方式修复数据表(第一种方法仅适合独立主机用户):

1.使用 MySQL 自带的专门用户数据表检查和修复工具 myisamchk。一般 情况下只有在命令行下面才能运行 myisamchk 命令。常用的修复命令为:
myisamchk -r 数据文件目录/数据表名.MYI;

通过 phpMyAdmin 修复, phpMyAdmin 带有修复数据表的功能,进入 到某一个表中后,点击“操作”,在下方的“表维护”中点击“修复表”即可

2.修改文件的属组(仅适合独立主机用户):
复制数据库文件的过程中没有将数据库文件设置为 MySQL 运行的帐号 可读写(一般适用于 Linux 和 FreeBSD 用户)

(5)故障现象
ERROR 1129 (HY000): Host ‘xxx.xxx.xxx.xxx’ is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts

问题分析:由于 mysql 数据库的参数:max_connect_errors,其默认值是 10。当大量 (max_connect_errors)的主机去连接 MySQL,总连接请求超过了 10 次,新的连接就再也无 法连接上 MySQL 服务。同一个 ip 在短时间内产生太多中断的数据库连接而导致的阻塞(超过 mysql 数据库 max_connection_errors 的最大值)

#解决方法:
#使用 mysqladmin flush-hosts 命令清除缓存,命令执行方法如下:

1.mysqladmin -uroot -p -h 192.168.241.48 flush-hosts 
Enter password:

2.修改 mysql 配置文件,在[mysqld]下面添加 max_connect_errors=1000,然后重 启 MySQL

(6)故障现象
客户端报 Too many connections。
问题分析:连接数超出 Mysql 的最大连接数限制。

#解决方法:
1.在 my.cnf 配置文件里面增大连接数,然后重启 MySQL 服务
max_connections = 10000

2.临时修改最大连接数,重启后不生效。需要在 my.cnf 里面修改配置文件,下次重启生效
set GLOBAL max_connections=10000;

(7)故障现象

Warning: World-writable config file '/etc/my.cnf' is ignored
 ERROR! MySQL is running but PID file could not be found

问题分析:MySQL 的配置文件/etc/my.cnf 权限不对。

#解决方法:
chmod 644 /et/my.cnf

(8)故障现象

InnoDB: Error: page 14178 log sequence number 29455369832
InnoDB: is in the future! Current system log sequence number 29455369832

问题分析:innodb 数据文件损坏

#解决方法:
#修改 my.cnf 配置文件,在[mysqld]下添加 innodb_force_recovery=4, 
启动数据库后备份数据文件,然后去掉该参数,利用备份文件恢复数据

MySQL 主从故障排查

(1)故障现象
从库的 Slave_IO_Running 为 NO

问题分析:主库和从库的 server-id 值一样。

解决方法:修改从库的 server-id 的值,修改为和主库不一样。修改完后重启,再同步 即可

(2)故障现象 2
从库的 Slave_IO_Running 为 NO

问题分析:造成从库线程为 NO 的原因会有很多,主要原因是主键冲突或者主库删除或 更新数据,从库找不到记录,数据被修改导致。通常状态码报错有 1007、1032、1062、1452 等。

#解决方法一:
mysql> stop slave; 
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1; 
mysql> start slave;

解决方法二:
设置用户权限,设置从库只读权限
set global read_only=true;

(3)故障现象

Error initializing relay log position: I/O error reading the header from the binary log

分析问题:从库的中继日志 relay-bin 损坏

#解决方法:
手工修复,重新找到同步的 binlog 和 pos 点,然后重新同步即可

mysql>CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.xxx',MASTER_LOG_POS=xxx;

MySQL 优化

硬件方面

说到服务器硬件,最主要的无非 CPU、内存、磁盘三大关键因素

(1)关于 CPU
CPU 对于 MySQL 应用,推荐使用 S.M.P.架构的多路对称 CPU。例如:可以使用两颗
Intel Xeon 3.6GHz 的 CPU。现在比较推荐用 4U 的服务器来专门做数据库服务器,不仅仅
是针对于 MySQL

(2)关于内存
物理内存对于一台使用 MySQL 的 Database Server 来说,服务器内存建议不要小于
2GB,推荐使用 4GB 以上的物理内存。不过内存对于现在的服务器而言可以说是一个可以
忽略的问题,工作中遇到了高端服务器基本上内存都超过了 32G

(3)关于磁盘
磁盘寻道能力(磁盘 I/O)。以目前市场上普遍高转速 SAS 硬盘(15000 转/秒)为例,
这种硬盘理论上每秒寻道 15000 次,这是物理特性决定的,没有办法改变。 MySQL 每秒
钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以通常认为磁盘 I/O 是制
约 MySQL 性能的最大因素之一,通常是使用 RAID-0+1 磁盘阵列,注意不要尝试使用
RAID-5,MySQL 在 RAID-5 磁盘阵列上的效率并不高。如果不考虑硬件的投入成本,也可
以考虑固态(SSD)硬盘专门作为数据库服务器使用。数据库的读写性能肯定会提高很多

MySQL 配置文件

通常默认的 my.cnf 配置文件无法发挥出 MySQL 最高的性能,所以需要根据不同的硬 件进行优化,配置文件的优化也是重点。下面是物理内存为 32G 的数据库优化参数,具体 从全局、二进制日志、主从、innodb、myisam 几个方面优化,仅供参考。

(1)default-time-zone=+8:00
默认 MySQL 使用的是系统时区,修改为北京时间,也就是所说的东八区
(2)interactive_timeout = 120
服务器关闭交互式连接前等待活动的秒数。
(3)wait_timeout = 120
服务器关闭非交互连接之前等待活动的秒数
(4)open_files_limit = 10240
MySQL 服务器打开文件句柄数限制。
(5)group_concat_max_len = 102400
MySQL 默认的拼接最大长度为 1024 个字节,由于 1024 个字节会出现不够用的情况, 根据实际情况进行修改
(6)user=mysql
使用 mysql 用户运行。
(7)character-set-server=utf8、init_connect=‘SET NAMES utf8’
设置字符集为 utf8
(8)back_log = 600
在 MySQL 暂时停止响应新请求之前,短时间内的多少个请求可以被存在堆栈中。如果 系统在短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的 TCP/IP 连接的 监听队列的大小。默认值 50
(9)max_connections = 5000
MySQL 允许最大的进程连接数,如果经常出现 Too Many Connections 的错误提示, 则需要增大此值。
(10)max_connect_errors = 6000
设置每个主机的连接请求异常中断的最大次数。当超过该次数,MySQL 服务器将禁止 host 的连接请求,直到 MySQL 服务器重启或通过 flush hosts 命令清空此 host 的相关信息
(12)table_open_cache = 2048
指定表高速缓存的大小。每当 MySQL 访问一个表时,如果在表缓冲区中还有空间,该 表就被打开并放入其中,这样可以更快地访问表内容
(13)max_heap_table_size = 256M
这个变量定义了用户可以创建的内存表(memory table)的大小。这个值用来计算内存表 的最大行数值。这个变量支持动态改变,即 set @max_heap_table_size=#。
但是对于已经 存在的内存表就没有什么用了,除非这个表被重新创建(create table)、修改(alter table)或者 truncate table。服务重启也会设置已经存在的内存表为全局 max_heap_table_size 的值
(14)external-locking = false
使用 skip-external-lockingMySQL 选项以避免外部锁定。该选项默认开启
(15)max_allowed_packet = 32M
设置在网络传输中一次消息传输量的最大值。系统默认值为 1MB,最大值是 1GB,必 须设置 1024 的倍数
(16)sort_buffer_size = 512M
Sort_Buffer_Size 是一个 connection 级参数,在每个 connection(session)第一次需 要使用这个 buffer 的时候,一次性分配设置的内存。Sort_Buffer_Size 并不是越大越好,由 于是 connection 级的参数,过大的设置+高并发可能会耗尽系统内存资源。
(17)join_buffer_size = 8M
用于表间关联缓存的大小,和 sort_buffer_size 一样,该参数对应的分配内存也是每个 连接独享
(18)default-storage-engine = innodb
默认引擎,现在一般都是 innodb 引擎表居多
(20)thread_stack = 192K
设置 MySQL 每个线程的堆栈大小,默认值足够大,可满足普通操作。可设置范围为 128K 至 4GB,默认为 192KB
(21)transaction_isolation = READ-COMMITTED
设定默认的事务隔离级别,READCOMMITTEE 是读已提交。
(22)key_buffer_size = 1024M
指定用于索引的缓冲区大小,增加它可以得到更好的索引处理性能。
(23)bulk_insert_buffer_size = 64M
批量插入数据缓存大小,可以有效提高插入效率,默认为 8M
(24)skip-name-resolve
禁止域名解析,包括主机名.所以授权的时候要使用 IP 地址。

关于 MySQL 二进制日志文件

(1)log-bin=mysql-bin
打开 MySQL 二进制功能。
(2)expire_logs_days = 7
二进制日志只留存最近 7 天,不用人工手动删除
(3)slow_query_log
打开慢查询日志
(4)slow_query_log_file=slow.log
慢查询日志文件位置
(5)long_query_time = 2
记录超过 2 秒的 SQL 查询

关于引擎是 innodb 的优化如下:

(1)innodb_additional_mem_pool_size = 64M
这个参数用来设置 InnoDB 存储的数据目录信息和其它内部数据结构的内存池大小,类 似于 Oracle 的 library cache。这不是一个强制参数,可以被突破
(2)innodb_file_io_threads = 4
文件 IO 的线程数,一般为 4,但是在 Windows 下,可以设置得较大
(3)innodb_thread_concurrency = 8
服务器有几个 CPU 就设置为几,建议用默认设置,一般为 8
(4)innodb_write_io_threads = 8
InnoDB 使用后台线程处理数据页上写 I/O(输入输出)请求的数量。一般设置为 CPU 核数,比如 CPU 是 2 颗 8 核的,可以设置为 8
(5)innodb_log_files_in_group = 3
#为提高性能,MySQL 可以以循环方式将日志文件写到多个文件
(6)innodb_file_per_table = 1
独享表空间(关闭)
(7)innodb_open_files = 8192
innodb 打开文件句柄数

关于引擎是 myisam 的优化

(1)myisam_sort_buffer_size = 128M
MyISAM 表发生变化时重新排序所需的缓冲大小
(2)myisam_max_sort_file_size = 10G
MySQL 重建索引时所允许的最大临时文件的大小(当 REPAIR,ALTERTABLE 或者LOADDATAINFILE)。
如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
(3)myisam_repair_threads = 1
如果一个表拥有超过一个索引,MyISAM 可以通过并行排序使用超过一个线程去修复
这对于拥有多个 CPU 以及大量内存情况的用户是一个很好的选择
(4)myisam_recover
自动检查和修复没有适当关闭的 MyISAM 表

猜你喜欢

转载自blog.csdn.net/weixin_48190891/article/details/108713072