MySQL是典型的三层架构模式,在日常使用中对MySQL问题排查和优化,也应该针对具体问题,从对应的层解决问题前端
max_connections参数用来设置最大链接 ( 用户 ) 数 。每一个链接MySQL的用户均算做一个链接,mysql
max_connections的默认值为100 。linux
MySQL不管如何都会为管理员保留一个用于登陆的链接,所以实际MySQL最大可链接数为面试
max_connections+1。sql
max_connections 最大为16384 。数据库
该参数设置太小的话,会出现”Too many connections”错误。后端
查看max_connections参数的方法:缓存
mysql> show variables like "max_connections";
修改最大可链接数的方法有:安全
# 方法一:即时生效,无需重启MySQL,重启失效 1.root登陆MySQL: $ mysql -uroot -p 2.查看当前的Max_connections参数值: mysql> SELECT @@MAX_CONNECTIONS AS 'Max Connections'; 3.设置该参数的值: mysql> set global max_connections = 200; # 方法二:须要重启MySQL,重启不失效,修改my.conf max_connections=200 # 方法三:编译MySQL的时候,设置默认最大链接数 1.打开MySQL源码,进入SQL目录,修改mysqld.cc文件: {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, 0}, 2. 编译三部曲 $ ./configure $ make $ make install
maxconnecterrors是一个MySQL中与安全有关的计数器值,它负责阻止过多尝试失败的客户端以防止暴力破解密码的状况。maxconnecterrors的值与性能并没有太大关系。bash
因为出现某台host链接错误次数等于maxconnecterrors , 日志中会出现相似blocked because of many connection errors 的信息,解决方法以下:
1.执行mysqladmin flush-hosts或者重启 MySQL服务,将错误计数器清零 2.my.cnf修改max_connect_errors的值,能够适当大些
是在特定场合下才能使用的,这个变量是针对Solaris系统的,若是设置这个变量的话,mysqld就会调用thr_setconcurrency()
.这个函数使应用程序给同一时间运行的线程系统提供指望的线程数目。
CPU核数的2倍,好比有一个双核的CPU,那么thread_concurrency
的应该为4;2个双核的cpu, thread_concurrency的值应为8。
这个参数是限制server容许通讯的最大数据包大小,有时候可能由于这个参数设置太小,比较大的insert或者update操做会失败,因此参数应该设置大一些
关键词缓冲区大小,缓存MyISAM索引块 ,决定索引处理速度,读取索引处理。
根据增大Key_reads / Uptime
来优化这个参数查看Key_reads / Uptime
的方法:
$ mysqladmin ext -ri10 | grep Key_reads
此参数用来缓存空闲的线程,以致不被销毁,若是线程缓存中有空闲线程,这时候若是创建新链接,MYSQL就会很快的响应链接请求。
使用 show status查看当前mysql链接状况 :
mysql>SHOW STATUS WHERE Variable_name LIKE '%Thread%'; Threads_cached:表明当前此时此刻线程缓存中有多少空闲线程。 Threads_connected:表明当前已创建链接的数量,由于一个链接就须要一个线程,因此也能够当作当前被使用的线程数。 Threads_created:表明从最近一次服务启动,已建立线程的数量。 Threads_running:表明当前激活的(非睡眠状态)线程数。并非表明正在使用的线程数,有时候链接已创建,可是链接处于sleep状态,这里相对应的线程也是sleep状态。
建议threadcachesize设置成与threads_connected同样 。
每一个链接须要使用 buffer 时分配的内存大小,不是越大越好。例 : 1000个链接 , 一个1MB,会占用1GB内存,200WX1MB=20GB
为了减小参与 join 的 ” 被驱动表 “的读取次数以提升性能 , 须要使用到join buffer来协助完成 join 操做当 join buffer 过小,MySQL 不会将该buffer存入磁盘文件而是先将join buffer中的结果与需求join的表进行操做,而后清空 join buffer 中的数据,继续将剩余的结果集写入次buffer中,如此往复,这势必会形成被驱动表须要被屡次读取,成倍增长IO访问,下降效率 。
查询缓存大小,再查询时返回缓存,缓存期间表必须没有被更改,不然缓存失效,多写入操做的话设置大了会影响写入效率。
mySQL用于查询的缓存的内存被分红一个个变长数据块,用来存储类型,大小,数据等信息。 当服务器启动的时候,会初始化缓存须要的内存,是一个完整的空闲块。当查询结果须要缓存的时候,先从空闲块中申请一个数据块大于参数querycacheminresunit的配置,即便缓存数据很小,申请数据块也是这个,由于查询开始返回结果的时候就分配空间,此时没法预知结果多大。
配内存块须要先锁住空间块,因此操做很慢,MySQL会尽可能避免这个操做,选择尽量小的内存块,若是不够,继续申请,若是存储完时有空余则释放多余的。 缓存存放在一个引用表中,经过一个哈希值引用,这个哈希值包括查询自己,数据库,客户端协议的版本等,任何字符上的不一样,例如空格,注释都会致使缓存不命中。
当查询中有一些不肯定的数据时,是不会缓存的,比方说now(),current_date(),自定义函数,存储函数,用户变量,字查询等。因此这样的查询也就不会命中缓存,可是还会去检测缓存的,由于查询缓存在解析SQL以前,因此MySQL并不知道查询中是否包含该类函数,只是不缓存,天然不会命中。 缓存存放在一个引用表中,经过一个哈希值引用,这个哈希值包括查询自己,数据库,客户端协议的版本等,任何字符上的不一样,例如空格,注释都会致使缓存不命中。
这个参数是MySQL读入缓冲区的大小,将对表进行顺序扫描的请求将分配一个读入缓冲区,mysql会为它分配一段内存缓冲区,readbuffersize变量控制这一缓冲区的大小,若是对表的顺序扫描很是频繁,并你认为频繁扫描进行的太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能,read_buffer_size
变量控制这一提升表的顺序扫描的效率 数据文件顺序。
这个参数是MySQL的随机读缓冲区大小,当按任意顺序读取行时(列如按照排序顺序)将分配一个随机读取缓冲区,进行排序查询时,MySQL会首先扫描一遍该缓冲,以免磁盘搜索,提升查询速度,若是须要大量数据可适当的调整该值,但MySQL会为每一个客户链接分配该缓冲区因此尽可能适当设置该值,以避免内存开销过大。表的随机的顺序缓冲 提升读取的效率。从排序好的数据中读取行时,行数据从缓冲区读取的大小,会提高order by性能 注意:MySQL会为每一个客户端申请这个缓冲区,并发过大时,设置过大影响内存开销。
MyISAM表发生变化时,从新排序所需的缓存。
InnoDB 使用缓存保存索引,保存原始数据的缓存大小,能够有效减小读取数据所需的磁盘IO。
数据日志文件大小,大的值能够提升性能,但增长了恢复故障数据库的时间(恢复故障数据库时须要读取数据日志文件,当日志过大会致使时间过长)。
日志文件缓存,增大该文件能够提升性能,但增大了突然宕机后损失数据的风险(日志文件在缓存中,还没来得及存进硬盘就断电了)。
执行事务的时候,会往InnoDB存储引擎的日志缓存插入事务日志,写数据前先写日志(预写日志方式)设置为0,实时写入;当设置为1时,缓存实时写入磁盘;2时,缓存实时写入文件,每秒文件实时写入磁盘。
回滚前(当一个事务被撤销时),一个InnoDB事务,应该等待一个锁被批准多久,当InnoDB没法检测死锁时,这个值就有用了。
MyISAM 索引顺序访问方法,支持全文索引,非事务安全,不支持外键,会加表级锁存在三个文件:
InnoDB 事务型存储引擎,加行锁,支持回滚,崩溃恢复,ACID事务控制,表和索引放在一个表空间里头,表空间多个文件。
例:
update tableset age=3 where name like "%jeff%"; //会锁表
给合适的列表创建索引,给where子句,链接子句创建索引,而不是select选择列表索引值应该不相同,惟一值时效果最好,大量重复效果不好使用短索引,指定前缀长度char(50)的前20,30值惟一例。文件名索引缓存必定(小)时,存的索引多,消耗IO更小,能提升查找速度最左前缀n列索引,最左列的值匹配,更快。
like查询,索引会失效,尽可能少用like。百万、千万数据时,用like Sphinx开源方案结合MySQL不能滥用索引。
“” 和 NULL问题
{“name”:”myf”} {“name”:””} {“hobby”:空array}
NULL占空间
例:安卓须要判断””仍是NULL
Java和OC都是强类型,会形成APP闪退
写文件:文件延迟写入机制,先把文件存放到缓存,达到必定程度写进硬盘。
读文件:同时读文件到缓存,下次须要相同文件直接从缓存中取,而不是从硬盘取。
本地缓存:数据防盗服务器内存的文件中。
分布式缓存:Redis, Mencache 读写性能很是高,QPS(每秒查询请求数)每秒达到1W以上;数据持久化用Redis,不持久化二者均可以。
日志和数据分开存储,日志顺序读写 – 机械硬盘,数据随机读写 – SSD
能够调参数
#操做系统禁用缓存,直接经过fsync方式将数据刷入机械硬盘 innodb_flush_method = O_DIRECT # 控制MySQL中一次刷新脏页的数量,SSD io 加强,增大一次输入脏页的数量 innodb_in_capacity = 1000
水平拆分:数据分红多个表拆分后的每张表的表头相同。
垂直拆分:字段分红多个表。
插入数据、更新数据、删除数据、查询数据时:MyISAM MERGE存储引擎,多个表合成一个表,InnoDB用alter table,变成MyISAM存储引擎,而后MEGRE。
面试题:MERGE存储引擎将N个表合并,数据库中如何存储?答: 真实存储为N个表,表更大的话就须要分库了。
读是一些机器,写是一些机器,二进制文件的主从复制,延迟解决方案。数据库压力大了,能够把读和写拆开,对应主从服务器,主服务器写操做、从服务器是读操做。大多数业务是读业务。京东、淘宝大量浏览商品、挑选商品是读操做(多),购买是写操做(少)。主服务器写操做的同时,同步到从服务器,保持数据完整性——主从复制。
主从复制原理:基于主服务器的二进制日志(binlog)跟踪全部的对数据库的完整更改实现要实现主从复制,必须在主服务器上启动二进制日志主从复制是异步复制。
三个线程参与:主服务器一个线程(IO线程)、从服务器两个(IO线程和SQL线程)
主从复制过程:
弊端:延迟
主从复制延迟解决方案:
Cobar方案:阿里开源(后续无更新)
MyCat基于Cobar,MySQL通信协议,代理服务器,无状态,容易部署,负载均衡。
原理:应用服务器传SQL语句,路由解析,转发到不一样的后台数据库,结果汇总,返回MyCat把逻辑数据库和数据表对应到物理真实的数据库、数据表,遮蔽了物理差别性。
MyCat工做流程:
慢查询:指执行超过必定时间的SQL查询语句记录到慢查询日志,方便开发人员查看日志
找问题:
long_qeury_time定义慢查询时间 slow_query_log设置慢查询开关 slow_query_log_file设置慢查询日志文件路径
设置方法1:
set log_query_time = 1; set slow_query_log = on; set slow_query_log_file = '/data/slow.log'
设置方法2:
/etc/my.comf设置参数
分析:
explain命令进行分析,输出结构含义,官方文档。