MySQL优化
第1章 前言:
优化无非从安全方面入手或者性能方面入手
1.1 优化的范围有哪些:
存储;主机和操作系统:
主机架构稳定性
io规划及配置
swap交换分区
os内核参数和网络问题
1.2 应用程序方面:
应用程序稳定性
sql语句性能
串行访问资源
性能欠佳会话管理
这个应用适不适合用mysql
1.3 数据库优化方面:
内存
数据库结构(物理和逻辑)
实例配置
1.4 优化维度:
1. 硬件
2. 系统配置
3. 数据库表结构
4. sql及索引
1.5 优化的工具有什么?
1. 检查问题常用工具:
mysql
msyqladmin mysql客户端,可进行管理操作
mysqlshow 功能强大的查看shell命令
show [SESSION | GLOBAL] variables 查看数据库参数信息
SHOW [SESSION | GLOBAL] STATUS 查看数据库的状态信息
information_schema 获取元数据的方法
SHOW ENGINE INNODB STATUS Innodb引擎的所有状态
SHOW PROCESSLIST 查看当前所有连接session状态
explain 获取查询语句的执行计划
show index 查看表的索引信息
slow-log 记录慢查询语句
mysqldumpslow 分析slowlog文件的
2. 不常用,但好用的工具:
zabbix 监控主机、系统、数据库(部署zabbix监控平台)
pt-query-digest 分析慢日志
mysqlslap 分析慢日志
sysbench 压力测试工具
mysql profiling 统计数据库整体状态工具
Performance Schema mysql性能状态统计的数据
workbench 管理、备份、监控、分析、优化工具(比较费资源)
1.6 系统层面优化方面:
CPU方面 --vmstat;sar;top;htop;nmon;mpstat
内存 --free;ps –aux
io设备 --iostat;ss;netstat;iptraf;losf
1.6.1 vmstat命令说明:
[root@db03 mysql]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 17528 138636 0 308152 0 0 6 12 25 52 0 0 99 0 0
Procs:r显示有多少进程正在等待CPU时间。b显示处于不可中断的休眠的进程数量。在等待I/O
Memory:swpd显示被交换到磁盘的数据块的数量。未被使用的数据块,用户缓冲数据块,用于操作系统的数据块的数量
Swap:操作系统每秒从磁盘上交换到内存和从内存交换到磁盘的数据块的数量。s1和s0最好是0
Io:每秒从设备中读入b1的写入到设备b0的数据块的数量。反映了磁盘I/O
System:显示了每秒发生中断的数量(in)和上下文交换(cs)的数量
Cpu:显示用于运行用户代码,系统代码,空闲,等待I/O的CPU时间
1.6.2 iostat命令说明:
实例命令: iostat -dk 1 5
iostat -d -k -x 5 (查看设备使用率(%util)和响应时间(await))
[root@db03 mysql]# iostat -dk 1 5
Linux 3.10.0-327.el7.x86_64 (db03) 04/14/2018 _x86_64_ (1 CPU)
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.48 6.37 11.63 360474 658470
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
tps:该设备每秒的传输次数。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。
iops :硬件出厂的时候,厂家定义的一个每秒最大的IO次数
"一次传输"请求的大小是未知的。
kB_read/s:每秒从设备(drive expressed)读取的数据量;
KB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;
kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。
1.6.3 出现tps过度条带化的问题:
磁盘的条带化,建议1次为适宜,超过会导致IO次数过多,导致读写太慢的问题
1.6.4 系统层面问题解决办法:
在生产中,一般CPU占用只要不超过90%都没有问题
1.6.5 当然不排除一下特殊情况:
问题一:CPU负载高,IO负载低
1. 内存不够
2. 磁盘性能差
3. sql问题--->去数据库层,进一步排查sql问题
4. IO出问题了(磁盘到临界了,raid降级,锁,在单位时间内tps过高)
问题二:io负载高,CPU负载低
1. 大量的小io写操作
autocommit,产生大量小io
IO/ps,磁盘的一个定值,硬件出厂的时候厂家定义的一个每秒UI大的io次数
2. 大量的大IO写操作
sql问题的几率比较大
第2章 基础优化:
2.1 优化思路:
硬件 --> 系统 --> 应用 --> 数据库 --> 架构(高可用;读写分离;分库分表)
2.2 处理方向:
明确优化目标,性能和安全的折中,防患未然
2.2.1 硬件优化:
1. 主机方面:
a) 根据数据库类型,主机CPU选择,内存容量选择,磁盘选择
b) 平衡内存和磁盘资源
c) 随机的io和顺序的io,避免随机io的出现
d) 主机raid卡的bbu关闭,即将数据直接写到磁盘中,防止先写到内存,避免断电的故障
2. cpu的选择:
a) cpu的两个关键因素:核数,主频
b) 根据不同的业务类型进行选择
c) cpu密集型:计算机比较堵,主频很高的cpu,核数还要多
d) IO密集型:查询比较多,OLTP 核数要多,主频不一定高的
3. 内存的选择:
a) OLAP(数据仓库)类型数据库,需要更多内存,和数据获取量级有关
b) OLTP(在线事务处理系统)类型数据一般内存是cpu核心数量的2倍到4倍
4. 存储方面:
a) 根据存储数据的种类不同,选择不同的存储设备
b) 配置合理的raid级别(raid5;raid10;热备盘)
c) 对于操作系统来讲,不需要太特殊的选择,最好做好冗余(raid1)
5. 网络设备方面:
a) 使用流量支持更高的网络设备(交换机,路由器,网线,网卡)
2.2.2 服务器硬件优化:
1. 物理状态灯:
2. 自带管理设备:远程控制卡,开关机,硬件监控
3. 第三方的监控软件,对物理设备进行监控
4. 存储设备:自带的监控平台,
2.2.3 系统优化:
1. CPU : 在硬件方面下功夫
2. 内存 : 在硬件方面下功夫
3. io : raid no lvm;ext4或xfs
4. swap : mysql尽量避免使用swap
/proc/sys/vm/swappiness的内容改成0(临时),/etc/sysctl.conf上添加vm.swappiness=0(永久)
这个参数决定了linux是倾向于使用swap,还是倾向于释放文件系统cache,在内存紧张的情况下,数值越低越倾向于释放文件系统cache
当然这个参数之鞥呢减少使用swap的概率,并不能避免linux使用swap
修改mysq的配置参数innoDB_flush_method,开启O_DIRECT模式
这种情况下,innoDB的buffer pool 会直接绕过文件系统cache来访问磁盘,但是redo log依旧会使用文件系统cache
5. IO调度策略:
#echo deadline>/sys/block/sda/queue/scheduler 临时修改为deadline
永久修改:
[root@db03 grub2]# vim grub.cfg
kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet
2.2.4 系统参数调整:
linux系统内核参数优化:
vim /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535 # 用户端口范围
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_fin_timeout = 30
fs.file-max=65535 # 系统最大文件句柄,控制的是能打开文件最大数量
用户限制参数(mysql服务器可以不设置一下参数)
vim /etc/security/limits.conf
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
2.2.5 应用优化:
关闭无用服务:
chkconfig --level 23456 acpid off
chkconfig --level 23456 anacron off
chkconfig --level 23456 autofs off
chkconfig --level 23456 avahi-daemon off
chkconfig --level 23456 bluetooth off
chkconfig --level 23456 cups off
chkconfig --level 23456 firstboot off
chkconfig --level 23456 haldaemon off
chkconfig --level 23456 hplip off
chkconfig --level 23456 ip6tables off
chkconfig --level 23456 iptables off
chkconfig --level 23456 isdn off
chkconfig --level 23456 pcscd off
chkconfig --level 23456 sendmail off
chkconfig --level 23456 yum-updatesd off
2.3 数据库优化:
1. SQL优化方向:
a) 执行计划;索引;SQL改写
2. 架构优化方向:
a) 高可用架构;高性能架构;分库分表
2.3.1 数据库参数优化:
实例整体:
thread_concurrency # 并发线程数量个数
sort_buffer_size # 排序缓存
read_buffer_size # 顺序读取缓存
read_rnd_buffer_size # 随机读取缓存
key_buffer_size # 索引缓存
thread_cache_size # (1G—>8, 2G—>16, 3G—>32, >3G—>64)
连接层:
设置合理的连接客户和连接方式:
max_connections # 最大连接数,看交易笔数设置
max_connect_errors # 最大错误连接数,能大则大
connect_timeout # 连接超时
max_user_connections # 最大用户连接数
skip-name-resolve # 跳过域名解析
wait_timeout # 等待超时
back_log # 可以在堆栈中的连接数量
SQL层:
query_cache_size : 查询缓存 >>> OLAP类型数据库,需要重点加大此内存缓存
使用场景:经常对数据库的少部分数据进行反复查询,可以调整较大,8M左右
sync_binlog #binlog的刷新策略(控制binlog写入磁盘的条件)
0 : 达到binlog缓冲区大小就触发写入binlog日志中
1 : 每个事务提交就触发一次binlog写入文件中,双一标准中的其中一个
log_bin #设置binlog的位置及名称前缀,建议放到ssd存储上,并与数据隔离存储
binlog_format #设置binlog格式,建议row
max_binlog_cache_size #binlog 缓冲区大小
max_binlog_size #binlog缓冲区最大大小
2.3.2 存储引擎层(innoDB基础优化参数):
default-storage-engine #默认的存储引擎
innodb_buffer_pool_size # 没有固定大小,50%测试值,看看情况再微调。但是尽量设置不要超过物理内存65%
innodb_file_per_table=(1,0) #表空间模式,建议是1
innodb_flush_log_at_trx_commit=(0,1,2) # redo日志的刷新策略 0:每秒钟刷新redo一次(最大性能模式)1:每次事务提交时,刷新一次redo日志到磁盘中(最大的安全模式)2:每次事务提交时都刷新日志到os buffer,每秒钟fsync到磁盘
Innodb_flush_method=(O_DIRECT, fdatasync)
innodb_log_buffer_size # 100M以下
innodb_log_file_size # 100M 以下
innodb_log_files_in_group # 5个成员以下,一般2-3个够用(iblogfile0-N)
innodb_max_dirty_pages_pct # 达到百分之75的时候刷写 内存脏页到磁盘。
log_bin
max_binlog_cache_size # 可以不设置
max_binlog_size # 可以不设置
innodb_additional_mem_pool_size #小于2G内存的机器,推荐值是20M。32G内存以上100M
transaction_isolation #隔离级别,默认第三种级别
第3章 双一标准:
innoDB_flush_log_at_trx_commit和sync_binlog两个参数是控制mysql磁盘写入策略以及数据安全性的关键参数
3.1 参数意义说明:
innoDB_flush_log_at_trx_commit=1
Ø 如果设置为0,log buffer将每秒一次的写入logfile中,并且log file的flush(刷新磁盘)操作同时进行,该模式下,在事务提交的时候,不会主动触发写入磁盘的操作
Ø 如果设置为1,每次事务提交时,mysql都会把log buffer的数据写入log file,并且flush(刷新到磁盘)中
Ø 如果设置为2,每次事务提交时mysql都会把log buffer的数据写入log file,但是flush操作不会同时进行,该模式下mysql会每秒执行一次flush操作
3.2 参数意义说明:
sync_binlog=1
Ø sync_binlog的默认值是0,像操作系统刷其他文件的机制一样,mysql不会同步到磁盘中去而是依赖操作系统来刷新binary log
Ø 当sync_binlog=N(N>0),mysql在N次写入后,与磁盘进行同步
3.3 安全说明:
当innoDB_flush_log_at_trx_commit和sync_binlog都为1时是最安全的,在mysqld服务崩溃时,二进制日志只有可能丢失最多一个语句或者一个事务,但是双一标准会导致频繁的io操作,因此也是最慢的一种方式
当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。
当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失。
双1适合数据安全性要求非常高,而且磁盘IO写能力足够支持业务,比如订单,交易,充值,支付消费系统。双1模式下,当磁盘IO无法满足业务需求时 比如11.11 活动的压力。推荐的做法是 innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N为500 或1000) 且使用带蓄电池后备电源的缓存cache,防止系统断电异常。
系统性能和数据安全是业务系统高可用稳定的必要因素。我们对系统的优化需要寻找一个平衡点,合适的才是最好的,根据不同的业务场景需求,可以将两个参数做组合调整,以便是db系统的性能达到最优化。