默认值才是王道:记一次MySQL服务器参数调优之旅

【前言】

     最近入职一家新的公司维护MySQL,最开始的工作是配置调优。在研究了我们的业务和前任留下的配置文件后,做了若干基准测试,基于测试结果,对数据库做了一些简单优化。这里整理了部分自己写的测试报告分享一下。

 

【过程】

1.环境            
        ①Slave        
    64位CentOS服务器:        
    物理机2核4G;        
    MySQL2G内存池。        
        ②Master        
    64位CentOS服务器:        
    物理机8核32G;        
    MySQL4G内存池。        
            
2.工具            
    ①sysbench(https://github.com/akopytov/sysbench):数据库和服务器系统基准测试工具。        
    ②tpcc-mysql(https://github.com/Percona-Lab/tpcc-mysql):数据库复杂事务处理能力TPC-C指标测试工具。        
            
3.目标            
    MySQL性能优化。        
            
4.方式            
    对比法:先以原配置进行测试并记录测试结果;再修改部分数据库配置参数重新执行测试。每个项测试结束皆清除缓存并重启MySQL数据库,消除交叉影响。        
            
5.测试过程            
    ①随机读写测试(sysbench):        
    对一张100W条记录的表执行随机读写测试。        
    ②复杂事务处理能力(tpcc-mysql):        
    对一个虚拟仓库销售供应商公司的数据库模型执行复杂事务处理能力测试。        
            
6.测试结果            
    本次测试基于原配置文件(当前线上在用版本)主要做了以下测试,具体的每份测试报告可以查看群里面的共享文件夹:        
    ①修改部分基础参数至MySQL默认值;        
    ②修改部分基础参数低于MySQL默认值;        
    ③修改MySQL事务隔离级别(基于原配置文件);        
    ④修改InnoDB事务日志缓冲刷新机制(基于原配置文件);        
    ⑤修改基于数据安全和高可用的部分参数;        
    ⑥综合修改。        
    测试结果如下(基于Slave测试数据)。        
            
        >>>>>>>>吞吐量
        
    如图所示,从最左边天蓝色到右边草绿色分别为原配置文件、修改部分基础参数至MySQL默认值、修改部分基础参数低于MySQL默认值、修改MySQL事务隔离级别(基于原配置文件)、        
    修改InnoDB事务日志缓冲刷新机制、修改基于数据安全和高可用的部分参数以及综合修改调整的测试结果:左边为事务总量(Throughput);右边为其相应的TPS。以此可以简单看出:        
    ①MySQL基于数据安全和高可用的部分参数对吞吐能力有极大影响,若干倍级别,数据安全和读写性能是一对绝对的矛盾体;        
    ②事务隔离级别到了5.7版本对MySQL的性能已经几乎没有多大影响;        
    ③MySQL各种参数的默认值在大多数情况下都是最优解或接近最优解;        
    ④对当前线上在用配置文件进行一些非核心参数的微调,性能还是能有一定的上升,测试中TPS可以从590提高到680。        
            
        >>>>>>>>复杂事务处理能力
       
    复杂事务处理能力的测试情况基本上与吞吐量数据一致。        
    
    在处理复杂事务时MySQL两种隔离级别的表现。        
            
7.综合修改测试数据            
        >>>>>>>>Slave        

        >>>>>>>>Master        

            
8.测试结论配置意见            
    当前配置的主要问题:        
    ①部分基础参数值设置过大,造成系统资源消耗,如一些buffer/cache size的大小;        
    ②部分基础参数值设置不合理,影响数据库性能,如缓冲池实例数量;        
    ③数据库安全、数据安全和MySQL高可用的一些参数基本上都设置了比较低的级别,有事件丢失等潜在风险。        
            
    修改建议(之后会为Slave和Master配置文件升级分别写一个Shell脚本):        
    ①部分参数根据测试结果可以考虑切回默认值;        
    ②部分参数根据物理机服务器配置做一些适当调整;        
    ③修改或增加一些对数据库性能基本上没有直接影响但保护数据库安全的配置;        
    ④数据安全和高可用配置的修改,对性能影响较大,可以暂时维持现状,其中复制库slave只是用于BI读库复制的潜在问题可以忽略,但是master有丢失事件的潜在风险,这是当前数据安全的最大隐患。        

【小结】

     本次调优最终主要是将若干参数的现有配置调回默认值或官方推荐的修改值,可以看出经过微调Master和Slave的性能都有所提升,服务器的硬件压力也有所减轻。以下是主要修改列表。

 

→ 基础设置:
参考MySQL内存计算器(http://www.mysqlcalculator.com/)。
	①.max_connections
客户端最大连接数。
MySQL默认151;线上配置1024。
考虑到实际连接并发数,先尝试降到500。
	②.max_user_connections
账户最大连接数,其实受全局变量“max_connections”控制。
MySQL默认0表示没有限制;线上配置1000。
建议切回默认值。
	③.wait_timeout
非交互式客户端连接系统回收之前的空闲等待时间(秒)。
MySQL默认28800(非Windows系统);线上配置8640000。
建议先切回默认值。
	④.interactive_timeout
交互式客户端连接系统回收之前的空闲等待时间(秒)。
MySQL默认28800;线上配置8640000。
建议切回默认值。
	⑤.max_heap_table_size
MEMORY表最大长度。该参数和“tmp_table_size”共同起作用(取两者中的最小值为实际中的上限值)。
MySQL默认16MB;线上配置64MB。
建议切回默认值。
	⑥.tmp_table_size
临时表最大长度。该参数和“max_heap_table_size”共同起作用(取两者中的最小值为实际中的上限值)。
MySQL默认16MB;线上配置64MB。
建议切回默认值。
	⑦binlog_cache_size
事务执行过程中的二进制日志缓冲,每个客户端连接在执行事务时都会分配一块“binlog_cache_size”大小的内存。
MySQL默认32KB;线上配置2MB。
建议切回默认值。

→ 存储引擎
对MySQL默认存储引擎InnoDB若干设置的修改。
	①.innodb_buffer_pool_instances
InnoDB存储引擎内存池实例。
MySQL默认8个(innodb_buffer_pool_size < 1GB时默认1个);线上配置8个。
MySQL官方推荐每个内存池实例应该分配1GB的内存,所以建议“innodb_buffer_pool_size”设置几G,
这个值就设置几个。【该系统参数不支持动态修改,所以修改在MySQL重启后才能启用。】
	②.transaction_isolation
事务隔离级别。MySQL默认是“REPEATABLE-READ”消除了“幻读”;Oracle和MS SQL Server默认是“READ-COMMITTED”。
线上配置READ-COMMITTED。
建议切回默认值。
	③.innodb_purge_threads
Undo回收线程数。
MySQL默认4(5.7.7版本以后)表示开启4个后台线程回收Undo;线上配置1。
维持现值。
	④.innodb_purge_batch_size
Purge线程一次批处理的Undo页数量。
MySQL默认300;线上配置32。
建议切回默认值。该参数只是用来测试和调优innodb_purge_threads用,MySQL官方不建议修改其默认值。
	⑤.innodb_page_cleaners
脏页刷新线程数。
MySQL默认4(5.7.7版本以后);线上采用默认值。
建议将该值设置为“innodb_buffer_pool_instances”参数的设置值。
	⑥.innodb_log_buffer_size
InnoDB事务日志缓冲大小。
MySQL默认16MB(5.7.5版本以后);线上配置64MB。
建议切回默认值。InnoDB事务日志刷新回磁盘的频率非常高(Master线程秒刷;或者配置事务提交时触发刷新),OLTP事务默认值足以支撑。
	⑦.innodb_change_buffer_max_size
Change Buffer可以使用InnoDB内存池的最大百分比。
MySQL默认25(25%);线上采用默认值。
建议提升到35试试,线上写事务比较频繁。
	⑧.innodb_file_format
InnoDB表空间文件格式。
MySQL默认“Barracuda”(5.7.6版本以后);线上采用默认值。
建议从配置文件里面去掉该配置行,该参数为一个版本升级用过渡参数,即将废弃。

→ 访问安全:
	①max_connect_errors
连接错误超过该次数设定后主机将被禁止继续访问数据库(FLUSH HOSTS命令解除限制)。
MySQL默认100;线上配置10000。
基于数据库安全考虑建议该参数切回默认值。

→ 数据安全和高可用配置(为了性能考虑暂时未上线):
	①.innodb_flush_log_at_trx_commit
InnoDB事务日志缓冲刷新回磁盘触发选项。
MySQL默认1,表示事务每提交一次就刷新回磁盘,以确保完整的ACID;线上配置2,表示事务每提交一次刷新到操作系统(OS文件系统也有可能缓冲)。
文件缓冲(并不能保证写入磁盘文件)。
建议切回默认值,避免宕机故障丢失线上事务。
	②.sync_binlog
二进制日志缓冲刷新回磁盘触发选项。
MySQL默认1(5.7.6版本以后)表示同步磁盘写;线上配置0表示非同步写。
建议切回默认值,保证复制架构的高可用。

 

     因为服务器物理机和数据库实例比较多,手动修改配置文件也很容易出现误操作。最后写了一个小Shell脚本,然后每次停机维护的时候修改几台配置,慢慢迭代。

 

# !/bin/bash
# Author    : 蛙鳜鸡鹳狸猿
# create_ts : 2017年 12月 28日 星期四 09:47:09 CST
# program   : MySQL Master Config File Upgrade
# crontab   : o(>﹏<)o


### header parameters ceil ###
cnf_file=/etc/my.cnf
bak_file=/etc/my.cnf.$(date +%Y%m%d%H%M%S)
### header parameters floor ###


### function block ceil ###
# set backups
function setbackups(){
    cp ${cnf_file} ${bak_file}
    if [ $? == 0 ]; then
        echo -e "\n\(^o^)/ ${cnf_file} backup to ${bak_file} \(^o^)/\n"
        return 0
    else
        echo -e "\no(>﹏<)o my.cnf backup failed o(>﹏<)o\n"
        exit 1
    fi
}

# set threads
function setthreads(){
    cpus=$(lscpu | sed -ne '4p' | awk '{ print $2 }') && declare -i threads=${cpus}-1
    if [ $? == 0 ]; then
        echo -e "\n\(^o^)/ threads sets ${threads} \(^o^)/\n"
        return ${threads}
    else
        echo -e "\no(>﹏<)o threads sets failed o(>﹏<)o\n"
        exit 1
    fi
}

# set setbuffers
function setbuffers(){
    buffers=$(cat ${cnf_file} | grep ^innodb_buffer_pool_size | tr -cd "[[:digit:]]\n")
    if [ $? == 0 ]; then
        echo -e "\n\(^o^)/ buffers sets ${buffers} \(^o^)/\n"
        return ${buffers}
    else
        echo -e "\no(>﹏<)o buffers sets failed o(>﹏<)o\n"
        exit 1
    fi
}
### function block floor ###


######## main block ceil ########
# get threads
setthreads
thread=$?
# get buffers
setbuffers
buffer=$?
# set backup
setbackups
# upgrade block
sed -i '1, $s/^wait_timeout.*$/wait_timeout = 28800/g' ${cnf_file}
sed -i '1, $s/interactive_timeout.*$/interactive_timeout = 28800/g' ${cnf_file}
sed -i '1, $s/^max_connections.*$/max_connections = 500/g' ${cnf_file}
sed -i '1, $s/^max_user_connections.*$/max_user_connections = 0/g' ${cnf_file}
sed -i '1, $s/^tmp_table_size.*$/tmp_table_size = 16M/g' ${cnf_file}
sed -i '1, $s/^max_heap_table_size.*$/max_heap_table_size = 16M/g' ${cnf_file}
sed -i '1, $s/^innodb_log_buffer_size.*$/innodb_log_buffer_size = 16M/g' ${cnf_file}
sed -i '1, $s/^innodb_purge_batch_size.*$/innodb_purge_batch_size = 300/g' ${cnf_file}
sed -i '1, $s/^max_connect_errors.*$/max_connect_errors = 100/g' ${cnf_file}
sed -i '1, $s/^transaction_isolation.*$/transaction_isolation = REPEATABLE-READ/g' ${cnf_file}
sed -i '1, $s/^default-storage-engine.*$/default_storage_engine = InnoDB/g' ${cnf_file}
sed -i '1, $s/^character-set-server.*$/character_set_server = utf8/g' ${cnf_file}
sed -i '1, $s/^slave-net-timeout.*$/slave_net_timeout = 10/g' ${cnf_file}
sed -i '1, $s/^open-files-limit.*$/open_files_limit = 28192/g' ${cnf_file}
sed -i '1, $s/^skip-external-locking/skip_external_locking/g' ${cnf_file}
sed -i '1, $s/^skip-name-resolve/skip_name_resolve/g' ${cnf_file}
sed -i '1, $s/^no-auto-rehash/disable-auto-rehash/g' ${cnf_file}
sed -i '1, $s/^innodb_file_format.*$//g' ${cnf_file}
sed -i "1, \$s/^innodb_buffer_pool_instances.*\$/innodb_buffer_pool_instances = ${buffer}/g" ${cnf_file}
sed -i '99i innodb_change_buffer_max_size = 35' ${cnf_file}
sed -i "94i innodb_page_cleaners = ${buffer}" ${cnf_file}
sed -i "1, \$s/^innodb_purge_threads.*\$/innodb_purge_threads = ${thread}/g" ${cnf_file}
######## main block floor ########

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值