运维知识体系

运维知识体系

运维知识体系总结,持续更新,欢迎转载。
缓存知识体系

缓存知识体系

运维知识体系之缓存,分层多级缓存体系。
DevOps学院

DevOps学院

全新体系化课程,开启运维新征程!
基础设施实践指南

基础设施实践指南

KVM、OpenStack、Docker、Kubernetes

mysql-5.5.32 make 错误

回复

MySQL新月竖 发起了问题 • 1 人关注 • 0 个回复 • 79 次浏览 • 2020-06-19 21:12 • 来自相关话题

mysql-5.5.32 make 错误

回复

MySQL新月竖 发起了问题 • 2 人关注 • 0 个回复 • 56 次浏览 • 2020-06-19 20:25 • 来自相关话题

MySQL5.7参数调优(涵部分参数具体解释)

MySQLl_ning 发表了文章 • 0 个评论 • 298 次浏览 • 2020-05-22 00:11 • 来自相关话题

前言:全文中一共有常用的(事实上你如果花1-2周阅读、理解、自己动手设一下后是需要这么多参数的)76个参数,笔者把近10年里3个亿万级项目的数据库调优用此篇浓缩到了可能读者只需要2周时间就可以掌握,同时我是按照: 每一个参数干吗? ...查看全部
前言:全文中一共有常用的(事实上你如果花1-2周阅读、理解、自己动手设一下后是需要这么多参数的)76个参数,笔者把近10年里3个亿万级项目的数据库调优用此篇浓缩到了可能读者只需要2周时间就可以掌握,同时我是按照:

每一个参数干吗?
在某些典型硬件配置下的db上参数该设多少?
设会怎么样?
不设会怎么样?
有什么坑如何填坑?
有些参数怎么算、算法又如何

这种style来写的,相信此篇会对一些使用mysql的尤其是正在或者将要面临万级并发的项目、网站有所帮助。具体请看文档!

一千个DBA就有一千种配置方式!

大家一定记得不要轻易去看网上,要看只看官网!网上很多博客都是错的,连参数都列错了,5.7很多参数和5.6是完全不一样的。

可能你从未看到过这样的一篇集中火力式的把mysql参数列了这么全的文章,很有兴曾参与过超3万并发的18~19年的数轮520、618、双11、双12保卫战。因此这一篇是汇集了最精华和实战的内容把mysql所有的参数列在这边供大家参考。并且以(64c cpu,128gb内存)的mysql cpu和内存来进行了一轮配置。而此文的内存相关参数部分可以延展至256gb~512gb。

另外有一点,建议在mysql的服务器上使用ssd。除非并发数永远控制在500-1000内那就没必要使用ssd,普通高速磁盘就可以了。

你会发觉这篇文章是一篇宝藏,这些参数都能够自己动手试验一篇基本在外面是可以吊打mysql面试官了。

client域:

1.character_set_client

推荐设置:

utf8mb4

作用:

字符集设定,如果前台有连social mobile application一类包括wechat,并且允许有使用emoji表情的,请开启成utf8mb4

如果不配的后果:

mysql不支持前端app存表情等字符

配置实例:

character_set_client=utf8mb4

mysqld域:

1)server-id

推荐设置:

如果没有做任何主从复制,此值可以不设。

作用:

遇有主从复制,必设该值,每个参与主从复制的mysql实例的server-id不能重复,必须为阿拉伯数字。

如果不配的后果:

如果你用的是主从复制,这个id不设那么整个mysql的主从复制会失几。

配置实例:

server-id=1

2)port

推荐设置:

3306

作用:

mysql实例端口

如果不配的后果:

默认为3306

配置实例:

port=3306

3)bind_address

推荐设置:

0.0.0.0

作用:

除非有特殊需要,我们会限制只允许mysql实例被某一个ip方问,不支持多个,生产上都为:0.0.0.0然后使用防火墙策略来控制。

如果不配的后果:

默认不允许远程登录

配置实例:

bind_address=0.0.0.0

4)autocommit

推荐设置:

1

作用:

生产上开启成1,如果你开启的是0会有一个这样的情况:

a运行一条insert语句,并未作commit;b去做查询此时b是查询不到的。这种操作一般用于在写store procedure时用到。

如果不配的后果:

如果在系统的my.cnf层面把它设成了0,如果在使用时(99%情况是用的1)时,你想要用root在生产运行时把它设成set autocommit = 1都开启不了。而如果你在一开始就没它设置成1,那么当碰到某些特殊场景特别是写store procedure时需要把它设成0时,你是可以手动临时把某一个session给开在0的。

配置实例:

autocommit = 1

5)character_set_server

推荐设置:

utf8mb4

作用:

字符集设定,如果前台有连social mobile application一类包括wechat,并且允许有使用emoji表情的,请开启成utf8mb4

如果不配的后果:

mysql不支持前端app存表情等字符

配置实例:

character_set_server=utf8mb4

6)skip_name_resolve

推荐设置:

1

作用:

生产上建议开启成1,这样mysql server不会对客户端连接使用反向dns解析,否则客户端连上后有时在遇有生产高速运行时直接timeout,如果设成了1带来的问题就是你不能在mysql中使用主机名来对客户端权限进行划分,而是需要使用ip。

如果要做成即允许mysql里允许使用主机名来分配客户端连接权限,又要做到不要让mysql去做dns解析,可以在mysql所在主机端的/etc/hosts文件中写上客户端的主机名,因为当客户端连接连上来时,mysql反向查找客户端连接时的域名解析的步骤是:首先查找 /etc/hosts 文件,搜索域名和IP的对应关系。但是这样做也有一个问题,那就是如果你有多个客户端多个mysql主从关系,哪到你要把mysql做成一个dns解析器吗?因此推荐设成1

如果不配的后果:

mysql server每一次会对客户端连接使用反向dns解析,经常会出现客户端连上后有timeout现象。

配置实例:

skip_name_resolve=1

7)max_connections

推荐设置:

20,000

作用:

最大连接数,以微品会:前端3万的tps并发,假设redis命中失效50%(这是灾难),那么后端mysql单个主或从开启连接数为:20,000,我们公司在前端并发曾达到过6万,80%被waf、vanish、缓存挡掉,落在db上的qps最高一次为20,000连接,再按照mysql官方,max_connections值受系统os最大打开连接数限制,因此我们需要做以下2步操作:

1)在 /etc/security/limits.conf 底部增加2行

mysql hard nofile 65535
mysql soft nofile 65535
2)在/usr/lib/systemd/system/mysqld.service(视如何安装mysql所决定,用编译安装和yum安装会产生path路径不同。)文件最后添加:

LimitNOFILE=65535
LimitNPROC=65535
$ systemctl daemon-reload
$ systemctl restart mysqld.service
如不生效重服务器。

如果不配的后果:

默认只有150

配置实例:

max_connections = 20,000

8)max_connect_errors

推荐设置:

生产上设10

开发测试上使用默认-100

作用:

生产上开启成10次,开发测试上使用默认即不设。

max_connect_errors是一个MySQL中与安全有关的计数器值,它负责阻止过多尝试失败的客户端以防止暴力破解密码的情况。如果需要设置此数值,手动添加。当此值设置为10时,意味着如果某一客户端尝试连接此MySQL服务器,但是失败(如密码错误等等)10次,则MySQL会无条件强制阻止此客户端连接。相关的登录错误信息会记录到performance_schema.host_cache表中。如果希望重置此计数器的值,则必须重启MySQL服务器或者执行

Mysql> FLUSH HOSTS;

1 Mysql> FLUSH HOSTS;

当这一客户端成功连接一次MySQL服务器后,针对此客户端的max_connect_errors会清零。可以在防火墙上做策略限制某些ip的远程连接。

如果不配的后果:

默认为100

配置实例:

max_connect_errors =10

9)innodb_flush_log_at_trx_commit

推荐设置:

2

作用:

(核心交易系统设置为1,默认为1,其他2或者0),

0代表:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。

1代表:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认(因此会保留每一份redo日志)

2代表:每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。该模式速度较快,也比0安全,只有在操作系统崩溃或者系统断电的情况下,上一秒钟所有事务数据才可能丢失。

除非你用的是小型机或者是超大规模mysql集群一类如:游戏行业,那么需要保留每一秒的事务,否则请设成2,要不然会严重影响系统性能。这个参数是5.6所没有的。

如果不配的后果:

