mysql调优
DESCRIPTION
mysql tunning step by stepTRANSCRIPT
© 2011 绿盟科技www.nsfocus.comnsfocus.comwww.nsfocus.comnsfocus.com
MYSQL 性能优化
• 寻找问题
要优化数据库,先得知道数据库存在哪些问题,对症下药
问题包括下面三类,分而治之
• 硬件
• 软件
• MySQL
硬 件
与数据库性能相关的硬件资源
• CPU
• Memory
• Disk
• Network
必知必会的几个监控工具
• vmstat
• iostat
• netstat
• dstat
• top
• ifconfig
• vmstat
• iostat
• dstat
• netstat
配合上面的工具要能回答下面几个问题• I/O– I/O 负载是否高?
iostat tps 每秒 i/o 请求次数iostat %util 一秒钟内有多少时间用于 I/O 操作wa cpu 平均等待 IO 的时间
– 主要是读还是写? iostat r/s , w/s 很容易判断
– 是随机写还是顺序写? 顺序读写性能远高于随机读写 数据库文件涉及索引等内容,写入是随机写 binlog 文件是顺序写
• Memory– mem 使用率是否过高? 很容易判断, free , top , vmstat– mem 用在了哪?
各种 buffer&cache , 后面再细讲
• CPU– CPU 使用率是否过高? 很容易判断, top , vmstat
– 什么进程占用 cpu top
• Network– 带宽? dstat , ifconfig– 谁占用的带宽? iftop 、 tcpdump
软 件
• OS 可做的事情不多– 用主流的发行版( RHEL 、 Ubuntu 、 SLES )– kernel 版本 ( >=2.6.12 )– 用主流的文件系统 (ext3 , xfs)– 用 64-bit 架构系统( RAM>4G )– 其它的就不要碰了
MySQL
调优的过程也是一个寻找问题的过程
• MySQL 整体性能如何?瓶颈在哪?– show status– mysqlreport– tuning-primer.sh
• 系统中哪些查询最慢?– mysqldumpslow -s c -t 10 /var/lib/mysql/slowquery.log 查看 10 条出现最多的慢查询
• 当前哪些进程正在操作数据库?– Show processlist
• 某个查询是否使用了索引?效率是否足够高?– explain
• 一个查询,时间都花在了哪?– profiling
定位 mysql 的性能问题
寻找问题只是开始,更重要的还是解决问题。
下面才是我们的重点,涉及 MySQL 性能优化的诸多细节。
• 服务器调优
• Shcema 设计
• 查询优化
• 存储引擎优化
• 架构设计
目录
•服务器调优
• Tips
• 所有 MySQL 服务器调优的参数,都在 my.cnf 中设置。
• 所有参数的值都可以通过 show variables 查看 。
• 所有参数设置是否合理,都可以通过 show status 来判断。 也可以通过 mysqlreport 这样的工具帮助分析。
• 与性能相关的参数主要是 log ,以及各种 buffer & cache
log
•主要 log
• Error log 默认打开
• Binlog 一般都打开,增量备份和复制的基础
• Slow query log 需要调优时打开
• Query log 除非出于 debug 目的,否则肯定不开, I/O 消耗严重
• 各类日志相关的参数中,性能相关主要是两项– Binlog -- sync_log
– log_slow_queries -- long_query_time
log
• Binlog -- sync_log
只要系统不是对事务的安全性要求特别高,都将 sync_binlog 置为0 ,当 sync_binlog=1 时,事务的安全性最高,但是系统整体性能下降极为明显。
• log_slow_queries -- long_query_time.
慢查询的阈值,默认为 2 秒。最短可设置为 1 秒。记录慢查询日志会消耗 cpu 资源,需要对每次查询计算时间,只要 cpu 资源足够,影响不大。
我们的数据库中,默认为 2 秒, 2202630284 次查询中, 83692 次查询时间超过 2
秒,整体来说并不差。
mysqldumpslow -s c -t 5 /var/lib/mysql/slowquery.log 显示最慢的 5 条 SQL
Buffer & cache
Buffer & cache
Global buffer
query_cache
key_buffer
innodb_buffer_pool
thread_cache_size
table_open_cache
Thread buffer
sort_buffer
join_buffer
read_buffer
read_rnd_buffer
• 查询缓存 -> query_cache• MyISAM 索引缓存 -> key_buffer• InnoDB缓存 -> innodb_pool_buffer• 慢查询日志 -> log_slow • 日志优化 -> binlog_cache• 连接线程池 -> thead_cache• 文件描述符缓存 -> table_cache• 各类线程级 buffer -> sort/join/read_rnd/read buffer
• Query_cache
• 经验值 query_cache_size 设成 32 – 128 M
• 缓存命中率 = Qcache_hits/(Qcache_hits+Qcache_inserts) * 100 %
• query_cache_min_res_unit 合理值 = (query_cache_size-Qcache_free_memory
/Qcache_queries_in_cache
• 当 Qcache_lowmem_prunes持续增长,而 free memory 还比较大,说明 query cache 有很多碎片。
query cache
• Key_buffer
• key_buffer_size 分配给MyISAM 的索引缓存大小
• Key_buffer_size 的理想值 = 所有索引文件的大小
• Key_buffer_size 的经验值 = 25%- 33% RAM
• 查询命中率 = ( Key_read_requests- key_reads ) /Key_read_requests
• Key_blocks_used , Key_blocks_unused 显示 key_buffer 的实际使用情况
• innodb_buffer_pool
• 缓存 innodb 数据和索引
• Innodb_buffer_pool_size 理想值 = Innodb表数据文件大小+ 索引文件大小
• Innodb_buffer_pool_size 经验值 = 50% – 80% RAM
• Buffer 使用率 = Innodb_buffer_pool_pages_data/Innodb_buffer_pool_pages_total *
100%
• 查询命中率 =
(Innodb_buffer_pool_read_requests-Innodb_buffer_pool_reads)/Innodb_buffer_pool_r
ead_requests * 100%
• thread-cache
• 连接线程池
• Thread_cache_size经验值 = 8 - 12
• 连接线程缓存命中率 = (Connections - Threads_created) / Connections * 100%
• table_open_cache
• table_open_cache 经验值 = 64 – 2048
• open_tables 保证<= table_open_cache
解释 经验值 我们设置的大小sort_buffer_size 系统在排序时使用的
buffer2 – 16 M 8 M
join_buffer_size 当 Join 是 ALL index , rang 或index_merge 的时候使用的 Buffer
8M
read_buffer_size 顺序读 buffer 2M
read_rnd_buffer_size
随机读 buffer 16M
• Schema 设计
• 表结构设计• 限制表的数量
– 单库不超过300-400个表
• 限制单表数据量
– 一年内纯 int不超过1000W
– 一年内含char不超过500W
• 限制列的数量
– 单表字段数控制在20 – 50个
• 大字段垂直拆分
– TEXT处理性能远低于VARCHAR
– 尽量不用TEXT/BLOB类型字段
– 如必须使用,则拆分到单独的表中
• 反范式
– 适当冗余,减少关联查询
• 字段类型• 整型
TINYINT 、 INT 、 BIGINT
• 浮型FLOAT 、 DOUVBLE 、 DECIMAL 、 NUMERIC
• 时间日期DATETIME 、 DATE 、 TIMESTAMP
• 字符类型VARCHAR 、 CHAR 、 BLOB 、 TEXT 、 ENUM
• 原则• 选用更小的数据类型,减少存储空间
• 通过合适数据类型加速数据比较
• 字段设计• 将字符转为数字
– 用无符号 INT 存储 IP ,而非 CHAR(15)
– INET_ATON(’10.1.1.1’) = 167837953
– INET_NTOA(653235463) = 38.239.149.7
• 优先使用 ENUM或SET
– ENUM 占用 1 个字节
– SET视界节点,最多占用 8字节
– `sex` enum(‘F’,’M’)
• 避免使用 NULL字段– 很难进行查询优化
– NULL列添加索引需要额外空间
– 含NULL 复合索引无效
• 使用 timestamp 而不是 datetime
– UNIX_TIMESTAMP('2012-07-17 15:01:15') = 1342508475
– FROM_UNIXTIME(1342508475) = 2012-07-17 15:01:15
• SQL语句优化
• 索引
• 小结果集驱动大结果集
• http://vdisk.weibo.com/s/SMRp
• http://vdisk.weibo.com/s/4sEw-
• http://vdisk.weibo.com/s/gYYQ
•存储引擎
• MyISAM 表锁 不支持事务 Count() 快 内存占用和磁盘存储小
• InnoDB 行锁 支持事务 count() 慢内存占用和磁盘存储大
• 并发读高 MyISAM
• 并发写高 MyISAM
• 并发写高 +并发读高 InnoDB
• 架构设计
• Scalability
• HA
• Scale Up
• Scale Out
Replication
Sharding
Cluster
scalability
• Master - Slaves
replication
replication
• Master -- Master – Slaves -- Slaves
级联
• Sharding
垂直分区
水平分区
sharding
垂直分区
优点 :
• 拆分规则简单• 数据整合容易 • 维护方便
缺点 :
• 事务处理复杂 • 扩展性有瓶颈
水平分区
优点 :
• 应用程序端架构改动相对较少• 事务处理相对简单• 无扩展性限制
缺点 :
• 很难有满足全局的切分规则 • 数据维护复杂• 应用系统耦合度高
• 数据整合
自行研发
MySQL Proxy
Amoeba
数据整合
MySQL Proxy
• 连接路由 • 查询分析
• 查询过滤
• Load balance
• HA
Amoeba
• 数据切分后数据源整合 • 连接池
• 读写分离路由
与 MySQL Proxy比较:
优点:不需要自己写大量 lua script
缺点:作者个人维护,缺少社区支持
cluster
• HA
数据备份
Fail-over
HA
• keepalived
Replication
cluster
• 网络 RAID1
DRBD
谢谢!