mysql优化七:通过配置MySQL系统配置信息和引擎参数配置优化

1.数据库引擎

什么是数据库引擎

引擎(engine)能够决定程序管理和数据操作的程序或程序段。数据库引擎就是操作数据库的一段程序或程序段

简单说来,一个数据库的存储引擎就是用来对数据表进行信息存储、处理、查询等操作。

查看数据库引擎

SHOW ENGINES;

MySql有十几种数据库引擎,像测试的这个MySQL就内置了9种数据库引擎,但是我们一般常用的数据库引擎只有两种---MyISAM引擎和InnoDB引擎。这两种数据库引擎已经可以处理绝大部分业务场景了。但是总的来说没有十全十美的数据库存储引擎。InnoDB 和 MyISAM 虽然比较通用,但是它们并不是对所有的场景都是完美支持的,也许其他的存储引擎可以很好地支持你的应用。这个就需要DBA来设计了,我们暂时不用关心这么深入。

查看表所使用的引擎

show table status from mydb2 where name='vote_record';

一个表只能用一种引擎,同一个库中的不同表允许使用不同的引擎

每个表的应用场景不同,所需要的处理策略也有所不同,每张表不一样的引擎配置可以使数据库灵活的适应各种场景。

2.MyISAM引擎和InnoDB引擎

  • MyISAM引擎在5.5以前是作为MySQL的默认引擎的,5.5之后改为了InnoDB引擎。
  • MyISAM由早期的ISAM所改良。虽然性能极佳,但却有一个缺点:不支持事务处理(transaction)。不过,在这几年的发展下,MySQL也导入了InnoDB(另一种数据库引擎),以强化参考完整性与并发违规处理机制,后来就逐渐取代MyISAM。
  • InnoDB,是MySQL的数据库引擎之一,为MySQL AB发布binary的标准之一。InnoDB由Innobase Oy公司所开发,2006年五月时由甲骨文公司并购。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能并且实现了SQL标准的四种隔离级别,该引擎还提供了行级锁和外键约束。

主要区别:

  • MyISAM是非事务安全型的,而InnoDB是事务安全型的。
  • •MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
  • •MyISAM支持全文类型索引,而InnoDB不支持全文索引。
  • •MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。
  • •MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。
  • •InnoDB 中不保存表的具体行数,也就是说,执行select count(*) fromtable时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM中存储了表的行数,只要简单的读出保存好的行数即可。
  • •InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

应用场景:

  • MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。--select
  • InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。--insert,update

引擎操作常用命令:

1.查看表的存储类型(三种):

•show create table tablename
•show table status from  dbname  where name=tablename
•mysqlshow  -u user -p password --status dbname tablename

2.修改表的存储引擎:

alter table tablename type=InnoDB

3.启动mysql数据库的命令行中添加以下参数使新发布的表都默认使用事务:

--default-table-type=InnoDB

4.临时改变默认表类型:

•set table_type=InnoDB

•show variables like 'table_type'

数据库引擎常用命令

(1)查看表的存储类型(三种):

•show create table tablename
•show table status from  dbname  where name=tablename
•mysqlshow  -u user -p password --status dbname tablename

(2)修改表的存储引擎:

alter table tablename type=InnoDB

(3)启动mysql数据库的命令行中添加以下参数使新发布的表都默认使用事务:

--default-table-type=InnoDB

(4)临时改变默认表类型:

set table_type=InnoDB
show variables like 'table_type'

(5)关闭mysql服务net stop mysql

         启动mysql服务net start mysql

实验

1.InnoDB引擎下

       插入1W条数据

2.MyISAM引擎下

       插入1W条数据

3.MyISAM引擎下

select * from vote_record

4.InnoDB引擎下

 select * from vote_record

引擎操作语句:

show table status from mydb2 where name='vote_record';

alter table vote_record engine=MyISAM;

alter table vote_record engine=INNODB;

InnoDB写入:

call add_vote(10000);

受影响的行:1

时间:223.621s

MyISAM写入:

call add_vote(10000);

受影响的行:1

时间:2.721s

select * from vote_record

InnoDB查询:

0.282s

MyISAM查询:

0.016s

实验总结:

看之前介绍的时候在高并发的状态下InnoDB的行级锁设计应该是比MyISAM表级锁的设计更高效的

但是现在没有高并发,两个数量级的差距,这是多大的高并发才能展现出InnoDB的高并发状态优于MyISAM

既然现在不存在高并发的问题,那么问题就应该是出在其他的差别方面。

我们知道InnoDB是支持事务的,而MyISAM是不支持事务的,那有没有可能是因为事务的关系呢?