默认为1,影响系统写性能。

配置实例:

innodb_flush_log_at_trx_commit=2

10)transaction_isolation

推荐设置:

READ-COMMITTED

作用:

此参数直接决定了mysql的性能,oracle中的事务默认级别就是read-commited,而mysql的默认级别是:repeatable-read,它利用自身独有的Gap Lock解决了"幻读"。但也因为Gap Lock的缘故,相比于READ-COMMITTED级别的Record Lock,REPEATABLE-READ的事务并发插入性能受到很大的限制。离级别的选择取决于实际的业务需求(安全与性能的权衡),如果不是金融、电信等事务级别要求很高的业务,完全可以设置成transaction_isolation=READ-COMMITTED。
Repeatable-read: 这是MySQL的InnoDB引擎默认的隔离级别,它阻止查询的任何行被其他事务更改。因此,阻塞不可重复读,而不是幻读。也就是说在可重复读中,可能会出现幻读。重复读使用一种中等严格的锁定策略,以便事务中的所有查询都能看到来自相同快照(即事务启动时的数据)的数据。当拥有该级别的事务执行 UPDATE ... WHERE, DELETE ... WHERE, SELECT ... FOR UPDATE和LOCK IN SHARE MODE操作时,其他事务可能需要等待。
Read-Committed-推荐: 事务无法看到来自其他事务的未提交数据,但可以看到当前事务启动后另一个事务提交的数据。当拥有这种级别的事务执行 UPDATE ... WHERE or DELETE ... WHERE操作时,其他事务可能需要等待。但是该事务可以执行 SELECT ... FOR UPDATE, and LOCK IN SHARE MODE操作,其他事务不需要等待。
串行化(SERIALIZABLE)-极力不推荐,串行化隔离级别是最高的隔离级别,它使用了最保守的锁策略。它阻止任何其他事务插入或更改此事务读取的数据,直到该事务完成。简单的来说,就是一个事务一个事务的来执行,显然性能会很低。在这种隔离级别下,一个事务中的相同查询可以反复执行,每次查询结果是一样的。从当前事务开始执行,任何更改另一个事务提交的数据的尝试都会导致当前事务等待(阻塞)。这是SQL标准指定的默认隔离级别(注意不是MySQL)。在实践中,这种严格程度是很少需要的。
读未提交(READ-UNCOMMITTED)-它是最低的隔离级别,虽然性能最高,但也不推荐
它会读取到其他事务修改尚未提交的数据,使用此隔离级别就需要非常小心,认识到这种级别下的查询结果可能不一致或不可复制,这取决于其他事务同时在做什么。通常,具有此隔离级别的事务只执行查询,而不执行插入、更新或删除操作。
在实际环境中,应当根据是否允许出现脏读(dirty reads),不可重复读(non-repeatable reads)和幻读(phantom reads )现象而选择相应的隔离级别。例如在大数据中,少量的数据不一致不会影响到最后的决策,这种情况下可以使用较低的隔离级别以提交性能和并发性。
如果不配的后果:

默认就是repeatable-read

配置实例:

transaction_isolation = READ-COMMITTED

11)explicit_defaults_for_timestamp

推荐设置:

1

作用:

mysql5.7默认对于timestamp字段会显示“系统当前日期”,就算你在插表时这个timestamp字段留空,它在select出来时也会显示系统日期。因此,这个值的影响范围是你在建表时导致的。
系统默认这个值是0,在0的情况下,你要让该表的timestamp字段在为null时不显示系统默认时间,你的建表必须为:create table order(o_id int ,updateed_time timestamp null default null) ;
explicit_defaults_for_timestamp 变量会直接影响表结构,也就是说explicit_defaults_for_timestamp的作用时间是在表定义的时候;你的update | insert 想通过它去改变行为已经太晚了!
因此,我推荐把这个值设为1.
如果不配的后果:

默认为0

配置实例:

explicit_defaults_for_timestamp = 1

12)join_buffer_size

推荐设置:

16M

作用:

系统默认大小为:512k,mac下默认大小为:256k,针对128GB,1万并发的mysql我推荐给到的值为:8~16M
对于JOIN KEY 有索引和二级索引,JOIN KEY 无索引mysql会使用到join_buffer_size,一般建议设置一个很小的 GLOBAL 值,完了在 SESSION 或者 QUERY 的基础上来做一个合适的调整。如果你拍脑袋给也个4g,我们有1000个并发,就是用掉了4T的内存。。。4T啊。。。你以为你是小型机。适当的去改变它确实可以带来一定的提速,但并不是说很多值越大越好,为什么我们设置成4m呢?我们假设我们的mysql所在的vm是128gb,一根这样的join(如果被用到)是4M,1万个也不过用掉40G,而根据官方说法,total加在一起产生的join_buffer_size不要超过你所在系统的50%.默认512k肯定是小了点,我们可以适当放宽,比如说:2M,在实际使用场景时我们发觉有这样的高频操作(要看高频出现的有意义的sql的执行计划,并确认该计划的:执行cost如:"query_cost": "1003179606.87",它产生的cost为:0.93个G,如果它真的很高频出现在调优sql到无法调优的程度,我们会去做set session join_buffer_size = 1024 * 1024 * 1024;这样的操作。而不是在一开始的my.cnf中去分配一个暴大的值,我们这边基于128gb,1万connection的并发来说,你给个16M不算小也不算多,我推荐给到8~16M间(这是指在一开始)。
如果不配的后果:

默认的为256k

配置实例:

join_buffer_size = 16M

13)tmp_table_size

推荐设置:

67108864

作用:

如果是128gb内存的服务器,我建议是在my.cnf中设成64M
通过设置tmp_table_size选项来增加一张临时表的大小,例如做高级GROUP BY操作生成的临时表。默认系统为32M,如果当你的临时表越来越多加在一起超过了这个值,那么mysql会在系统磁盘上创建,这个值不是越多越好,也没有一个合适的值。一开始的建议为>64M,然后在运行时我们通过以下公式来做临时调优,
show global status like 'created_tmp%';
把得到的结果中的:(Created_tmp_disk_tables / Created_tmp_tables) * 100% 如果<=25%为最佳值。注意了,在生产时热设定时一定要用类似以下算法:
set global tmp_table_size=64*1024*1024而不是set global tmp_table_size=64M。
如果不配的后果:

默认为32M

配置实例:

tmp_table_size = 67108864

14)tmpdir

这块参数可以让运维给到,放到大空间里就行了,没什么太敏感的。

15)max_allowed_packet

推荐设置:

134217728

作用:

如果你经常在应用层碰到了:Got a packet bigger than'max_allowed_packet' bytes,这时你可以使用
show variables like '%max_allowed_packet%';来查看这个值,这个值没有合适,一般如:用客户端导入数据的时候,遇到 错误代码: 1153 - Got a packet bigger than 'max_allowed_packet' bytes 终止了数据导入。这样的场景下,当MySQL客户端或mysqld服务器收到大于max_allowed_packet字节的信息包时,将发出“信息包过大”错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,可能会遇到“丢失与MySQL服务器的连接”错误。
客户端和服务器均有自己的max_allowed_packet变量,因此,如你打算处理大的信息包,必须增加客户端和服务器上的该变量。一般情况下,服务器默认max-allowed-packet为1MB,可以通过在交换机上抓包或者是图形化分析来抓返回结果判断。一般推荐在128gb内存下设置的置为128M.也可以在运行时动态调整:set global max_allowed_packet = 128*1024*1024
如果不配的后果:

1M

配置实例:

max_allowed_packet = 134217728

16)sql_mode

不需要去设置,使用默认的,这块和性能无关。我们的中台中的sql如果碰到有sql报错,因该是在测试环境上就已经报了,它的作用是用来约束你sql的写法的,如果是一个从头开始开发的应用,我们比如说约束好都是ansi sql写法,对于一个产品,不要去做这种画蛇添足的做法。

17)interactive_timeout

推荐设置:

600

作用:

单位为s,系统默认为:28800s即8小时。如果这2个值太大,你会发觉在mysql中有大量sleep的连接,这些连接又被称为:僵尸连接,僵尸连接一多你真正要用的时候就会抛:too many connection这样的错,因此对于长久不用的连接,我们一般要使用“踢出机制”,多久对于一个活动累的sql进行踢呢?我们说如果有一个长事务,它要执行1小时,我不知道这是不是属于正常?当然如果你设了太短,说1分钟就把它踢了,还真不一定踢的对,按照我们在oracle中设置的best practice我们都会把它放到10分钟。你有一条sql连着,10分钟不用,我就把它踢了,这也算正常。但是在高并发的场景下这个timeout会缩短至3-5分钟,这就是为什么我提倡我们的非报表即时类查询需要优化到sql的运行时间不超过300ms的原因,因为在高并发场景下,超过500ms的sql都已经很夸张了。保守点我觉得可以设成10分钏,在应用端由其通过jdbc连接数据库的,做的好的应用都会在jdbc里有一个autoconnect参数,这个autoconnect参数就要和mysql中的wait_timeout来做匹配了。同时在应用端要有相应的validate sql一类的操作来keep alived。不过我更推荐使用”连接池内连接的生存周期(idleConnectionTestPeriod)”来做设置,把这个置设成 interactive_timeout:交互式连接超时时间(mysql工具、mysqldump等)
wait_timeout:非交互式连接超时时间,默认的连接mysql api程序,jdbc连接数据库等
interactive_timeout针对交互式连接,wait_timeout针对非交互式连接。所谓的交互式连接,即在mysql_real_connect()函数中使用了CLIENT_INTERACTIVE选项。
show global variables like 'wait_timeout';
1 timeout 只是针对空闲会话有影响。

2 session级别的wait_timeout继承global级别的interactive_timeout的值。而global级别的session则不受interactive_timeout的影响。

3 交互式会话的timeout时间受global级别的interactive_timeout影响。因此要修改非交互模式下的timeout,必须同时修改interactive_timeout的值。

4 非交互模式下,wait_timeout参数继承global级别的wait_timeout。

如果不配的后果:

系统默认为28800

配置实例:

interactive_timeout = 600

18)wait_timeout

同interactive_timeout,两个值都设成一样。

19)read_buffer_size

推荐设置:

4194304

作用:

这个值其实轻易是用不到的,因为,它只对2种场景的full table scan产生影响而不是所有的full table scan,同时从mysql5.6以后开始没有数据块多块读的功能,与是否设置 read_buffer_size参数无关。应用场景:

1)SELECT INTO … OUTFILE ‘fileName‘

2)When filesort is used, during merge buffers and when merged results are written to a temporary file, then writes are buffered

一般保留默认:64k,保守作法是设置在1~4M,不过它的应用场景很有限,对于互联网场景真的不太用,我推荐设成4M

如果不配的后果:

默认为64k

配置实例:

read_buffer_size = 4194304

20)read_rnd_buffer_size

推荐设置:

8388608

作用:

就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取,进而使用到 read_rnd_buffer_size 参数所设置的内存缓冲区。它的默认为256k,最大可以设到2G,它会对order by关键字起作用,当order by的计划成本超出了sort_buffer_size后,mysql会产用随机读取并消耗额外的内容,很多外面的博客说它是只对myisam引擎起作用,但其实不是,该参数还真的覆盖到所有引擎,一般它的推荐设置在8-16M,我推荐8M,根据sql分析计划如果碰到高频的查询且order by的返回包体都很大,那么再在session级别去放。

如果不配的后果:

默认为256k

配置实例:

read_rnd_buffer_size = 8388608

21)sort_buffer_size

推荐设置:

4194304

作用:

每个会话执行排序操作所分配的内存大小。想要增大max_sort_length参数,需要增大sort_buffer_size参数。如果在SHOW GLOBAL STATUS输出结果中看到每秒输出的Sort_merge_passes状态参数很大,可以考虑增大sort_buffer_size这个值来提高ORDER BY 和 GROUP BY的处理速度。建议设置为1~4MB。当个别会话需要执行大的排序操作时,在会话级别增大这个参数。所谓会话级别,我举个例子,你拍脑袋一下,说我设个32M,你所它乘10,000请求,这得多大内存。另外,千万要注意,在mysql内存,当你的sort_buffer_size在超过2K时在底层使用的是mmap()的c函数去做内存分配的,而不是malloc(),做过c的都知道mmap()是一个矢量单位,因此它会付出性能的影响,能影响多少呢?单条sql影响值在30%。

如果不配的后果:

默认值为1M

配置实例:

sort_buffer_size =4194304

22)innodb_page_size

推荐设置:

8192

作用:

这个值可要小心,一般它在设置后就不能轻易改了,一般来说我们都认为,值越大越好,不是的, 这个值它的原理是这样的:size越小,内存划分粒度越大,使用率越高,但是会有其他问题,就是限制了索引字段还有整行的大小。innodb引擎读取内存还有更新都是一页一页更新的,这个innodb_page_size决定了,一个基本页的大小。常用B+Tree索引,B+树是为磁盘及其他存储辅助设备而设计一种平衡查找树(不是二叉树)。B+树中,所有记录的节点按大小顺序存放在同一层的叶子节点中,各叶子节点用指针进行连接。MySQL将每个叶子节点的大小设置为一个页的整数倍,利用磁盘的预读机制,能有效减少磁盘I/O次数,提高查询效率。如果一个行数据,超过了一页的一半,那么一个页只能容纳一条记录,这样B+Tree在不理想的情况下就变成了双向链表。我们拿白话来说就是:你越大,空间利用率更高,但是越小呢越有助于性能但是这边一定一定有一个“但是”,但是小到一定的量反而性能不好,为什么呢?太大上面我已经举例了,太小。。。mysql的页间的check point太频繁。怎么样做才能达到一个合理值呢?
这个我们是在全真生产环境、全数据量下用测试工具去对4k,8k,16k三种场景压测得到的吞吐量即tps来做观察的,我这边可以给出一个推荐值,以单表超1000w条数据基于中台1.1的数据库结果(每个表都超1000w),我们在设置该值为:8K时,它的吞吐达到最优。
如果不配的后果:

32位下默认为8192

64位下默认为16384

配置实例:

innodb_page_size = 8192

23)innodb_buffer_pool_size

推荐设置:

72G

作用:

这个值和innodb_buffer_pool_instances相辅相成。在32位机器下,innodb_buffer_pool_instances一般为1,在64位机器上,这个值为8-64.

pool_instances其实为cpu核数,它的作用是:

1)对于缓冲池在数千兆字节范围内的系统,通过减少争用不同线程对缓存页面进行读写的争用,将缓冲池划分为多个单独的实例可以提高并发性。

2)使用散列函数将存储在缓冲池中或从缓冲池读取的每个页面随机分配给其中一个缓冲池实例。每个缓冲池管理自己的空闲列表, 刷新列表, LRU和连接到缓冲池的所有其他数据结构,并受其自己的缓冲池互斥量保护。

innodb_buffer_pool_size的设置需要为pool_instance的整数倍。

网上很多说innodb_buffer_pool_size为系统的70%,这是错的!因为你真的设了70%你的swap空间会被挤压,你不要忘了你还有os,上面还可能有监控agent端。一旦swap空间被挤压后你的mysql反面严重拖慢读写。

此处强烈建议设成内存的20%-65%间(独立的mysql服务器),为什么有一个20%呢?对于<4gb的mysql用服务器来说按照20%系统内存来设置。由于我们是128gb的内存,此处我建议使用72G,如果内存超过128gb,一般我们会把pool instance设成16个,每个开启10g左右的buffer_pool_size,对于256gb内存的服务器来说我们可以这样设。

如果不配的后果:

默认为64

配置实例:

innodb_buffer_pool_size = 72G

24)innodb_buffer_pool_instances = 8

这个参数同innodb_buffer_pool_size一起讲解了。

25)innodb_buffer_pool_load_at_startup

推荐设置:

0

作用:

这两个参数几乎没人用一般dba也不曾听说过,它是什么意思呢?Mysql在第一次(重启)时,它的buffer_pool_size中是空的,随着mysql运行时间1-2小时后,它的buffer_pool_size里开始被塞入东西,它分为old block与new block,而此时mysql性能开始一点点读写效率上去了,那是因为在buffer_pool_size没有放入东西时,mysql很多读写发生在硬盘上,从硬盘到内存的加载过程是一个比较漫长和耗时的过程,因此我们往往会设一个startup=1以加快这个“预热”过程,它与参数shutdown配合使用,即相当于把上次使用的innot_db_buffer_pool里的东西在启动时先做一次加载,以加快mysql的性能。它会在innodb的数据目录中生成一个文件:ib_buffer_pool。高度注意:加入了startup和shutdown=1时,mysql的启动过程会比较慢,如果你上次的dump出的buffer_pool里的东西有50多g那么mysql启动时的加载过程会变得比较慢。这个值很多人使用默认的0(不开启),它的影响就是你在mysql重启后,一开始你的系统读写性能不如在你系统运行了2-4小时(视db读写而定)反而它的读写性能变好了。不设使用默认值(0)。

