mysql故障排查与环境优化

发布于:2025-05-21 ⋅ 阅读:(12) ⋅ 点赞:(0)

一、mysql运行原理
    mysql的运行分为三层
    客户端和连接服务
    
    核心服务功能(sql接口、缓存的查询、sql的分析和优化以及部分内置函数的执行等。)

    存储引擎层(负责mysql中数据的存储和提取。)
 

二、示例
1、实验环境
	单台mysql
	1主+1从
2、mysql单实例故障排查
现象1:
	ERROR 2002 (HY000):can't connect to local MySQL server through socket '/data/mysql/mysql.sock'(2)

分析:
	一般是数据库未启动、mysql配置文件未指定socket文件或者数据库端口被防火墙拦截导致。

解法:
	启动数据库或者防火墙开放数据库监听端口。

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

分析:
	密码不正确或没有权限访问。

解法:
	修改my.cnf主配置文件,在[mysqld]下添加skip-grant-talbes=on,重启数据库,最后修改密码命令如下。	

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

8.0版本
mysql> update mysql.user set authentication_string='' where user='root' and Host='localhost';
mysql> flush privileges;
mysql> alter user 'root'@'localhost' identified by '123456';

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

5.7版本
mysql> grant all on *.* to 'root'@'mysql-server' identified by '123456';

8.0版本
mysql> create user 'root'@'mysql-server' identified  by '123456';
mysql> grant all on *.* to 'root'@'mysql-server';

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

分析:
	开启了dns解析功能。

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

现象4:
	Can't open file: 'xxx_forums.MYI'. (error:145)

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

解法:
	myisamchk -r 数据文件目录/数据表名.MYI;  # 仅适合独立主机用户。
	
	或
	
	修改文件的属组。复制数据库文件的过程中没有将数据库文件设置为MySQL运行的账号可读写。 # 仅适合独立主机用户。

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

分析:
	超出了mysql的总连接请求数,新的连接会无法连接。

解法:
	使用mysqladmin flush-hosts命令清除缓存即可。
	mysqladmin -uroot -p -h ip flush-hosts 

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

现象6:
	客户端报 Too many connections.

分析:
	连接数超出mysql的最大连接数限制。

解法:
	在my.cnf配置文件中增大连接数,然后重启mysql
	max_connections=1000
	
	或

	临时修改最大连接数。
	set GLOBAL max_connections=1000;

现象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 /etc/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
	The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

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

解法:
	修改从库的server-id值,与主库不一样,重启mysql后再同步即可。

现象2
	从库的Slave_IO_Running 为 NO
	
分析:
	原因很多,例如主键冲突、主库删除,从库找不到记录、数据被修改导致。通常状态码报错有1007、1032、1062、1452等。

解法:
mysql> stop slave; 
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;  # 设置全局sql从属计数器为1.
mysql> start slave;

或

mysql> set global read_only=true; # 设置用户权限,从库只读。

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

分析:
	从库的中继日志relay-log损坏。

解法:
	手工修复,重新找到同步的binlog和pos点,然后重新同步即可。
	mysql>chan gemaster to master_log_file='mysql-bin.xxxxxx',master_log_pos=xxx;


mysql的sql语句优化

创建测试表并插入数据
mysql> create database test;
Query OK, 1 row affected (0.02 sec)

mysql> use test;
Database changed
mysql> create table users(
    -> id int primary key auto_increment,
    -> name varchar(50) not null,
    -> email varchar(100) not null,
    -> age int not null,
    -> created_at datetime default current_timestamp
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> delimiter $$  # 设置分隔符,用$$来作为当前语句的终止符,以便后续存储过程使用它作为分隔符。
mysql> create procedure ii_users()  # 创建存储程序
    -> begin  # 开始存储程序。
    -> declare i int default 0;  # 声明变量。
    -> while i < 100000 do  # 执行循环插入数据。当i小于10万时,进入循环,name列由concat('user',i)生成,如user1、user2等,email列由concat('user',i,'@example.com')生成,如'user1@example.com',age列通过floor(rand() * 100) 随机生成0到99之间的整数值。 通过 i = i + 1 来更新变量的值。
    -> insert into users(name,email,age) 
    -> values (concat('user',i),concat('user',i,'@example.com'),
    -> floor(rand() * 100));
    -> set i = i + 1;
    -> end while;  # 结束循环
    -> end$$  #结束存储程序,使用之前的$$作为终止符。
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;  # 恢复语句分隔符,将默认的语句分隔符恢复为; 避免后续查询出错。
mysql> call ii_users();   # 执行存储过程。
Query OK, 1 row affected (6 min 34.95 sec)

mysql> explain select * from users where name = 'user123';
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+
|  1 | SIMPLE      | users | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 99909 |    10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> alter table users add index idx_name(name);  # 优化,创建索引。
Query OK, 0 rows affected (0.68 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select * from users where name = 'user123';  # 查询使用了索引,大大提高了查询效率。
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_name      | idx_name | 152     | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+

explian用于显示mysql如何执行一条sql语句,关键字段解释:
字段 说明 优化关注点
id 查询序列号,相同id为同一执行层,不同id按序执行。

select_type 查询类型(simple、primary、subquery、derived等) 识别子查询或临时表操作。

table  访问的表名或别名。  确认查询涉及的表。

type  访问类型 性能从优到劣:system > const > eq_ref > ref > range > index > ALL 避免ALL(全表扫描),优先优化为ref或range。

possible_keys 可能使用的索引    检查是否有合适索引未被使用。

key  实际使用的索引    确认是否命中最佳索引

rows 预估扫描的行数	行数越少,查询效率越高。

extra	附加信息(如 using where 、using index、using temporary等) 发现潜在性能问题(如临时表、文件排序)。


网站公告

今日签到

点亮在社区的每一天
去签到