服务端参数
最大连接数 max_connections=3000
控制服务器允许同时建立的最大客户端连接数,这是调优的重要数据之一。当我们通过应用程序、用户或者工具来连接 MySQL 时,如果连接数已经达到最大值,新的连接就会被拒绝,会报 Too many connections
的错误。
每个连接的创建和销毁都会占用一定的内存和系统资源(如线程、文件描述符)。合理设置该参数可避免服务器因连接过多导致资源耗尽,比如内存、文件句柄,业务所谓的支持多少并发,实际上就是每秒的请求数,也就是 QPS。
每个连接至少需要占 256KB 内存,最大会到 64M,如果一个连接的请求数据超过 64M,比如进行了排序操作,这个时候就会申请临时空间,可能会将原来的内存中的数据清除,再将数据放到磁盘上。
(设置最大连接数需要根据实际情况进行合理设置,设置过高可能导致内存不足,反而会降低性能甚至引发 OOM )
如果 3000 个用户同时连接上 MySQL,最小内存需要 3000256KB=750M,最大需要 300064M=192G。如果 innodb_buffer_pool 配置了 40G(配置为实际内存的 60%-70%),加上给操作系统分配 4G,那么给连接使用的空间就剩下不足 20G,然而如果连接过多,就会出现磁盘 SWAP(交换空间),此时就会影响服务器性能。
连接数过高不一定能够带来很大的吞吐量,反而可能会消耗更多的系统资源。
如何微调?
我们可以通过以下两个命令来查询当前活跃和历史最大的连接数。
SHOW STATUS LIKE 'Threads_connected'; -- 当前活跃连接数
SHOW STATUS LIKE 'Max_used_connections'; -- 历史最高连接数
通过以下命令查看当前设置的最大连接数。
SHOW VARIABLES LIKE 'max_connections';
当线上发生连接数过多,可以通过临时解决,以下命令是临时生效,重启后就会失效。
SET GLOBAL max_connections = 1000;
允许用户最大连接数 max_user_connections=2980
设置允许用户最大连接数为 2980,与设置最大连接数 3000 相差了 20,这 20 个连接数是为了防止 MySQL 被程序全部占用,导致 DBA 无法连接。
其默认值是 0,表示无限制。
暂存连接数 black_log=300
back_log 参数是 MySQL 缓存的尚未处理的连接数量,当 MySQL 在短时间内收到非常多的请求时,一时间处于不过来时,这个参数就会起到非常重要的作用。如果 MySQL 的连接数达到了最大连接数,那么多余的连接就会被暂存到堆栈中,等待某个连接释放资源。这个暂存数就是 black_log 配置的数据,如果超过了这个数量,超出的连接将会被拒绝。
假如最大连接数是 3000,暂存连接数是 300,那么,最多可以有 3300 个连接进来,300 个连接在堆栈中缓存。如果有 3301 个连接,那么多余的 1 个将会被拒绝。
非交互式空闲超时时间 wait_timeout=300
指的是 app 应用程序通过 jdbc 连接 MySQL 进行操作完毕后,空闲 300 秒后会自动断开,默认是 28800 秒,也就是 8 小时。
关于等待超时最好是设置一下,默认 8 小时会很长,会导致连接数占用。当客户端在超时后尝试使用已关闭的连接会收到错误:Lost connection to MySQL server during query
。
交互式空闲超时时间 interactive_timeout=300
指的是**通过命令行、图形化工具(Navicat)**等交互方式连接到 MySQL,并在指定时间内无操作时,服务器会自动关闭连接以释放资源。它与 wait_timeout 共同管理连接生命周期,但针对不同类型的客户端。默认也是 28800 秒=8 小时,这里建议与 wait_timeout 设置的时间一致。
Innodb 的几个参数
innodb_thread_concurrency=64
这个是 MySQL InnoDB 存储引擎的一个配置参数,它用于控制 InnoDB 处理用户查询时的并发线程数量。默认值:0,表示不被限制,若要设置则与服务器的 CPU 核心数相同,或者是 CPU 核心数的 2 倍,如果超过配置的并发数,则需要排队,这个值的配置不建议太大,否则可能当并发量过大,操作同一条数据,这样会导致锁等待锁争用,甚至会导致死锁,会影响性能。
tip(不仅考虑服务器,还应考虑系统的并发数)
- 对于小型服务器(<8 核):保持默认值 0,或设置为 2-4,避免线程争抢资源。
- 对于中型服务器(8-32 核):可以尝试 8-32。
- 对于大型服务器(>32 核):通常保持 0,让 InnoDB 自适应调度,或者进行压力测试找到最优值。
innodb_buffer_pool_size=40G
innodb 存储引擎 buffer pool 缓存大小,一般设置物理内存的 60-70%(独立的 MySQL 服务器,没有其他主要进程),这个是越大越好,是来缓存数据页、索引页、插入缓冲、适配哈希索引等,目的是减少磁盘 I/O,从而提升数据库性能。
innodb_lock_wait_timeout=10
MySQL InnoDB 存储引擎中的一个参数,用于控制 事务等待行锁 的最大时间(以秒为单位)。如果某个事务等待锁的时间超过该值,MySQL 会终止该事务并报错。
行锁锁定时间,默认 50 秒,这个需要根据实际业务情景来设定。
innodb_flush_log_at_trx_commit=1
决定事务提交时日志(redo log)刷盘的策略,直接影响数据一致性、性能和崩溃恢复。
该参数有 0、1、2 三种取值,每个值的行为不同:
对于设置0和2,不能100%保证每秒刷新一次。因为DDL更改和其他内部InnoDB活动会导致日志的刷新独立于innodb_flush_log_at_trx_commit 设置,刷新可能会更频繁地发生。如果日志每秒刷新一次,则在崩溃中最多会丢失一秒钟的事务。如果日志刷新频率大于或小于每秒一次,则可能丢失的事务量会相应变化。
1. 设置为 0
日志刷新行为:
事务提交时,重做日志不会被立即写入磁盘,而是将日志缓存在内存中。
随后,InnoDB 会依赖后台的日志刷新线程(Master Thread)每秒将日志缓冲区(log buffer)的内容写入磁盘一次。
性能影响:
由于减少了磁盘 I/O 操作,这种设置通常能提供较高的数据库性能。
数据安全性:
在系统崩溃或突然断电的情况下,可能会丢失最近一秒内的事务数据,因为这些事务的日志还没有被写入磁盘。
2. 设置为 1
日志刷新行为:
每次事务提交时,重做日志都会被立即写入磁盘,并进行同步(fsync)操作,确保日志数据被物理地写入磁盘。
性能影响:
这种设置提供了最高的数据持久性,但会对性能产生一定的影响,因为每次事务提交都需要等待磁盘 I/O 操作完成。
数据安全性:
在系统崩溃或突然断电后,数据库能够恢复到最近一次成功提交的事务状态,只会丢失崩溃前最后一秒内的事务数据(如果此时事务正在提交过程中)。
3. 设置为 2
日志刷新行为:
每次事务提交时,重做日志会被写入到操作系统的文件系统缓存(page cache)中,但并不会立即等待这些日志被刷新到磁盘上。
随后,InnoDB 会依赖操作系统的后台刷新机制或定期刷新策略(如每秒一次的刷新)来将缓存中的日志写入磁盘。
性能影响:
与设置为 0 类似,由于减少了每次事务提交时的磁盘写入等待时间,这种设置也提供了较高的性能。
但与设置为 0 相比,它在一定程度上提高了数据的安全性,因为日志至少被写入了操作系统的缓存。
数据安全性:
在系统崩溃或突然断电的情况下,如果操作系统的缓存还没有被刷新到磁盘,那么最近一秒内的事务数据可能会丢失。
然而,与设置为 0 相比,由于日志至少存在于操作系统的缓存中,因此在某些情况下(如仅数据库进程崩溃而操作系统正常)数据可能更安全。
sync_binlog=1
MySQL 二进制日志(binlog)同步 相关的关键参数,决定了 binlog 写入到磁盘的频率,直接影响数据安全性、事务持久性和性能。
当事务提交时,MySQL 会将 二进制日志(binlog) 写入操作系统缓存,但不会立即刷入磁盘。sync_binlog 控制每多少次事务提交后,执行一次 fsync(),确保 binlog 持久化到磁盘。
sync_binlog
可取值 0 或正整数
sync_binlog=0,禁用MySQL服务器将二进制日志同步到磁盘的功能。取而代之的是,MySQL服务器依靠操作系统不时地将二进制日志刷新到磁盘上,就像处理任何其他文件一样。此设置可提供最佳性能,但是在电源故障或操作系统崩溃的情况下,服务器可能提交了尚未同步到二进制日志的事务。
sync_binlog=1,在提交事务之前启用二进制日志到磁盘的同步。这是最安全的设置,但是由于磁盘写入次数增加,可能会对性能产生负面影响。如果发生电源故障或操作系统崩溃,二进制日志中缺少的事务将仅处于准备状态。这允许自动恢复例程回滚事务,从而确保二进制日志中不会丢失任何事务。
sync_binlog=n,其中N的值代表事务量:在N次事务之后,二进制日志将同步到磁盘 。在电源故障或操作系统崩溃的情况下,服务器可能提交了尚未刷新到二进制日志的事务。由于磁盘写入次数的增加,此设置可能会对性能产生负面影响。较高的值可以提高性能,但会增加数据丢失的风险。
sort_buffer_size=4M
排序缓存大小、
每个需要排序的线程分配该大小的一个缓冲区,增加该值可以加速 ORDER BY 或 GROUP BY 的操作。
sort_buffer_size 是 connection 级别,即在每个 connection(session) 第一次需要使用这个 buffer 时候,一次性分配设置的内存。
这个参数的设置并不是越大越好,它是 connection 级别,需要考虑到连接数占用资源大小,比如有 500 个连接需要进行排序,会分配内存资源,也就是 500*sort_buffer_size(4M)=2G。(要根据业务情况、服务器配置、并发数来进行修改)
join_buffer_size=4M
表关联缓存大小。
用于表关联缓存的大小,和sort_buffer_size 一样,该参数对应的分配内存也是每个连接独享。