写操作:

MyISAM比InnoDB快了两个数量级, 这仅仅是1W条数据的无并发插入

3.日志写入优化

MySQL事务

数据库本身不支持事务,老师上课讲事务知识点的时候,提到一个概念,数据库默认支持事务的,不过只是针对一条sql语句。所以现在更加深入理解是,数据库采用Innodb这个支持事务引擎的时候,引擎在做sql操作的时候会为每一条sql语句增加事务。所以每条sql的事务操作,就是使InnoDB引擎的添加要比MyISAM慢的主要原因。

Undo Log原理:

为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

Redo Log原理:

 和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。

总结:简单来说,redo log 记录事务修改后的数据, undo log 记录事务前的原始数据。

如何解决这个问题呢?

了解了事务机制之后,我们知道,数据库在写数据的时候,不单单只保存了数据,同时还要写入日志文件。日志文件也是先写到缓冲区,然后再刷写到磁盘的。所以我们现在来看下日志写入方面的相关参数配置,看下有什么能够优化的地方

日志统

错误日志:记录启动,运行或停止MySQL时出现的问题

通用日志:记录建立的客户端连接和执行语句

更新日志(记录所有更改数据的语句。5.1中已不再使用)

二进制日志:记录所有更改数据的语句

慢查询日志:记录所有执行时间超过long_query_tim秒的所有查询或不使用索引的查询

InnoDB日志:innodb redo log

InnoDB对日志写入策略的参数

1.innodb_flush_log_at_trx_commit     

       参数定制化commit返回时日志是否刷新到磁盘

2.sync_binlog是MySQL innodb

       将二进制日志文件刷新到磁盘上。

1.innodb_flush_log_at_trx_commit参数:

# If set to 1, InnoDB will flush (fsync) the transaction logs to the

# disk at each commit, which offers full ACID behavior. If you are

# willing to compromise this safety, and you are running small

# transactions, you may set this to 0 or 2 to reduce disk I/O to the

# logs. Value 0 means that the log is only written to the log file and

# the log file flushed to disk approximately once per second. Value 2

# means the log is written to the log file at each commit, but the log

# file is only flushed to disk approximately once per second.

innodb_flush_log_at_trx_commit=1

===================================================================

0

 每隔一秒,把事务日志缓存区的数据写到日志文件中,以及把日志文件的数据刷新到磁盘上; log buffer会每秒写入到日志文件并刷写(flush)到磁盘。但每次事务提交不会有任何影响,也就是 log buffer 的刷写操作和事务提交操作没有关系。在这种情况下,MySQL性能最好,但如果 mysqld 进程崩溃,通常会导致最后 1s 的日志丢失。

意味着数据的写入,跟事务的提交是分开的,数据该怎么写入就怎么写入,而事务的提交没有任何写入操作,系统每秒会将事务的提交写入日志缓存,同时刷写到磁盘

1

当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。

这意味着事务提交和数据的写入是同步的,每次提交数据,就执行写入磁盘的操作。

2

如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。

总结:

1的时候,提交一次,写入一次事务日志到磁盘,写入数据到磁盘。

0的时候,写入数据,事务的提交跟数据的写入没有关系,异步操作。

2的时候,每次提交事务都会写入缓存里,每一秒定时刷到磁盘里这里是同步的操作,但是不是一条条的写入磁盘,而是先写入缓存,最后每隔1秒钟写入一次磁盘。

默认值1是为了保证完整的ACID。当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。设为0的话,mysqld进程崩溃的时候,就会丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。

实验

修改innodb_flush_log_at_trx_commit值

set global innodb_flush_log_at_trx_commit=0;

set global innodb_flush_log_at_trx_commit=1;

set global innodb_flush_log_at_trx_commit=2;

查看innodb_flush_log_at_trx_commit值

SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';

实验数据

call add_vote(10000);

0 : 2.700s

1:231.832s

2:5.788s

2.sync_binlog参数:

sync_binlog =  N: 

N>0    每向二进制日志文件写入N条SQL或N个事务后,则把二进制日志文件的数据刷新到磁盘上; 

N=0    不主动刷新二进制日志文件的数据到磁盘上,而是由操作系统决定;

实验:

设置

set global sync_binlog=N;(0-N)

查看

SHOW GLOBAL VARIABLES like 'sync_binlog';

实验数据

call add_vote(10000);

N=2,0  4.754s

N=2,1  4.909s

N=2,100  4.838s

数据安全性