如果不配的后果:

不配的话系统默认为0

配置实例:

innodb_buffer_pool_load_at_startup = 0

26)innodb_buffer_pool_dump_at_shutdown

同上面的startup参数以及解说

27)innodb_lru_scan_depth

推荐设置:

2000

作用:

innodb_io_capactiy 在sas 15000转的下配置800就可以了,在ssd下面配置2000以上。

可使用默认配置。即不设。

如果不配的后果:

默认为200,db吞吐量上不去。

配置实例:

innodb_lru_scan_depth = 2000

28)innodb_lock_wait_timeout

推荐设置:

60

作用:

我们一般会碰到,mysql innodb_lock_wait_timeout这个错,这个错是慢sql导致,它代表的是慢sql的事务锁超过了mysql锁超时的设置了。默认这个值为:50s,这个值是可以动态改变的,我不建议去改这个值,因为一个sql能达50s这得多夸张?

动态改变命令如下:

SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

SET GLOBAL innodb_lock_wait_timeout=500;

SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';

把它设成60s足够了。

如果不配的后果:

默认为50s

配置实例:

innodb_lock_wait_timeout = 60

29)innodb_io_capacity_max

推荐设置:

8000

作用:

这个值很重要,它对读无效,对写很有决定意义。
它会直接决定mysql的tps(吞吐性能),这边给出参考:sata/sas硬盘这个值在200. sas raid10: 2000,ssd硬盘:8000, fusion-io(闪存卡):25,000-50,000
本调优基于的是ssd,此值设置为8000,笔者上一家公司互联网金融是把一整个mysql扔到了闪存卡里的,因此设置的值为:50,000.
需要根据paas或者是ias的vm的硬盘性号来定
如果不配的后果:

默认为200,系统吞吐上不去。

配置实例:

innodb_io_capacity_max = 8000

30)innodb_io_capacity

它是io_capacity_max的一半,同样,它对读无效对写有决定意义。

配置实例:

innodb_io_capacity_max = 4000

31)innodb_flush_method

推荐设置:

O_DIRECT

作用:

推荐使用O_DIRECT。让我们一起来理解一下,它有3种模式:

1)fdatasync,上面最常提到的fsync(int fd)函数,该函数作用是flush时将与fd文件描述符所指文件有关的buffer刷写到磁盘,并且flush完元数据信息(比如修改日期、创建日期等)才算flush成功。它对磁盘的io读写会很频繁

2)O_DIRECT则表示我们的write操作是从mysql innodb buffer里直接向磁盘上写,它会充分利用缓存

3)_DIRECT模式的free内存下降比较慢,因为它是据文件的写入操作是直接从mysql innodb buffer到磁盘的,并不用通过操作系统的缓冲,而真正的完成也是在flush这步,日志还是要经过OS缓冲,O_DIRECT在SQL吞吐能力上较好。

如果不配的后果:

它的默认值为fdatasync。

配置实例:

innodb_flush_method = O_DIRECT

32)innodb_file_format

推荐设置:

Barracuda

作用:

推荐使用Barracuda模式

它是启用表压缩用的,如:

CREATE TABLE `test_1` (
`x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
建完后可以通过:show table status like 'test_1';来查看是否已经启用了表压缩了。

innodb_file_format有这么几种模式:

Antelope-羚羊模式,支持Redundant(冗余)、Compact(紧凑)模式

Barracuda-梭子鱼,是InnoDB Plugin支持的文件格式,在原来的基础上新增了两种数据表格式的支持:Dynamic 和 Compressed

因此我推荐使用:Barracude模式,因为它可以兼容其它数据模式。

它也可以在运行时动态改变:SET GLOBAL innodb_file_format_max = barracuda;

如果不配的后果:

它默认使用的是叫“联合模式”,即不是棱子鱼也不是羚羊。

配置实例:

innodb_file_format = Barracuda

33)innodb_file_format_max

这个参数必须和innodb_file_format参数一致,一定记住,要不然不生效。

34)innodb_log_group_home_dir = /redolog/

这个就不用解释了,太傻瓜了。这种路径的都可由运维决定,记得挂在大磁盘下。

35)innodb_undo_directory = /undolog/

这个就不用解释了,太傻瓜了。这种路径的都可由运维决定,记得挂在大磁盘下。

36)innodb_undo_logs = 128

推荐设置:

128

作用:

指定回滚段的个数(早期版本该参数名字是innodb_rollback_segments),默认128个。每个回滚段可同时支持1024个在线事务。这些回滚段会平均分布到各个undo表空间中。该变量可以动态调整,但是物理上的回滚段不会减少,只是会控制用到的回滚段的个数。现在SSD非常普及。innodb_undo_logs可以默认为128不变。

如果不配的后果:

默认就是128

配置实例:

innodb_undo_logs = 128

37)innodb_undo_tablespaces

推荐设置:

3

作用:

推荐:3,默认为3

定单独存放的undo表空间个数,例如如果设置为3,则undo表空间为undo001、undo002、undo003,每个文件初始大小默认为10M。该参数我们推荐设置为大于等于3,更多的碎片文件会影响磁盘的io性能,而不够碎片同样影响mysql的吞吐率,在ssd上一般最佳的配置在3.如果只有1个undo表空间,那么整个系统在此过程中将处于不可用状态。为了尽可能降低truncate对系统的影响,建议将该参数最少设置为3;

如果不配的后果:

默认为:3

配置实例:

innodb_undo_tablespaces = 3

38)innodb_flush_neighbors

推荐设置:

推荐为:0

作用:

这个参数很要紧,目前在ssd盛行的情况下我们都把它设为0(不开启),如果你设置成了1即开启(默认状态)InnoDB就会刷新一个extent中的所有页面,因为SSD在随机IO上没有额外负载,所以不需要启用该特性,开启了反而多此一句。下面给出一段mysql5.7源码编译前程序员看的readme里的一句话:

This new default changes MySQL to cater for SSDs and fast storage devices by default. We expect that for the majority of users, this will result in a small performance gain. Users who are using slower hard drives may see a performance loss, and are encouraged to revert to the previous defaults by setting innodb_flush_neighbors=1.

如果不配的后果:

它的默认是1,不是0.这个参数对机性硬盘来说很有效,可以减少随机io,增加性能。如果是ssd类磁盘,建议设置为0,可以更快的刷新脏页。如果你把它设为1同时又是ssd那就显得没必要了。这边普及一下小知识,如果你装过8.0,你可以去看一下,8.0已经把这个默认值设为0了。

配置实例:

innodb_flush_neighbors = 0

39)innodb_log_file_size

推荐设置:

第1步:show engine innodb status;

得到:

Log sequence number 2944118284

Log flushed up to 2944118283

Last checkpoint at 2724318261

第2步:设innodb_log_file_size$=log Log sequence number-last checkpoint at=select (2944118284-2724318261)/1024/1024;=209M

第3步:设真正的innodb_log_file_size<=(innodb_log_files_in_group*innodb_log_file_size)*0.75,innodb_log_files_in_group为2(默认),得:

第4步:select 209/(2*0.75);=139.33即:139m,此时可把这个值设为140M

作用:

这个值的默认为5M,是远远不够的,在安装完mysql时需要尽快的修改这个值。

如果对 Innodb 数据表有大量的写入操作,那么选择合适的 innodb_log_file_size 值对提升MySQL性能很重要。然而设置太大了,就会增加恢复的时间,因此在MySQL崩溃或者突然断电等情况会令MySQL服务器花很长时间来恢复。

而这个值是没有一个绝对的概念的,MySQL的InnoDB 存储引擎使用一个指定大小的Redo log空间(一个环形的数据结构)。Redo log的空间通过innodb_log_file_size和innodb_log_files_in_group(默认2)参数来调节。将这俩参数相乘即可得到总的可用Redo log 空间。尽管技术上并不关心你是通过innodb_log_file_size还是innodb_log_files_in_group来调整Redo log空间,不过多数情况下还是通过innodb_log_file_size 来调节。为InnoDB引擎设置合适的Redo log空间对于写敏感的工作负载来说是非常重要的。然而,这项工作是要做出权衡的。你配置的Redo空间越大,InnoDB就能更好的优化写操作;然而,增大Redo空间也意味着更长的恢复时间当出现崩溃或掉电等意外时。我们是通过“测试”得到,怎么测试下面给出方法论:一般情况下我们可以按照每1GB的Redo log的恢复时间大约在5分钟左右来估算。如果恢复时间对于你的使用环境来说很重要,我建议你做一些模拟测试,在正常工作负载下(预热完毕后)模拟系统崩溃,来评估更准确的恢复时间。你可以安装 Percona Monitoring and Management,在该pmm的percona monitoring and management图表中,主要看:

1)Uncheckpointed Bytes ,如果它已经非常接近 Max Checkpoint Age,那么你几乎可以确定当前的 innodb_log_file_size 值因为太小已经某种程度上限制了系统性能。增加该值可以较为显著的提升系统性能。

2)Uncheckpointed Bytes 远小于 Max Checkpoint Age,这种情况下再增加 innodb_log_file_size 就不会有明显性能提升。

在调整完log_file_size后我们再到pmm中去看:Redo Log空间指标,比如说我们看到了1小时内有60g数据被写入日志文件,差不多就是每10分钟会有10g数据在进行“写日志“,我们需要牢牢记得,这个”写日日土已“的时间拖得越久、出现的频次越少就越有助于mysql的innodb的性能。因此这个值没有绝对推荐。如果你没有pmm,那么我们来人肉算,在上面我已经给出了人肉算的详细例子!

如果不配的后果:

默认是5M,这是肯定不够的。

配置实例:

innodb_log_file_size = 140M

40)innodb_log_buffer_size

推荐设置:

16777216

作用:

对于较小的innodb_buffer_pool_size,我们会把它设成和innodb_buffer_pool_size一样。
而当超过4gb的innodb_buffer_pool_size时,我们的建议是把它切的够碎,这是mysql5.7里新带的特性,它的默认在8m,但是对于大量有事务操作的mysql我们推荐在写操作库上设置:16m
此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据.官方的方档建议设置为1-8M之间!
如果不配的后果:

默认是8M

配置实例:

innodb_log_buffer_size = 16777216

41)innodb_purge_threads

推荐设置:

0

作用:

这个参数轻易不用的,我推荐它设为:0,为什么呢?这个参数是和innodb_force_recovery关联起来的,只有当数据库崩溃后重启时才会临时去设的。它的使用场景如下:

mysql断电,重启后无效,起不来。所以我们根据innodb_force_recovery的参数:

1. (SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。

2. (SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。

3. (SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。

4. (SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作。

5. (SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。

6. (SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。

我们在my.cnf中如下设置:

innodb_force_recovery = 6

innodb_purge_threads = 0

记住,一旦当innodb_force_recovery>2时,要把innodb_purge_threads设成0.

如果不配的后果:

默认不要去设,可以不配,出现了问题在recover需要时再去改。

配置实例:

innodb_purge_threads = 0

42)innodb_large_prefix

推荐设置:

1

作用:

如果你的客户端和服务端的字符集设成了utf8mb4,那么我们需要把这个开关开启,为什么呢?mysql在5.6之前一直都是单列索引限制767,起因是256×3-1。这个3是字符最大占用空间(utf8)。但是在5.6以后,开始支持4个字节的uutf8。255×4>767, 于是增加了这个参数。这个参数默认值是OFF。当改为ON时,允许列索引最大达到3072.

在mysql5.6中这个开关叫on, off。而在5.7中叫0和1,由于我们前面设置了utf8mb4,因此这边我们必须把这个参数开启。

如果不配的后果:

不配会有问题,特别是索引会无效、或者不是走最优计划,如果你的字符集是utf8mb4,那么这个值必开启。

配置实例:

innodb_large_prefix = 1

43)innodb_thread_concurrency

推荐设置:

装mysql的服务器的cpu的核数

作用:

如:64核cpu,那么推荐:64(<=cpu核数)

如果一个工作负载中,并发用户线程的数量小于等于64,建议设置innodb_thread_concurrency=0;而事实上我们的系统是处于大并发大事务的情况下的,怎么来算这个值?建议是先设置为128,然后我们不断的降这个值,直到发现能够提供最佳性能的线程数。为了安全起间我们会把它设成和cpu一样大小。

如果不配的后果:

默认在64位下会是8

配置实例:

innodb_thread_concurrency = 64

44)innodb_print_all_deadlocks

推荐设置:

1

作用:

推荐:1

当mysql 数据库发生死锁时, innodb status 里面会记录最后一次死锁的相关信息,但mysql 错误日志里面不会记录死锁相关信息,要想记录,启动 innodb_print_all_deadlocks 参数 。

如果不配的后果:

不会记录该信息。

配置实例:

innodb_print_all_deadlocks = 1

45)innodb_strict_mode

推荐设置:

1

作用:

必须开启,没得选择,1,为什么?

从MySQL5.5.X版本开始,你可以开启InnoDB严格检查模式,尤其采用了页数据压缩功能后,最好是开启该功能。开启此功能后,当创建表(CREATE TABLE)、更改表(ALTER TABLE)和创建索引(CREATE INDEX)语句时,如果写法有错误,不会有警告信息,而是直接抛出错误,这样就可直接将问题扼杀在摇篮里。

如果不配的后果:

如果不配碰到开发或者非专业的dba会把旧ddl语句生效在5.7内,另外一个问题就是ddl语句出错时报错不明显,这会影响到“主从复制”,至于dll为什么会影响到主从复制,我们后面会在“slave_skip_errors = ddl_exist_errors”中详细解说。

配置实例:

innodb_strict_mode = 1

46)log_error

error log所在位置,这个不用多讲,可以和mysql log放在同一路径下,文件名能够和其它log区分开来。

47)slow_query_log

建议开启

48)slow_query_log_file

慢sql所在位置,这个不用多讲,可以和mysql log放在同一路径下,文件名能够和其它log区分开来。

49)log_queries_not_using_indexes=1

强烈建议开启成1.

50)log_slow_admin_statements = 1

强烈建议开启成1.

51)log_slow_slave_statements = 1

强烈建议开启成1.

52)log_throttle_queries_not_using_indexes

推荐设置:

在一开始上线后的初期我们会开成30~50条。随着性能逐渐优化我们会把这个数量开成10.

作用:

上线前一段时间会不太稳定,我们发生过近几十条sql没有走index

如果不配的后果:

不配不开启,建议开启。

配置实例:

log_throttle_queries_not_using_indexes = 50

53)expire_logs_days

推荐设置:

30

作用:

这个值不能太大,因为你不是土豪,不能让binlog无限占用你的磁盘空间,记得这个值一旦设小,你需要做好binlog备份策略,30这个值就是30天,前提是你的binlog的备份做的有效且不占用mysql的磁盘空间。

如果不配的后果:

默认是0,即永不过期。

配置实例:

expire_logs_days = 30

54)long_query_time

推荐设置:

10

作用:

默认为10秒种,即一切>=10s的sql都会被记录。我建议在开始刚上线期设成10(用默认值),越着慢sql调优越来越好,可以把这个值设成1.因为秒数越低,记录的sql越多,记录越多,也会造成mysql过慢。另外不能完全依赖于mysql的慢sql log,而是应该布署druid sql实时查看器或者是apm或者是专业的慢sql实时查询器。

如果不配的后果:

默认为10

配置实例:

long_query_time = 10

55)min_examined_row_limit

推荐设置:

100

作用:

这个值配合着慢查询sql记录用,指定为少于该值的行的查询就算慢sql不被记录成”慢sql日志“。

如果不配的后果:

不开启的话以慢sql的long_query_time为优先规则。

配置实例:

min_examined_row_limit = 100

56)master_info_repository

推荐设置:

TABLE

作用:

主从复制时用,推荐TABLE.
从机保存主节点信息方式,设成file时 会生成master.info 和 relay-log.info2个文件,设成table,信息就会存在mysql.master_slave_info表中。不管是设置的哪种值,都不要移动或者编辑相关的文件和表。
如果不配的后果:

不配的话默认存成file格式。

配置实例:

master_info_repository = TABLE

57)relay_log_info_repository

推荐设置:

TABLE

作用:

主从复制时用,推荐TABLE.

这个参数和上面的master_info_repository必须保持一致,要不然mysql实例启不起来。

不过需要注意的是,这几个table默认用的是myIsAM引擎,要开启成TABLE模式的话一定记得把这两个表的引擎改成innodb

alter table slave_master_info engine=innodb;
alter table slave_relay_log_info engine=innodb;
alter table slave_worker_info engine=innodb;
如果不配的后果:

这个参数和上面的master_info_repository必须保持一致,要不然mysql实例启不起来

配置实例:

relay_log_info_repository = TABLE

58)log_bin = bin.log

主从复制时用,主从复制下的bin.log日志所在文件夹。

59)sync_binlog

推荐设置:

1

作用:

主从复制时用,这个值是要看业务的,它可以有0,1,非零共3种设置方式。

1)0-代表mysql不控制写binlog的时间,由file system自由去控制,此时的mysql的并发性达到最好,但是一旦系统崩溃你会丢失很多还会写入binlog的数据(比如说你正在删数据和更新数据)

2)1-最安全,你最多丢掉一个事务或者是一条语句,但是此时它的性能很差,此参数设为0或者是1之间的性能能差4~5倍。

3)如果你用的是万兆光纤高速磁盘像或者是ssd同时data和binlog都放在一个目录下的同时你要为了安全可以开启成1.

如果不配的后果:

默认为0

配置实例:

sync_binlog = 1

60)gtid_mode

推荐设置:

on

作用:

主从复制时用,推荐开启成on,它的用处就是允许你在从库上进行”备份“,从库上在进行备份时它能够获取主库的binlog位点。

该参数也可以动态在线设定。如果你要在线运行时设定,在my.cnf文件中必须把它设成on。在开启该参数时,log-bin和log-slave-updates也必须开启,否则MySQL Server拒绝启动,当开启GTID模式时,集群中的全部MySQL Server必须同时配置gtid_mod = ON,否则无法同步。

如果不配的后果:

默认为off

配置实例:

gtid_mode = on

61)enforce_gtid_consistency

推荐设置:

1

作用:

主从复制时用,见gtid_mode,这是牵连参数,随着gtid_mode的开启一起开启。

如果不配的后果:

必须跟着gtid_mode一起开启,要不然mysql实例起不来。

配置实例:

enforce_gtid_consistency = 1

62)log_slave_updates

推荐设置:

它只要标注在my.cnf里就代表起作用了。

作用:

主从复制时用,见gtid_mode,这是牵连参数,随着gtid_mode的开启一起开启。它只要标注在这就可以了,代表开启,否则也就不要有这一行了。

如果不配的后果:

它是牵连参数,随着gtid_mode的开启一起开启。

配置实例:

log_slave_updates

63)binlog_format

推荐设置:

row

作用:

主从复制时用,mysql5.7有3种bin log模式:

1. STATEMENT:历史悠久,技术成熟,binlog文件较小,binlog中包含了所有数据库更改信息,可以据此来审核数据库的安全等情况。binlog可以用于实时的还原,而不仅仅用于复制主从版本可以不一样,从服务器版本可以比主服务器版本高。缺点是:不是所有的UPDATE语句都能被复制,尤其是包含不确定操作的时候。调用具有不确定因素的 UDF 时复制也可能出问题,使用以下函数的语句也无法被复制:

* LOAD_FILE()

* UUID()

* USER()

* FOUND_ROWS()

* SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)

2.同时,INSERT ... SELECT 会产生比 ROW 更多的行级锁,复制需要进行全表扫描(WHERE 语句中没有使用到索引)的 UPDATE 时,需要比 RBR 请求更多的行级锁

3.对于有 AUTO_INCREMENT 字段的 InnoDB表而言,INSERT 语句会阻塞其他 INSERT 语句,对于一些复杂的语句,在从服务器上的耗资源情况会更严重,而 RBR 模式下,只会对那个发生变化的记录产生影响,存储函数(不是存储过程)在被调用的同时也会执行一次 NOW() 函数,这个可以说是坏事也可能是好事,确定了的 UDF 也需要在从服务器上执行,数据表必须几乎和主服务器保持一致才行,否则可能会导致复制出错,执行复杂语句如果出错的话,会消耗更多资源。

2. ROW:任何情况都可以被复制,这对复制来说是最安全可靠的,和其他大多数数据库系统的复制技术一样。多数情况下,从服务器上的表如果有主键的话,复制就会快了很多。复制以下几种语句时的行锁更少:

* INSERT ... SELECT

* 包含 AUTO_INCREMENT 字段的 INSERT

* 没有附带条件或者并没有修改很多记录的 UPDATE 或 DELETE 语句

执行 INSERT,UPDATE,DELETE 语句时锁更少,从服务器上采用多线程来执行复制成为可能,它的缺点是:inlog 大了很多,复杂的回滚时 binlog 中会包含大量的数据,主服务器上执行 UPDATE 语句时,所有发生变化的记录都会写到 binlog 中,而 SBR 只会写一次,这会导致频繁发生 binlog 的并发写问题,UDF 产生的大 BLOB 值会导致复制变慢,无法从 binlog 中看到都复制了写什么语句。

从安全和稳定性的缩合考虑上来说我们选择ROW模式。

3. 混合式-不推荐

如果不配的后果:

5.7.6之前默认为STATEMENT模式。MySQL 5.7.7之后默认为ROW模式

配置实例:

binlog_format = row

64)relay_log

主从复制用,定义relay_log的位置和名称,如果值为空,则默认位置在数据文件的目录(datadir),文件名为host_name-relay-bin.nnnnnn(By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory)

65)relay_log_recovery

推荐设置:

1

作用:

主从复制用,推荐值为1,建议打开。
当slave从库宕机后,假如relay-log损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的relay-log,并且重新从master上获取日志,这样就保证了relay-log的完整性。默认情况下该功能是关闭的,将relay_log_recovery的值设置为 1时,可在slave从库上开启该功能,建议开启。
如果不配的后果:

默认情况下是关闭的。

配置实例:

relay_log_recovery = 1

66)slave_skip_errors

推荐设置:

ddl_exist_errors

作用:

主从复制用,推荐值:ddl_exist_errors。理论上我们不应该设置这个值的。即它在my.cnf文件中应该是消失的或者是这样的表示的:

#slave_skip_errors = ddl_exist_errors

但是有时我们的一些表(特别是不熟悉mysql的一些开发)真的是用的是mysql5.6旧版的建表语句,这个问题在平时单机模式下很难发现,一旦主从结构一上后,在5.7上真的是有一定机率(有10%-20%的机率)碰到ddl语句是旧版mysql而运行在mysql5.7上,这时在主从复制时会抛一个无法主从复制的错,那么这时我们需要抓数据,表已经建好了,这个影响不大、微乎其微,因此我们可以把它设成”忽略“。这个是本人的吐血经验,为什么要提这个梗。。。你们懂的。

如果不配的后果:

如果因为建表语句和mysql5.7有冲突时在单实例模式下mysql运行时不会发现,在主从复制时如果没有设跳过值,一旦发生,会影响主从复制,表现就是:主从复制失败。

配置实例:

slave_skip_errors = ddl_exist_errors

67)innodb_buffer_pool_dump_pct

推荐设置:

25~40

作用:

锦上添花的值,非必要,这边给出一些best practice:
通常来说我们会设成25%。对于大并发前提下我们会使用40这个值,这个值越大,mysql启动时间越长。它是你的innodb_buffer_pool_size的百分比!
MySQL默认在InnoDB缓冲池(而不是整个缓冲池)中仅保留最频繁访问页的25%。请注意,这个变量是基于内存中的实际数据量,而不是缓冲池的大小。例如,如果有100GB的缓冲池,但只有10GB的数据,默认只有10GB的25%(即2.5GB)数据保存在内存中。
在多数使用场景下,合理的选择是:保留最有用的数据页,比加载所有的页(很多页可能在后续的工作中并没有访问到)在缓冲池中要更快。你可以更改innodb_buffer_pool_dump_pct变量的值。
如果不配的后果:

不配的话不生效。

配置实例:

innodb_buffer_pool_dump_pct=25

68)innodb_page_cleaners=8

这值一般会在主从延迟的情况下会去设,它的值最好是=innodb_buffer_pool_instance的值,它就是cpu的核数。

69)innodb_undo_log_truncate

推荐设置:

1

作用:

建议开启,设为1

innodb_undo_log_truncate参数设置为1,即开启在线回收(收缩)undo log日志文件,支持动态设置。

如果不配的后果:

不配的话是不生效的。

配置实例:

innodb_undo_log_truncate=1

70)innodb_max_undo_log_size

推荐设置:

推荐在默认值的2倍(默认为1GB)

作用:

推荐在默认值的2倍(默认为1GB),一般我们不会轻易去设它。

这个值和innodb_undo_tablespaces、innodb_undo_logs以及innodb_purge_rseg_truncate_frequency有关,这4个值是互相有牵连的。

1)innodb_undo_tablespaces必须为>=3

2)innodb_undo_logs必须开启

3)innodb_purge_rseg_truncate_frequence必须开启

如果不配的后果:

系统按照1GB来计算。

配置实例:

innodb_max_undo_log_size=2G

71)innodb_purge_rseg_truncate_frequency

推荐设置:

128

作用:

默认值在128,这个值不太会去碰。控制回收undo log的频率。指定purge操作被唤起多少次之后才释放rollback segments。当undo表空间里面的rollback segments被释放时,undo表空间才会被truncate。由此可见,该参数越小,undo表空间被尝试truncate的频率越高。

如果不配的后果:

系统默认按照:128去设定。

配置实例:

innodb_purge_rseg_truncate_frequency=128

72)binlog_gtid_simple_recovery

推荐设置:

建议开启

作用:

前提是你的mysql必须>5.7.6,否则要设为关闭。

这个参数控制了当mysql启动或重启时,mysql在搜寻GTIDs时是如何迭代使用binlog文件的。

这个选项设置为真,会提升mysql执行恢复的性能。因为这样mysql-server启动和binlog日志清理更快。该参数为真时,mysql-server只需打开最老的和最新的这2个binlog文件。

如果不配的后果:

默认为0

配置实例:

binlog_gtid_simple_recovery=1

73)log_timestamps

推荐设置:

system

作用:

推荐使用:system

这个参数主要是控制错误日志、慢查询日志等日志中的显示时间。但它不会影响查询日志和慢日志写到表 (mysql.general_log, mysql.slow_log) 中的显示时间,此参数是全局的,可以动态修改。

如果不配的后果:

默认值为:UTC

配置实例:

log_timestamps=system

74)transaction_write_set_extraction

推荐设置:

这个值不需要去设,因为你用的不是mysql8.0,在5.7.6版以后这个制不是很成熟,如果要开启一般会使用:XXHASH64.

作用:

这个值是基于group(并行)复制用的,推荐值为:XXHASH64,如果没有开启基于group(并行)的复制千万不要去设这个参数,设都不用去设,保持默认就可以了。

如果不配的后果:

默认为off状态,即不生效。

配置实例:

transaction_write_set_extraction = OFF
transaction_write_set_extraction = XXHASH64
transaction_write_set_extraction = MURMUR32
75)show_compatibility_56

推荐设置:

on

作用:

推荐打开。这个参数是兼容mysql5.6版的INFORMATION_SCHEMA.GLOBAL_STATUS相关功能的,它有利于从5.6到5.7的过渡时非mysql专职dba但是懂mysql的运维用的。

如果不配的后果:

默认是off。相当于严格模式。

配置实例:

show_compatibility_56=on

至此,本文完,一共介绍了mysql5.7性能提升的75种方法和详细解释,希望对大家有所帮助!

参考文献:blog.csdn.net/lifetragedy/article/details/105944790

mysql数据库跨机房高可用的开源方案推荐

回复

MySQL 发起了问题 • 1 人关注 • 0 个回复 • 1392 次浏览 • 2018-10-05 11:53 • 来自相关话题

求一款SQL自动备份恢复带邮件功能的工具

MySQLz836441256 回复了问题 • 3 人关注 • 2 个回复 • 2134 次浏览 • 2017-12-07 18:47 • 来自相关话题

mysql 5.6(阿里云RDS)内存使用率持续增长

MySQLz836441256 回复了问题 • 3 人关注 • 2 个回复 • 3908 次浏览 • 2017-12-07 18:45 • 来自相关话题

NEWSQL为什么这么火,这种新的数据库优缺点是什么?适合什么类型的业务

回复

MySQL咖啡 回复了问题 • 1 人关注 • 1 个回复 • 2685 次浏览 • 2017-08-16 16:42 • 来自相关话题

MySQL DAL(Data Access Layer)中间件总结

MySQL赵班长 发表了文章 • 1 个评论 • 3881 次浏览 • 2016-12-10 13:53 • 来自相关话题

        DAL是数据访问层的英文缩写,即为数据访问层(Data Access Layer)。用在这里可能不是特别恰当,因为本文主要介绍MySQL访问的中间件,不过也是属于DAL的范畴。本文不会去高可用相关的知识,主要聚焦于MySQL的横向扩展。 ...查看全部
        DAL是数据访问层的英文缩写,即为数据访问层(Data Access Layer)。用在这里可能不是特别恰当,因为本文主要介绍MySQL访问的中间件,不过也是属于DAL的范畴。本文不会去高可用相关的知识,主要聚焦于MySQL的横向扩展。
       我们知道最简单的一种扩展是MySQL 主从复制,通过1主多从来实现读的性能扩展,但是这样的扩展不仅仅有局限性,而且写入的问题并没有解决。目前市场上用三类解决方案:
       1.客户端分片(推荐)
    程序客户端进行分库分表。也就是直接在程序里面进行数据库和表的拆分,例如用户表。根据用户的UID,例如13678789,根据最后一位,可以拆分为0-9共10个数据库,把尾号是0的存入db_user_0数据库,尾号是1的存入db_user_1数据库,select的时候也是一样。然后根据倒数第二位,可以拆分为0-9共10张表,根据倒数第二的尾号写入相应的表中。例如13678789这个UID的信息,写入db_user_9数据库的table_user_8的表中。
    
 2.各种数据成中间件:
 
  2.1 MySQL-Proxy(不强烈推荐)

      先说MySQL自己的,MySQL Proxy: 是处在你的MySQL数据库客户和服务端之间的程序,它还支持嵌入性脚本语言Lua。这个代理可以用来分析、监控和变换(transform) 通信数据。
mysql-proxy.jpg

    MySQL Proxy最强大的一项功能是实现“读写分离(Read/Write Splitting)”。基本的原理是让主数据库处理事务性查询,而从数据库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从数据库。

mysql-proxy2.png


    2.2  Atlas(不强烈推荐)

    Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基础上,修改了大量bug,添加了很多功能特性。目前该项目在360公司内部得到了广泛应用,很多MySQL业务已经接入了Atlas平台,每天承载的读写请求数达几十亿条。同时,有超过50家公司在生产环境中部署了Atlas,超过800人已加入了我们的开发者交流群,并且这些数字还在不断增加。

atlas.jpg


主要功能:
  1. 读写分离
  2. 从库负载均衡
  3.  IP过滤
  4. 自动分表
  5. DBA可平滑上下线DB
  6. 自动摘除宕机的DB

     简单的说是在MySQL Proxy的基础上做了二次开发,并支持了自动分表的特性。但是仅支持非常有限的rang进行分表。目前有先的分支Atlas Sharding来实现更多的功能。

具体的功能清看Github,非常详细
https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md

    2.3 Cobar(不强烈推荐)

      Cobar是阿里巴巴开源的一个,提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好的线性扩展,并看上去还是一个数据库,对应用保持透明。

  • 产品在阿里巴巴稳定运行3年以上。

  • 接管了3000+个MySQL数据库的schema。

  • 集群日处理在线SQL请求50亿次以上。

  • 集群日处理在线数据流量TB级别以上。



cobar.jpg


详情:https://github.com/alibaba/cobar/wiki

2.4 MyCAT(不强烈推荐)

     MyCAT基于阿里开源的Cobar产品而研发的,目前社区相对比较活跃,功能也是最多的一个MySQL中间件,

    什么是MYCAT

  • 一个彻底开源的,面向企业应用开发的大数据库集群

  • 支持事务、ACID、可以替代MySQL的加强版数据库

  • 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群

  • 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server

  • 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品

  • 一个新颖的数据库中间件产品


mycat.png


3.MySQL 集群

   3.1 MySQL Cluster(强烈不推荐)
      MySQL Cluster 是 MySQL 适合于分布式计算环境的高实用、高冗余版本。它采用了NDB Cluster 存储引擎,允许在1个 Cluster 中运行多个MySQL服务器。几乎无应用案例,不推荐。

mysql-cluster.png


    3.2 Percona XtraDB Cluster方案(推荐)

    Percona XtraDB Cluster简称PXCPercona Xtradb Cluster的实现是在原mysql代码上通过Galera包将不同的mysql实例连接起来,实现了multi-master的集群架构。
pxc.png

    上图中有三个实例,组成了一个集群,而这三个节点与普通的主从架构不同,它们都可以作为主节点,三个节点是对等的,这种一般称为multi-master架构,当有客户端要写入或者读取数据时,随便连接哪个实例都是一样的,读到的数据是相同的,写入某一个节点之后,集群自己会将新数据同步到其它节点上面,这种架构不共享任何数据,是一种高冗余架构。

    以上为个人生产经验,不代表产品本身的相关利益,不过还好了,都是开源的,大家可以根据自身情况选择。你会发现并没有强烈推荐的方案,主要是大家要考虑自身业务的情况进行选择,例如核心业务。连主从切换都不推荐自动,而是手动,宁愿业务不能访问,也不能出现自动主从切换导致数据丢失。
 

使用TiDB为Zabbix构建分布式MySQL数据库支持

MySQL赵班长 发表了文章 • 0 个评论 • 4732 次浏览 • 2016-10-27 11:13 • 来自相关话题

     当我们在生产上部署Zabbix进行企业级监控后,随着监控规模的扩大和时间的变化,MySQL逐渐会成为Zabbix的瓶颈,很多大的企业开始着手进行MySQL表分区、数据清理与优化,甚至来实现Zabbix数据库的分库分表。这些都让运维管理的复杂度大大增加 ...查看全部
     当我们在生产上部署Zabbix进行企业级监控后,随着监控规模的扩大和时间的变化,MySQL逐渐会成为Zabbix的瓶颈,很多大的企业开始着手进行MySQL表分区、数据清理与优化,甚至来实现Zabbix数据库的分库分表。这些都让运维管理的复杂度大大增加。
     当Zabbix遇上Tidb,一段美好的故事,就此展开!

TiDB介绍
    TiDB 是一个分布式 NewSQL 数据库。支持水平扩展、高可用、ACID 事务、SQL 等特性。同时 TiDB 还支持 MySQL 语法和 MySQL 协议。
    TiDB项目地址:https://github.com/pingcap/tidb  
   
由PingCAP公司开发并开源:https://github.com/pingcap/tidb
    对于熟悉Codis的小伙伴们来说,就更好解释了,就是当初豌豆荚开发Codis的团队出来创业组建的。
   
TiDB项目架构:
architecture.png


TiDB部署
    详细的内容请看github上的中文手册。来了解并部署TiDB。
https://github.com/pingcap/docs-cn

TiDB在Zabbix使用中授权注意事项
      
这里不会去介绍Zabbix Server的安装步骤,有几个注意事项需要说明下。
        1.注意:在Tidb授权的时候,不能直接使用grant授权并设置密码。应该使用下面的方式。
MySQL [(none)]> create user 'zabbix'@'192.168.99.0/255.255.255.0' identified by 'zabbix';
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> grant all on zabbix.* to 'zabbix'@'192.168.99.0/255.255.255.0';
Query OK, 2 rows affected (0.01 sec)


注意:TiDB 支持对用户授权,这里只是支持授权语法,并且记录在系统表中。但是实际上只对 DropTable 语句进行权限检查,对其他的语句并不会做权限检查。实现用户授权主要是为了兼容已有的 MySQL 业务。 请参考:https://github.com/pingcap/docs-cn/blob/master/faq.md


  2.TiDB在创建Zabbix表结构的时候会比较慢
    当我们初始化安装创建Zabbix表结构的时候,会发现卡住迟迟不动,这主要是TiDB的设计方式,为了数据的一致性和业务不受影响,DDL操作会比较慢。
zcat create.sql.gz | mysql -h 192.168.99.x -P 4000 -uzabbix -pzabbix zabbix


官方是这么介绍的:TiDB 实现了 Google F1 的在线 Schema 变更算法(具体参见 F1 论文 和我们的一篇 Blog)。 一般情况下,DDL 并不是一个频繁的操作,我们首先要保证的是数据的一致性以及线上业务不受影响。一个完整的 DDL 过程会有 2 到 5 个阶段(取决于语句类型),每个阶段至少会执行 2*lease 时间,假设 lease 设为 1分钟,对于 Drop Table 语句(需要两个阶段),会执行 2*2*1 = 4 分钟。除此之外,DDL 的时间还取决其他的条件,比如做 Add Index 操作时,表中已有的数据量是影响 DDL 时间的主要因素。我们也了解过 Google 内部在 F1 上是如何做 DDL,一般是提交给 DBA,DBA 再通过专用的工具执行,执行的时间会很长。


    耐心的等待着哦!如果不放心,可以use zabbix;show tables;看看表是不是在不停的增长!喝杯咖啡吧,这可能是一个漫长的过程。

TiDB运维技术交流QQ群:
  • 群名称:TiDB技术交流群
  • 群   号:463640808


QQ截图20161027105616.jpg

        近期我也在不停的测试TiDB,并持续给官方进行反馈,有兴趣的小伙伴环境,加入一起交流TiDB在生产环境中的使用经验。
 

MySQL基于复制的架构方案

MySQL运维社区编辑 发表了文章 • 2 个评论 • 2243 次浏览 • 2016-10-24 14:12 • 来自相关话题

    MySQL复制是一个非常简单而有方便进行架构扩展的功能,可以说是运维必备,我们通过对主从进行不同的组合,可以满足我们相应的需求。 分享目录: 一主一从,高可用一主一从,读写分离一主多从,读写分离一主多从,负载均衡主 ...查看全部
    MySQL复制是一个非常简单而有方便进行架构扩展的功能,可以说是运维必备,我们通过对主从进行不同的组合,可以满足我们相应的需求。

分享目录:
  • 一主一从,高可用
  • 一主一从,读写分离
  • 一主多从,读写分离
  • 一主多从,负载均衡
  • 主主复制,双写
  • 主主复制,单写
  • 双主双从

1.一主一从,高可用

1.png

架构说明:最传统的一主一从,如果主库发生故障,手动将从库提升为主库,从库仅用于故障恢复。

2.一主一从,读写分离

2.png

架构说明:还是一主一从,在客户端实现读写分离,不过需要注意主从延时的情况。小技巧:在写比较度的表上可以在Master不建立索引,而在Slave端来建立索引。

3.一主多从,读写分离

3.png

架构说明:和一主一从类似,在读请求比较多的情况下,可以增加MySQL从节点。


小技巧:可以在客户端实现多个从节点的轮询和权重的设置。



4.一主多从,负载均衡

4.png

架构说明:在对读需求场景比较多的情况下,为了不频繁的对客户端进行配置变更,可以在从库前端放置负载均衡。不过在slave比较多的时候。主从复制也会给MySQLMaster带来一些性能上和带宽上的压力。


小技巧:给Slave分配不同的角色。例如之前公众号文章说的延迟从库、灾备从库、数据仓库等。


5.主主复制,双写

5.png

架构说明:主主复制其实就是MySQL的双向复制,两台机器互为主从,双主可以同时写,不过要处理好自增ID重复问题,例如设置使用奇偶插入 。
6.主主复制,单写

6.png

架构说明:还是主主复制,不过这次单写,也就是双主当主从。既可以保证写的高可用,又可以保证读的高可用。


小技巧:这个是两台机器的最佳方案哦。



7. 双主双从

7.png


架构说明:在主主复制,单写的时候。如果一个主宕机,那么就读写另外一个主。可读的节点就剩下了一个。对于读需求比较多的业务可能会有问题,那么双主双从就可以解决这个问题。


小技巧:复杂的架构带的肯定是运维的难题哦。


好了,基于复制的扩展先写到这里,其实也可以使用MySQL Proxy替代客户端做的读写分离,不过一直没有生产使用过。今天北京天气不错,该出去转转了。如果觉得可以读,请转发和关注哦。

趁现在,关注我们         
牛人并不可怕,可怕的是牛人比我们还努力!关注“运维社区(微信ID:cloud-oaas)”公众号,每天利用空闲时间阅读一篇技术原创干货,满满的小幸福。
8.jpg