linux——mysql故障排查与生产环境优化
目录
一,mysql数据库常见的故障
1,故障现象1
2,故障现象2
3,故障现象3
4,故障现象4
5,故障现象5
6,故障现象6
二,mysql主从故障排查
1,故障现象1
2,故障现象2
三,mysql硬件方面的优化
1,CPU优化
2,内存优化
3,存储优化
四,mysql配置文件优化
1,连接相关方面的优化
2,lnnoDB引擎优化
3,查询优化
4,日志配置
5,核心性能优化
五,什么是mysql的引擎
1,mysql引擎是用来干什么的
2,lnnoDB(默认引擎)
3,Mylsam(历史引擎)
4,lnonDB与mylsam的区别
六,SQL方面的优化
一,mysql数据库常见的故障
1,故障现象1
mysql: [Warning] Using a password on the command line interface can be insecure.
问题分析:这只是一个警告信息,当你使用类似 mysql -u root -p123456
的命令登陆数据库时,
- 密码明文暴露:密码会在命令行历史记录(
~/.bash_history
)中留存 - 进程可见性:在进程列表(
ps aux
)中其他用户可能看到密码 - 日志风险:如果命令被记录或审计,密码会被明文存储
解决方法:登陆数据库时不要把密码输入到外边,使用类似命令进行登陆 mysql -uroot -p
2,故障现象2
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/data/mysql.sock' (2)
问题分析:这种情况一般都是数据库未启动,mysql中的配置文件为指定sock文件或者数据库端口被防火墙拦截导致。
解决方法:查看数据库是否启动,防火墙开放数据库监听端口,/etc/my.cnf配置文件指定sock目录位置 例如:socket=/usr/local/mysql/data/mysql.sock
3,故障现象3
忘记mysql登陆密码如何解决。
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
问题分析:密码不正确或者没有权限访问
解决方法:
[root@bogon ~]# vim /etc/my.cnf ##编辑mysql配置文件,添加一行
[mysqld]
skip-grant-tables=on ##跳过密码认证进入到数据库systemctl restart mysqld ##修改完之后重启生效[root@bogon ~]# mysql -uroot ##无需指定密码登陆到数据库update mysql.user set authentication_string='' where user='root' and Host='localhost';
flush privileges;alter user 'root'@'localhost' identified by '123456'; ##修改新密码为123456##删除skip-grant-tables=on,使用新密码登陆即可
4,故障现象4
使用远程连接数据库发生远程连接数据库很慢的问题
问题分析:如果 MySQL 主机查询 DNS 很慢或是有很多客户端主机时会导致连接很慢.由于开发机器是不能够连接外网的,在进行MySQL连接时,DNS 解析是不可能完成的,从而也就明白了为什么连接那么慢了。
解决方法:修改 my.cnf 主配置文件,在[mysgld]下添加 skip-name-resolve,重启数据库可以解决。注意在以后授权里面不能再使用主机名授权。
5,故障现象5
MySQL连接数过载
ERROR 1129(HY000):Host'xxx.xxx.xxx.xxx'is blocked because of manyconnection errors;
unblock with mysqladmin flush-hosts
问题分析:由于 mysql 数据库的参数:max_connect_errors,其默认值是 10。当大量(max connect errors)的主机去连接 MySQL,总连接请求超过了 10 次,新的连接就再也无法连接上 MySQL 服务。同一个 ip 在短时间内产生太多中断的数据库连接而导致的阻塞(超过 mysql 数据库 max connection errors 的最大值)。
解决方法:
##使用flush-hosts命令清理缓存
mysqladmin -uroot-p -h 192.168.10.102 flush-hosts ##使用此命令清理缓存
Enter password:方法二:
修改 mysql 配置文件,在[mysqld]下面添加 max connect errors=1000,
6,故障现象6
客户端报 Too many connections.
问题分析:连接数超出mysql的最大连接数限制
解决方法:
[root@bogon ~]# vim /etc/my.cnf ##修改mysql数据库的最大连接数,修改完成后需要重启
max_connections=2048
7,故障现象7
Warning: World-writable config file ,/etc/my.cnf' is ignoredERROR! MySQL is running but PID file could not be found
问题分析:MySQL 的配置文件/etc/my.cnf 权限不对,
解决方法:
chmod 644 /etc/my.cnf 将MySQL配置文件权限改为644
二,mysql主从故障排查
1,故障现象1
使用show slave status\G 查看从数据库复制状态,slave_IO_running为NO
问题分析:从库和主库的server-id值一样
解决方法:修改从库和主库的server-id值不一样,关闭u防火墙或者开启3306端口,然后重启mysql数据库,重新同步。
2,故障现象2
从数据库的SQL线程为no
Slave_SQL_Running: No
问题原因:MySQL 复制中的 SQL 线程停止了工作
解决方法:
##在主库上执行命令SHOW MASTER STATUS;重新查看file和position##在从库上重新执行主从连接命令
change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='file',master_log_pos=posttion;##从数据库stop slave; start slave ##重启slave并查看状态
三,mysql硬件方面的优化
1,CPU优化
CPU 对于 MySQL 应用,推荐使用 S.M.P.架构的多路对称 CPU。例如:可以使用两颗 Intel Xeon 3.6GHz的 CPU。现在比较推荐用 4U 的服务器来专门做数据库服务器,不仅仅是针对于 MySQL。
2,内存优化
物理内存对于一台使用 MySQL 的 Database Server 来说,服务器内存建议不要小于 2GB,推荐使用 4GB 以上的物理内存。不过内存对于现在的服务器而言可以说是一个可以忽略的问题,工作中遇到了高端服务器基本上内存都超过了32G。
3,存储优化
以目前市场上普遍高转速 SAS 硬盘(15000 转/秒)为例,这种硬盘理论上每秒寻道 15000 次,这是物理特性决定的,没有办法改变。 MySQL 每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以通常认为磁盘 I/0 是制约 MySQL 性能的最大因素之一,通常是使用RAID-0+1 磁盘阵列,注意不要尝试使用 RAID-5,MySQL 在 RAID-5 磁盘阵列上的效率并不高。如果不考虑硬件的投入成本,也可以考虑固态(SSD)硬盘专门作为数据库服务器使用。数据库的读写性能肯定会提高很多。
四,mysql配置文件优化
MySQL 配置文件/etc/my.cnf的优化可以显著提升数据库性能。以下是主要的优化方向和详细配置建议:
1,连接相关方面的优化
- max_connections = 500 #最大连接数,根据应用需求调整
- thread_cache_size = 32 #线程缓存大小,减少连接创建开销
- table_open_cache = 4000 #表缓存数量
2,lnnoDB引擎优化
- innodb_log_file_size = 1G # 重做日志文件大小,大事务需要更大的日志
- innodb_log_buffer_size = 64M # 日志缓冲区大小
- innodb_flush_log_at_trx_commit = 1 (数据安全) 或 2 (性能优先) # 1=每次提交都刷盘(最安全),2=每秒刷盘(性能更好)
- innodb_file_per_table = ON # 每个表使用独立表空间
- innodb_flush_method = O_DIRECT # Linux下推荐值,减少双缓冲
3,查询优化
- sort_buffer_size = 4M # 排序缓冲区大小
- join_buffer_size = 4M # 连接操作缓冲区大小
- read_buffer_size = 2M # 全表扫描时的缓冲区
- read_rnd_buffer_size = 4M # 随机读缓冲区
4,日志配置
- slow_query_log=ON #启用慢查询日志,0N
- long_query_time=1 #定义慢査询阈值
- log_error=/var/log/mysql/error.log ##指定错误日志路径
- binlog_format #指定二进制文件日志格式(主从复制需要)
- expire_logs_days=7 #自动清理旧的二进制日志天数。
5,核心性能优化
内存配置
- innodb_buffer_pool_size:#总内存的50-70%
- innodb_log_buffer_size:#大事务需增大
- key_buffer_size:MyISAM #专用(如不使用可设小值)
I/O优化
- innodb_io_capacity和innodb_io_capacity_max(SSD环境可增大)
- innodb_flush_neighbors(SSD建议关闭)
- innodb_read_io_threads和innodb_write_io_threads
并发控制
- innodb_thread_concurrency(通常设为CPU核心数×2)
- thread_cache_size(减少线程创建开销)
- table_open_cache(减少表打开开销)
五,什么是mysql的引擎
1,mysql引擎是用来干什么的
MySQL 引擎(存储引擎)是数据库管理系统的核心组件,负责数据的存储、检索、索引和事务处理。不同的引擎提供不同的功能特性,用户可以根据业务需求选择最适合的引擎。
数据存储与管理:
- 引擎决定数据在磁盘上的存储格式(如 InnoDB 的聚簇索引、MyISAM 的索引与数据分离)。
- 负责数据文件的组织、缓存和读取(如 InnoDB 的缓冲池缓存热点数据)。
事务处理:
- 原子性(Atomicity):事务中的操作要么全部成功,要么全部失败。
- 一致性(Consistency):事务执行前后数据保持一致状态。
- 隔离性(Isolation):多个事务并发执行时互不干扰(通过锁或 MVCC 实现)。
- 持久性(Durability):事务提交后数据永久保存(通过日志保证)。
2,lnnoDB(默认引擎)
特点如下:
- 表级锁:所有操作锁整张表,并发性能差。
- 不支持事务:不保证数据原子性和持久性。
- 不支持外键:无法强制关联表间的数据完整性。
- 索引与数据分离:索引和数据文件分开存储(
.MYI
索引文件、.MYD
数据文件)。 - 全文索引:支持全文检索(MySQL 5.6 前 InnoDB 不支持)。
查看所有支持的索引:SHOW ENGINES;
##永久指定mysql引擎,编辑 MySQL 配置文件my.cnf,在[mysqld]部分添加:
[mysqld]
default-storage-engine=InnoDB 指定mysql引擎为InnoDB##创建表时指定引擎
CREATE TABLE my_table (id INT PRIMARY KEY) ENGINE=InnoDB;##查看已有表使用的引擎
mysql> show table status like 'users'\G
*************************** 1. row ***************************Name: usersEngine: InnoDB
适用场景:
-
高并发事务型业务
-
数据一致性要求高的场景
-
高并发读写混合场景
-
大数据量存储
3,Mylsam(历史引擎)
特点如下:
- 表级锁:所有操作锁整张表,并发性能差。
- 不支持事务:不保证数据原子性和持久性。
- 不支持外键:无法强制关联表间的数据完整性。
- 索引与数据分离:索引和数据文件分开存储(
.MYI
索引文件、.MYD
数据文件)。 - 全文索引:支持全文检索
适用场景:
-
读多写少的静态数据场景
-
全文搜索场景
-
临时表或统计分析
-
轻量级应用
六,SQL方面的优化
SQL优化是确保数据库高效运行的关键,其核心在于通过减少资源消耗(如CPU、内存、磁盘 I/0)来提升査询响应速度,避免慢查询导致用户体验下降或系统崩溃。
- 准备用于测试的数据库和表
#创建测试库
Create database test;#创建用户表
Use test;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
);#插入 10 万条测试数据(使用存储过程生成)
DELIMITER $$
CREATE PROCEDURE insert_users()
BEGINDECLARE i INT DEFAULT 0;WHILE i < 100000 DOINSERT INTO users (name, email, age) VALUES (CONCAT('user', i), CONCAT('user', i, '@example.com'), FLOOR(RAND() * 100));SET i = i + 1;END WHILE;
END$$
DELIMITER ;select * from users; ##当表里面的数据量非常庞大时,使用此语句查看会非常慢
- 使用explain对sql优化
mysql> select * from users where name='user111';
+--------+---------+---------------------+-----+---------------------+
| id | name | email | age | created_at |
+--------+---------+---------------------+-----+---------------------+
| 112 | user111 | user111@example.com | 38 | 2025-05-09 08:16:12 |
| 100112 | user111 | user111@example.com | 38 | 2025-05-09 08:17:00 |
+--------+---------+---------------------+-----+---------------------+
2 rows in set (0.04 sec) ##普通查看数据的速度mysql> explain select * from users where name='user111';
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | NULL | 199578 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) ##使用explain查看数据的速度
- 添加索引优化查询速度
mysql> alter table users add index idx_name(name); ##添加名为idx_name值为name的索引
Query OK, 0 rows affected (0.24 sec)
Records: 0 Duplicates: 0 Warnings: 0mysql> select * from users where name='user111';
+--------+---------+---------------------+-----+---------------------+
| id | name | email | age | created_at |
+--------+---------+---------------------+-----+---------------------+
| 112 | user111 | user111@example.com | 38 | 2025-05-09 08:16:12 |
| 100112 | user111 | user111@example.com | 38 | 2025-05-09 08:17:00 |
+--------+---------+---------------------+-----+---------------------+
2 rows in set (0.00 sec) ##验证并观看查询时间