• 锅子 置顶
    2019-01-04
    老师好,有一个疑问:当设置sync_binlog=0时,每次commit都只时write到page cache,并不会fsync。但是做实验时binlog文件中还是会有记录,这是什么原因呢?是不是后台线程每秒一次的轮询也会将binlog cache持久化到磁盘?还是有其他的参数控制呢?

    作者回复: 你看到的“binlog的记录”,也是从page cache读的哦。
    Page cache是操作系统文件系统上的😄

    好问题

     4
     24
  • 倪大人
    2019-01-04
    老师求解sync_binlog和binlog_group_commit_sync_no_delay_count这两个参数区别

    如果
           sync_binlog = N
           binlog_group_commit_sync_no_delay_count = M
           binlog_group_commit_sync_delay = 很大值
    这种情况fsync什么时候发生呀,min(N,M)吗?
    感觉sync_binlog搭配binlog_group_commit_sync_delay也可以实现组提交?

    如果
            sync_binlog = 0
             binlog_group_commit_sync_no_delay_count = 10
    这种情况下是累计10个事务fsync一次?
    展开

    作者回复: 好问题,我写这篇文章的时候也为了这个问题去翻了代码,是这样的:
    达到N次以后,可以刷盘了,然后再进入(sync_delay和no_delay_count)这个逻辑;

    Sync_delay如果很大,就达到no_delay_count才刷;

    只要sync_binlog=0,也会有前面的等待逻辑,但是等完后还是不调fsync😄

     1
     22
  • alias cd=rm -rf
    2019-01-28
    事务A是当前事务,这时候事务B提交了。事务B的redolog持久化时候,会顺道把A产生的redolog也持久化,这时候A的redolog状态是prepare状态么?

    作者回复: 不是。

    说明一下哈,所谓的 redo log prepare,是“当前事务提交”的一个阶段,也就是说,在事务A提交的时候,我们才会走到事务A的redo log prepare这个阶段。

    事务A在提交前,有一部分redo log被事务B提前持久化,但是事务A还没有进入提交阶段,是无所谓“redo log prepare”的。

    好问题

     3
     16
  • WilliamX
    2019-01-04
    为什么 binlog cache 是每个线程自己维护的,而 redo log buffer 是全局共用的?
    这个问题,感觉还有一点,binlog存储是以statement或者row格式存储的,而redo log是以page页格式存储的。page格式,天生就是共有的,而row格式,只跟当前事务相关

    作者回复: 嗯,这个解释也很好。👍🏿

     1
     15
  • 某、人
    2019-01-06
    有调到非双1的时候,在大促时非核心库和从库延迟较多的情况。
    设置的是sync_binlog=0和innodb_flush_log_at_trx_commit=2
    针对0和2,在mysql crash时不会出现异常,在主机挂了时,会有几种风险:
    1.如果事务的binlog和redo log都还未fsync,则该事务数据丢失
    2.如果事务binlog fsync成功,redo log未fsync,则该事务数据丢失。
    虽然binlog落盘成功,但是binlog没有恢复redo log的能力,所以redo log不能恢复.
    不过后续可以解析binlog来恢复这部分数据
    3.如果事务binlog fsync未成功,redo log成功。
    由于redo log恢复数据是在引擎层,所以重新启动数据库,redo log能恢复数据,但是不能恢复server层的binlog,则binlog丢失。
    如果该事务还未从FS page cache里发送给从库,那么主从就会出现不一致的情况
    4.如果binlog和redo log都成功fsync,那么皆大欢喜。

    老师我有几个问题:
    1.因为binlog不能被打断,那么binlog做fsync是单线程吧?
    如果是的话,那么binlog的write到fsync的时间,就应该是redo log fsync+上一个事务的binlog fsync时间。
    但是测试到的现象,一个超大事务做fsync时,对其它事务的提交影响也不大。
    如果是多线程做fsync,怎么保证的一个事务binlog在磁盘上的连续性?
    2. 5.7的并行复制是基于binlog组成员并行的,为什么很多文章说是表级别的并行复制?
    展开

    作者回复: 1. Write的时候只要写进去了,fsync其实很快的。连续性是write的时候做的(写的时候保证了连续)

    2. 你的理解应该是对的。不是表级

     2
     9
  • 一大只😴
    2019-01-05
    你是怎么验证的?等于0的时候虽然有走这个逻辑,但是最后调用fsync之前判断是0,就啥也没做就走了
    回复老师:
           老师,我说的sync_binlog=0或=1效果一样,就是看语句实际执行的效果,参数binlog_group_commit_sync_delay我设置成了500000微秒,在=1或=0时,对表进行Insert,然后都会有0.5秒的等待,也就是执行时间都是0.51 sec,关闭binlog_group_commit_sync_delay,insert执行会飞快,所以我认为=1或=0都是受组提交参数的影响的。

    作者回复: 👍🏿
    非常好

    然后再补上我回答的这个逻辑,就完备了

    
     8
  • melon
    2019-02-28
    老师帮忙看一下我binlog 组提交这块理解的对不对

    binlog write 阶段
    组里面第一个走到 binlog write 的事务记录一个时间戳,用于在 binlog fsync 阶段计算 sync delay了多少时间,姑且计为 start_time
    组里已 sync write 次数+1,姑且记为 group_write
    全局已 sync wirte 次数+1,姑且记为 global_write

    binlog fsync 阶段
    IF ( NOW - sart_time ) >= binlog_group_commit_sync_delay || group_write >= binlog_group_commit_sync_no_delay_count
        IF sync_binlog >0 && global_write >= sync_binlog
            fsync

        设置 binlog 组提交信号,让其它等待的事务继续
    ELSE
        等待 binlog 组提交信号

    另外 binlog_group_commit_sync_no_delay_count 这个参数是不是不应该设置的比并发线程数大,因为一个组里的事务应该不会比并发线程数多吧,设置大了也就没什么意义了,可以这么理解吧老师。
    展开

    作者回复: 前面的伪代码不错哈

    ”binlog_group_commit_sync_no_delay_count这个参数是不是不应该设置的比并发线程数大“,最好是这样的,否则的话,就只能等binlog_group_commit_sync_delay |时间到了

    
     6
  • Komine
    2019-01-22
    为什么binlog 是不能“被打断的”的呢?主要出于什么考虑?

    作者回复: 好问题

    我觉得一个比较重要的原因是,一个线程只能同时有一个事务在执行。

    由于这个设定,所以每当执行一个begin/start transaction的时候,就会默认提交上一个事务;
    这样如果一个事务的binlog被拆开的时候,在备库执行就会被当做多个事务分段自行,这样破坏了原子性,是有问题的。

    
     6
  • chris~jiang
    2019-08-28
    刚开始我也遇到了jacy一样的问题,认为binlog写到file里面就是写到disk了,就不理解为什么还要fsync,后来仔细回读了文章,发现binlog写到file是指写到pagecache,并不是disk。
    建议老师在描述binlog写盘的那两个步骤时,把写到file直接描述为写到pagecache,避免歧义
    
     4
  • 往事随风,顺其自然
    2019-01-04
    redolog 里面有已经提交事物日志,还有未提交事物日志都持久化到磁盘,此时异常重启,binlog 里面不是多余记录的未提交事物,干嘛不设计不添加未提交事物不更好
    
     4
  • Tunayoyo
    2019-05-31
    老师您好,innodb_flush_log_at_trx_commit设置和后台线程的刷盘操作的关系是啥?
     3
     3
  • 猪哥哥
    2019-01-10
    老师 我想问下文件系统的page cache还是不是内存, 是不是文件系统向内核申请的一块的内存?

    作者回复: 你理解的是对的

    
     3
  • xiaoyou
    2019-01-09
    老师,请教一个问题,文章说innodb的 redo log 在commit的时候不进行fsync,只会write 到page cache中。当sync_binlog>1,如果redo log 完成了prepare持久化落盘,binlog只是write page cache,此时commit标识完成write 但没有落盘,而client收到commit成功,这个时候主机掉电,启动的时候做崩溃恢复,没有commit标识和binglog,事务会回滚。我看文章说sync_binlog设置为大于1的值,会丢binlog日志,此时数据也会丢失吧?

    作者回复: 你说的对,分析得很好

    
     3
  • 一只羊
    2019-08-15
    也不知道还会不会有问题解答,试试。

    我的问题是:现在知道 redo log 和 binlog 的落盘时机。但是我不知道记录数据是在什么时候、什么方式落盘的。
    不知道还有机会得到解答不。

    作者回复: 记录数据就是先写内存,然后写日志(redo和binlog),后台会有机会将内存的数据写到数据盘

    
     2
  • Tunayoyo
    2019-05-31
    是不是说并行的事务,都在提交,redo log就不能被顺带持久化?

    作者回复: redo log不需要“顺序”持久化的

    
     2
  • alias cd=rm -rf
    2019-01-28
    老师不好意思,我接着刚才的问题问哈
    并发事务的redolog持久化,会把当前事务的redolog持久化,当前事务的redolog持久化后prepare状态么?redolog已经被持久化到磁盘了,那么当前事务提交时候,redolog变为prepare状态,这时候是从redologbuffer加载还是从磁盘加载?

    作者回复: 每个事务在提交过程的prepare阶段,会把redolog持久化; “当前事务的redolog持久化后prepare状态么”这个描述还是不清楚,你用事务A、事务B这样来描述吧😆

    redolog已经被持久化到磁盘了,那么当前事务提交时候,
    (其实这里只是“部分”被持久化,因为这个事务自己在执行的过程中,还会产生新的日志),只需要继续持久化剩下的redo log

    
     2
  • Geek_527020
    2019-01-25
    您好,老师,我有一个以后,组提交,把为提交事务的redo log写入磁盘,如果有查询,岂不是查到未提交事务的更新内容了?

    作者回复: 不会啊,有MVCC的, 08篇再看下

    
     2
  • Geek_527020
    2019-01-08
    事务还未结束,binlog和redo log就写到磁盘中了,如果出现了事务回滚,写到磁盘的数据要删除吗,如果不删除,MYSQL奔溃重启,岂不是多了操作,请老师解答下疑惑

    作者回复: 没事,这些操作没提交,崩溃恢复的时候就回滚了

    
     2
  • Mr.Strive.Z.H.L
    2019-01-08
    老师你好,看了@倪大人的问题,个人认为:
    sync_binlog和binlog_group_commit_sync_no_delay_count的最大区别主要在于,数据的丢失与否吧?

    sync_binlog = N:每个事务write后就响应客户端了。刷盘是N次事务后刷盘。N次事务之间宕机,数据丢失。

    binlog_group_commit_sync_no_delay_count=N: 必须等到N个后才能提交。换言之,会增加响应客户端的时间。但是一旦响应了,那么数据就一定持久化了。宕机的话,数据是不会丢失的。

    不知道我这么理解对不对?
    展开

    作者回复: 你的理解很到位

     1
     2
  • 慧鑫coming
    2019-01-07
    老师,请问binlog_group_commit_sync_no_delay_count和sync_binlog参数有什么区别,前者设置为10后者设置为5,那是几次write page_cache才写盘一次?

    作者回复: 这样就是每10次fsync一下(sync_no_delay_count >sync_binlog)

    
     2
我们在线,来聊聊吧