当innodb_flush_log_at_trx_commit和sync_binlog  都为1时是最安全的,在mysqld 服务崩溃或者服务器主机crash的情况下,binary log 只有可能丢失最多一个语句或者一个事务。但是鱼与熊掌不可兼得,都为1会导致频繁的IO操作,因此该模式也是最慢的一种方式。 

当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。 

当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失。 

双1适合数据安全性要求非常高,而且磁盘IO写能力足够支持业务,比如订单,交易,充值,支付消费系统。双1模式下,当磁盘IO无法满足业务需求时,推荐的做法是innodb_flush_log_at_trx_commit=2 ,sync_binlog=N (N为500 或1000) 且使用带蓄电池后备电源的缓存cache,防止系统断电异常。

推荐配置组合: 

N=1,1  — 适合数据安全性要求非常高,而且磁盘IO写能力足够支持业务,比如充值消费系统; 

N=1,0  — 适合数据安全性要求高,磁盘IO写能力支持业务不富余,允许备库落后或无复制; 

N=2,0或2,m(0<m<100)  — 适合数据安全性有要求,允许丢失一点事务日志,复制架构的延迟也能接受; 

N=0,0  — 磁盘IO写能力有限,无复制或允许复制延迟稍微长点能接受,例如:日志性登记业务; 

  当两个参数设置为双1的时候,写入性能最差,sync_binlog=N (N>1 ) innodb_flush_log_at_trx_commit=2 时,(在当前模式下)MySQL的写操作才能达到最高性能。 

4.其他引擎配置

一、公共选项

1.skip-external-locking

避免MySQL的外部锁定,减少出错几率增强稳定性

2.skip-name-resolve

禁止MySQL对外部链接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间,单需要注意的是,如果开启该选项,则所有远程主机链接授权都要使用IP地址的方式,否则MySQL将无法正常处理请求链接

3.max_connection

指定MySQL允许的最大链接进程数。

4.query_cache_size

默认为0,指定MySQL查询缓冲区的大小

5.sort_buffer_size

每个线程的排序缓存大小,该选项对排序order by,group by起作用。

对于内存在4GB左右的服务器推荐设置为6-8M

6.record_buffer

每个进行一个顺序烧面的线程,为其扫描的每张表分配这个大小的一个缓冲区。

7.table_cache

为所有线程打开表的数量。增加该值能增加MySQL要求文件描述符的数量。MySQL对每个唯一打开的表需要2个文件描述符

二、MyISAM选项

1.key_buffer_size

指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能对于内存在4G左右的服务器该参数可设置为256M或384M。

2.read_buffer_size

读查询操作所能使用的缓冲区大小。和sort_buffer_size参数一样,该参数对应的分配内存也是每连接独享

3.myisam_sort_buffer_size

默认设置为16M,设置,恢复,修改表的时候使用的缓冲大小,值不要设置的太大。

4.join_buffer_size

联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享

三、InnoDB选项

1.innodb_buffer_pool_size

这个是Innodb最重要的参数,和MyISAM的key_buffer_size有相似之处,但也是有差别的。 

这个参数主要缓存innodb表的索引,数据,插入数据时的缓冲。

该参数分配内存的原则:

这个参数默认分配只有8M,可以说是非常小的一个值。

如果是一个专用DB服务器,那么他可以占到内存的70%-80%。

这个参数不能动态更改,所以分配需多考虑。分配过大,会使Swap占用过多,致使Mysql的查询特慢。

如果你的数据比较小,那么可分配是你的数据大小+10%左右做为这个参数的值。

例如:数据大小为50M,那么给这个值分配innodb_buffer_pool_size=64M

2.Innodb_additional_mem_pool_size

用来存放Innodb的内部目录这个值不用分配太大,系统可以自动调。不用设置太高。通常比较大数据设置16M够用了,如果表比较多,可以适当的增大。如果这个值自动增加,会在error log有中显示的。

3.innodb_log_file_size

在日志组中每个日志文件的大小,一般是innodb_buffer_pool_size的25%,官方推荐是innodb_buffer_pool_size的40-50%。一般控制在几个LOG文件相加大小在2G以内为佳。具体情况还需要看你的事务大小,数据大小为依据。说明:这个值分配的大小和数据库的写入速度,事务大小,异常重启后的恢复有很大的关系。

4.Innodb_log_files_in_group=2

指定你有几个日志组。分配原则:一般我们可以用2-3个日值组。默认为两个。

5.innodb_log_buffer_size=3M

事务在内存中的缓冲。分配原则:控制在2-8M.这个值不用太多的。他里面的内存一般一秒钟写到磁盘一次。具体写入方式和你的事务提交方式有关。在oracle等数据库了解这个,一般最大指定为3M比较合适。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值