Mysql原理(四) 数据与日志

WAL机制

     在Mysql中经常会听到WAL机制(Write-Ahead-Logging),主要讲了数据在操作的时候先进行写日志,然后再将数据写入磁盘的过程。之前提到过Mysql中的两个重要的日志文件redo log和bin log。
      redo log:Mysql分配给redoLog固定大小区域记录日志,该日志采用循环写从头写到尾然后在从头,同时还有一个记录擦除日志位置的标记checkpoint。当写入点和checkpoint在同一个位置,则停止写日志。如果数据库异常后,提交后的记录不会丢失称为crash-safe
     bin log:称为归档日志,是追加写不会覆盖之前的日志。所以可以根据binlog日志可以完成主从备份、数据订阅、恢复数据等工作。
     之前也提到mysql执行一条update语句遵从两阶段提交过程,整个流程如下
1.先通过引擎找到对应的行数据
2.对行数据进行修改并调用引擎接口修改这条数据
3.redo log记录更新流程此时处于prepare状态,告知mysql执行器完成操作
4.执行器生成binlog并写入磁盘
5.执行器调用引擎提交事务接口,redo log状态变为commit状态完成整个更新操作。
Redo log进行flush操作
     Mysql在记录redo log的时候会先将数据写入到内存中,然后通过flush将内存中的数据写入磁盘中。再次期间会产生脏数据页导致内存和磁盘的数据不一致。这时候mysql就需要刷脏数据页。
Mysql什么时候执行flush操作?
1.当记录redo log的内存满了,会停止写入redo log操作。
2.写入日志太多,发现分配的内存不够,这时候需要淘汰一部分数据页。
3.mysql空闲时会进行flush操作
     在flush过程中如果存在读入的数据页没有内存的时候,需要到缓冲池中申请数据页。当数据页不足首先将最久不使用的数据从内存中淘汰,如果是脏数据页还得先进行刷盘才能复用。可是在刷脏页过程中,若淘汰的数据页太多或者日志写满会导致mysql性能降低。所以InnoDB会有刷脏页的控制策略
InnoDB刷盘影响因素:脏页的比重、redo log写盘速度
     InnoDB_max_dirty_pages_pct脏页比重上线默认为75%,合理的设置innoDb_io_capacity的值不要超过上限。
     同时在刷盘的过程中,mysql会将旁边的数据页也会刷入。InnoDB通过innodb_flush_neighbors参数用来控制这个行为。1表示会刷入相邻的数据2.表示只刷自己。如果磁盘写性能高最好设置为0,减少sql响应时间。
     如果mysql在执行操作过程中出现抖动可能由于mysql在flush操作。
     Mysql在执行Binlog和redoLog过程有时什么样子呢?
     binlog写入机制
     执行事务过程,先将日志写入binlog cache,事务提交时再将cache写入到binlog中。对于cache系统会分配一片内存,每个线程一个,参数binlog_cache_size用于控制单个线程内binlog cache所占内存的大小。超过这个参数则暂存在磁盘中。
事务提交时,执行器将binlog cache完整事务写入binlog中,并清空binlog cache。
整个写入过程分为两步 write和fsync
write:指把日志写入到文件系统page cache,并没有写入磁盘中,速度快
fsync:将数据持久化到磁盘,该过程占用磁盘IOPS。
sync_binlog参数
等于0:表示每次提交事务只write不fsync
等于1:表示每次提交事务都执行fsync
等于n:表示事务在write后,会累积N个事务后才fsync。
     为了提升性能,实际场景考虑丢失日志量的可控性会设置到100-1000之间的值。风险:主机发生异常重启,会丢失N个事务binlog日志。
     redoLog写入机制
     首先确定redo log在写入的时经过redo log buffer、FSPage cache、hard disk
redo log buffer:物理上是Mysql进程内存
FSPage cache:写入磁盘但没有持久化,物理上是在文件系统page cache中hard disk 持久化到磁盘
      为了控制redo log写入策略,innodb_flush_log_at_trx_commit参数
等于0,表示事务提交只将redo log留在redo log buffer
等于1,表示每次事务提交都将redo log持久化到磁盘中
等于2,每次事务提交只把redo log写入page cache中。
     InnoDB后台线程,每秒把redo logbuffer中日志,调用write写入到文件系统page cache,然后调用fsync持久化到磁盘。
      所以在事务执行过程中redo log直接写入redo log buffer,然后隔一秒调用write写入到page cache中,最后持久化到磁盘中。所以说没有提交事务的redo log也有可能持久化到磁盘中。
     还有场景会将redo log buffer写入磁盘
1.redo log buffer占用空间达到innoDB_log_buffer_size一半,后台线程主动写入
2.并行事务提交时顺带将这个redo log持久化到磁盘中。
     innoDB_flush_log_at_trx_commit设置为1,事务B将redo log buffer里日志全部持久化到磁盘。会带上事务A里的日志。
     双1配置:sync_binlog和innoDb_flush_log_at_trx_commit都设置为1,一个事务完整提交需要两次刷盘,一次redo log(prepare)一次binlog。
     但是Mysql测试TPS每秒2万,刷盘得四万次?
     日志逻辑序列号(LSN)用来对应redo log写入点。LSN记录InnoDB的数据页,保证数据页不会被多次执行重复redo log。
redo log组提交:
     比如有三个事务,先到达的会选为组leader。当组成员达到3个,事务1会带着3个事务一起持久化,事务2和3直接返回。
     所以一次组提交过程组成员越多,fsync越晚调用,节约IOPS效果越好。
mysql有两个参数
binlog_group_commit_sync_delay:表示延迟多久调用fsync
binlog_grouo_commit_syn_no_delay_count:表示事务累积多少次调用fsync
这两个条件只要满足其一就会调用fsync。
     mysql出现性能瓶颈,瓶颈为IO上,可以有哪些方式提升?
1.设置binlog_group_commit_sync_delay和binlog_grouo_commit_syn_no_delay_count减少binlog写盘次数,增加语句响应时间,不会丢数据
2.sync_binlog设置大于1(常见为100-1000)但有风险主机异常会丢失binlog日志。
3.innoDb_flush_log_at_trx_commit设置2,主机掉电会丢数据 innoDb_flush_log_at_trx_commit为0时,如果mysql本身异常重启也会丢数据。
最终crash-safe保证
     客户端收到事务成功,事务一定持久化了
     客户端收到事务失败,则一定失败
     客户端收到异常,需要重连数据库连接,数据只要保证内部(数据和日志、主库和备库一致)就可以

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容