Mysql执行INSERT *** 作后是立即写硬盘的吗

Mysql执行INSERT *** 作后是立即写硬盘的吗,第1张

一般来讲在没有启动事物的情况下,执行动作查询都是立即写磁盘的,而在启用事物的情况下则在提交事务Commit时写磁盘。但是我们应该留意,执行动作查询时,启用事物有显式和隐式两种方式,很多情况下即使我们没用启用事物,但是数据库后台其实是会自动启用和提交事务的。例如将一个选择查询出来的多行记录插入导数据表等,系统会在确定所有记录行都可被插入后才提交Commit将记录写入磁盘,以确保全部执行成功或者全部失败。

具体的情况可能更加复杂,建议题主参阅MYSQL帮助中有关MySQL事务处理和锁定语句中的说明。

对于运行mysql这类程序需要的CPU要求比较高,如果电脑硬件配置满足不了,那么可以试试最近流行的云桌面来轻松运行mysql,让你轻松办公或者学习。

mysql硬盘配置具体配置如下:

(1)磁盘寻道能力(磁盘I/O),我们现在用的都是SAS15000转的硬盘,用6块这样的硬盘作RAID1+0。MySQL每一秒钟都在进行大量、复杂的查询 *** 作,对磁盘的读写量可想而知,所以,通常认为磁盘I/O是制约MySQL性能的因素之一。

对于日均访问量100万pv以上的Discuz!论坛,如果磁盘I/O性能不好,造成的直接后果是MySQL的性能会非常低下!解决这一制约因素可以考虑解决方案是:使用RAID1+0磁盘阵列,注意不要尝试使用RAID-5,MySQL在RAID-5磁盘阵列上的效率不会像你期待的那样快,如果资金允许,可以选择固态硬盘SSD来SAS硬件作RAID1+0。

(2)CPU对于MySQL的影响也是不容忽视的,建议选择运算能力强悍的CPU。推荐使用DELL PowerEdge R710,IntelE5504(双四核)商家的热点也是其强大的虚拟化和数据库能力。我现在比较喜欢用其做Linux/FreeBSD下的虚拟化应用,效果不错。

(3)对于一台使用MySQL的Database Server来说,建议服务器的内存不要小于2GB,推荐使用4GB以上的物理内存。不过内存对于现在的服务器而言可以说是一个可以忽略的问题,如果是高端服务器,基本上内存都超过了32GB,我们的数据库服务器都是32GB DDR3。

MySQL 里经常说到的 WAL技术,也就是先写日志,再写磁盘。

当内存数据页跟磁盘数据页内容不一致的时候,我们成这个内存页为“脏页”。内存数据写入磁盘后,内存和磁盘上的数据页内容就一致了,称为“干净页”。

MySQL 从 内存更新到磁盘的过程,称为刷脏页的过程(flush)。

InnoDB 刷脏页的时机:

往前推进之后,就要把两个点之间的日志对应的所有脏页都 flush 到磁盘上。

这种情况是 InnoDB 要尽量避免的。因为出现这种情况,整个系统都不能接受更新。更新数会跌为0。

那么为什么不能直接淘汰所有的内存,下次请求的时候,再从磁盘读入数据页,然后 拿 redo log 出来应用?这其实也是从性能的角度来考虑的,刷脏页一定写盘,就保证了每个数据页只有两种情况:

这种情况在日常应用中其实是常态。 在InnoDB 中,使用缓冲池 (buffer pool)管理内存,缓冲池中的内存页有三种状态:

刷脏页是常态,所以如果出现以下的情况,都会明明显影响性能:

首先,需要让 InnoDB 正确指导系统的 IO 能力,来控制刷脏页的快慢。

innodb_io_capacity 这个参数,它会告诉 InnoDB 你的磁盘能力,所以尽量设置成磁盘的 IOPS。可以使用 fio 工具来获取。

然后,如果你来设计策略控制刷脏页的速度,会参考哪些因素呢?

这个问题可以这么想,如果刷太慢,会出现什么情况?首先是内存脏页太多,其次是 redo log 写满。

所以,InnoDB 的刷盘速度就是要参考这两个因素:一个是脏页比例,一个是 redo log 写盘速度。

参数 innodb_max_dirty_pages_pct 是脏页比例上限,默认是 75%。InnoDB 会根据当前的脏页比例,计算出一个数字 F1。

InnoDB 写入日志都会有一个序号,当前写入序号跟 checkpoint 对应的序号之间的差值,假设为N。InnoDB 会根据N 计算出 F2.

根据 F1和F2 取其中较大的值为 R,之后引擎就可以按照 Innodb_io_capacity 定义的能力乘以 R% 来控制刷脏页的速度。

MySQL 中有一个机制,刷脏页的时候如果数据页旁边的数据页也是脏页,那么就会一起刷掉,而且这个逻辑是可以蔓延的,所以对于每个相邻的数据页,都会被一起刷。

在 InnoDB 中,innodb_flush_neighbors 参数就是用来控制这个行为的,值为 1 的时候会有上述的“连坐”机制,值为 0 时表示不找邻居,自己刷自己的。

在使用机械硬盘时,这个优化很有意义,可以减少很多随机 IO。如果使用的是 SSD 这种IOPS 比较高的设备,可以设置innodb_flush_neighbors 为0,只刷自己,这个时候 IOPS 往往就不是性能瓶颈了。只刷自己就可以提高刷脏页的速度,减少 SQL 语句的响应时间。

binlog 的写入机制比较简单:事务执行的过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到binlog 文件中。

系统给 binlog cache 分配了一片内存,每个线程一个,参数 binglog_cache_size 用于控制单个线程内 binlog cache 的内存大小,超过就要暂存在磁盘。

事务提交的时候,执行器把 binlog cache 里完整事务写入到 binlog 中,并清空 binlog cache。

write 和 fsync 的时机,是由参数 sync_binlog 控制的:

因此,在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成 0,比较常见的是将其设置为 100~1000 中的某个数值。但是,将 sync_binlog 设置为 N,对应的风险是:如果主机发生异常重启,会丢失最近 N 个事务的 binlog 日志。

事务的执行过程中,生成的 redo log 是要先写到 redo log buffer 的。

redo log 三种状态:

日志写到 redo log buffer 是很快的,write 到 page cache 也差不多,但是持久化到磁盘的速度就慢多了。

InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,取值如下:

InnoDB 有一个后台线程,每隔 1 秒,就会把 redo log buffer 中的日志,调用 write 写到文件系统的 page cache,然后调用 fsync 持久化到磁盘。

组提交 机制

日志逻辑序列号(log sequence number,LSN)是一个单调递增的值,对应 redo log 的一个个写入点。每次写入的长度为 lenght 的 redo log,LSN的值就会加上 length。

LSN 也会写到 InnoDB 的数据页中,来确保数据也不会被多次执行重复的 redo log。

在一组提交里面,组员越多,节约磁盘 IOPS 的效果越好。在并发更新的场景下,第一个事务写完 redo log buffer 以后,接下来这个 fsync 越晚调用,组员可能越多,节约 IOPS 的效果就越好。

WAL机制主要得益于两个方面:

如果你的 MySQL 现在出现了性能瓶颈,而且瓶颈在 IO 上,可以通过哪些方法来提升性能呢?

针对这个问题,可以考虑以下三种方法:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8506037.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-17
下一篇 2023-04-17

发表评论

登录后才能评论

评论列表(0条)

保存