今天同事反应系统响应缓慢,看了一下页面加载时间确实比较长,在排查了3层的网络后,确定网络没有问题,那么大概率是数据库的问题,因为应用并没有进行更新。
进入mysql所在的服务器发现CPU全部打满,停掉服务后正常,于是开始停机维护。
诊断过程:
1.检查数据表数量,发现并不多,主表才几十万条记录。
2.使用SHOW FULL PROCESSLIST命令查看了一下,是正常的查询语句。
3.看了下查询语句,IN子句中的子查询,如果子查询返回的结果集很大,它可能会影响性能。在某些情况下,可以考虑使用连接(JOIN)来代替子查询,但是结果集并不多,也不是关键。
4.使用EXPLAIN查了下语句,该语句是2张表的联查,A表没有用到索引,B表有一个唯一索引,感觉也不是问题所在。
5.最后问题在配置文件上,同事使用军哥的LNMP安装的套件,没有修改my.cnf,默认的配置是:
#password = your_password port = 3306 socket = /tmp/mysql.sock [mysqld] port = 3306 socket = /tmp/mysql.sock datadir = /usr/local/mysql/var skip-external-locking key_buffer_size = 16M max_allowed_packet = 1M table_open_cache = 64 sort_buffer_size = 512K net_buffer_length = 8K read_buffer_size = 256K read_rnd_buffer_size = 512K myisam_sort_buffer_size = 8M thread_cache_size = 8 query_cache_size = 8M tmp_table_size = 16M performance_schema_max_table_instances = 500 explicit_defaults_for_timestamp = true #skip-networking max_connections = 500 max_connect_errors = 100 open_files_limit = 65535 log-bin=mysql-bin binlog_format=ROW server-id = 3 binlog-do-db = case_manage expire_logs_days = 10 early-plugin-load = "" default_storage_engine = InnoDB innodb_file_per_table = 1 innodb_data_home_dir = /usr/local/mysql/var innodb_data_file_path = ibdata1:10M:autoextend innodb_log_group_home_dir = /usr/local/mysql/var innodb_buffer_pool_size = 16M innodb_log_file_size = 5M innodb_log_buffer_size = 8M innodb_flush_log_at_trx_commit = 1 innodb_lock_wait_timeout = 50 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [myisamchk] key_buffer_size = 20M sort_buffer_size = 20M read_buffer_size = 2M write_buffer_size = 2M [mysqlhotcopy] interactive-timeout
发现参数都是默认的,太小了,改了一下参数:
innodb_buffer_pool_size = 20G innodb_log_file_size = 1G innodb_buffer_pool_instances = 10 max_heap_table_size = 256M table_open_cache = 2000 thread_cache_size = 50 tmp_table_size = 256M innodb_log_buffer_size = 128M
部分修改,部分新增,修改完重启服务,使用命令检查是否生效:
HOW VARIABLES LIKE 'innodb_buffer_pool_size';
缓冲池的配置已经修改了,没问题。
服务跑起来后反馈良好,问题解决,下面附一下这些参数的意思。
- innodb_buffer_pool_size:
- 这是最关键的设置之一。对于32GB内存,建议设置为内存的50%到70%,即16GB到22GB。例如:
innodb_buffer_pool_size = 20G。
- 这是最关键的设置之一。对于32GB内存,建议设置为内存的50%到70%,即16GB到22GB。例如:
- innodb_log_file_size:
- 这取决于事务大小,但通常设置为1GB左右是个合适的起始值。例如:
innodb_log_file_size = 1G。
- 这取决于事务大小,但通常设置为1GB左右是个合适的起始值。例如:
- innodb_buffer_pool_instances:
- 如果你的
innodb_buffer_pool_size大于1GB,那我们可以考虑设置多个缓冲池实例。每个实例大约1GB到2GB。例如:innodb_buffer_pool_instances = 10。
- 如果你的
- key_buffer_size:
- 如果主要使用InnoDB,并且很少使用MyISAM表,那么你可以将这个值设置得较小,比如:
key_buffer_size = 32M。
- 如果主要使用InnoDB,并且很少使用MyISAM表,那么你可以将这个值设置得较小,比如:
- table_open_cache:
- 这取决于你打开表的数量。可以尝试更高的值,如2000或更多:
table_open_cache = 2000。
- 这取决于你打开表的数量。可以尝试更高的值,如2000或更多:
- thread_cache_size:
- 这个值取决于你的连接数。对于高负载的服务器,可以设置为50或更高:
thread_cache_size = 50。
- 这个值取决于你的连接数。对于高负载的服务器,可以设置为50或更高:
- tmp_table_size 和 max_heap_table_size:
- 这两个参数控制临时表的大小。设置为较大的值,例如256M,以减少将临时表写入磁盘:
tmp_table_size = 256M和max_heap_table_size = 256M。
- 这两个参数控制临时表的大小。设置为较大的值,例如256M,以减少将临时表写入磁盘:
- query_cache_size:
- MySQL 5.7及以上版本已弃用查询缓存。但是如果你使用的是较旧版本,请根据你的查询模式调整这个值。需要注意的是,过大的查询缓存可能会降低性能。
- max_connections:
- 根据你的应用需求设置。你的服务器可能可以处理更多连接,但需要监控性能和资源使用情况来决定合适的值。
- innodb_log_buffer_size:
- 对于高负载的写操作,可以增加至128M或更高:
innodb_log_buffer_size = 128M。
- 对于高负载的写操作,可以增加至128M或更高:
- innodb_flush_log_at_trx_commit:
- 这个参数影响性能和可靠性。值为1表示每次事务提交都会写入日志,值为2或0会增加性能但降低可靠性。根据你的需求调整,普通项目建议不动。
- open_files_limit:
- 我们保持现有设置,需要注意的是要确保这个值高于操作系统允许打开的文件数限制。