• mysql基础~基础知识问答


    一 二阶段提交与组提交
     单个事务遵循二阶段提交,组提交是针对多个并行事务触发的
     二阶段提交
     1 innoDB 事务进入 prepare 状态
     2 事务写入redo log并刷盘-组提交优化
     3 事务写入binlog并刷盘-组提交优化
     4 innodb层提交 事务进入commit状态
     组提交
      分为 flush  sync  commit阶段
      组提交之前 只有前一个事务commit后 后一个事务才能进行prepare 严重限制了并发
      flush  1  Flush Redo log 2 Write binlog
      sync   1  Sync binlog  确保 binlog落盘  
                参数 

               binlog_group_commit_sync_delay=N:在等待N μs后,开始事务刷盘

               binlog_group_commit_sync_no_delay_count=N:如果队列中的事务数达到N个,就忽视binlog_group_commit_sync_delay的设置,直接开始刷盘(图中Sync binlog)

      commit    
    • 依次将Redo log中已经prepare的事务在引擎层提交(图中InnoDB Commit)

              Commit阶段不用刷盘,如上所述,Flush阶段中的Redo log刷盘已经足够保证数据库崩溃时的数据安全了

     
    二 MVCC 机制
    基本概念:
      1 read view 事务开始时会对现有的活动事务进行一次快照,被称为read view,每次事务结束时才能被销毁
      2 行版本号 innodb的每行都有隐藏的列,我们需要记住trx_id(活动事务号),代表最新的事务ID,指向undo历史版本的指针
    具体过程
      1 即MVCC一致性度是在事务启动时,获取当前活跃事务列表。
      2 如果事务ID小于read view的最小事务ID,则可以直接读取
      3 如果事务ID 大于等于read view的最大事务ID+1,则去undo中去寻找需要的快照版本
      4 如果事务ID 介于这两者之间,则进行具体判断,如果存在与活动事务列表中,则需要读取undo的历史版本快照
    三 隔离级别
    RR模式的两个特性,解决了可重复性读和幻读的问题

    不可重复性读 一个事务内读取表中的某一行数据,多次读取结果不同
    解决方式:利用MVCC机制解决可重复读-针对select操作
    幻读 一个事务内读取表中某个范围的数据,多次读取结果不同
    说明 MySQL对于update,insert,delete使用的都是当前读模式,读取的都是当前最新的数据,所以需要添加gap锁
    解决方式:利用间隙锁解决幻读问题-针对update,insert,delete

    四  innodb_flush_log_at_trx_commit

      0 代表mysql每秒刷新到文件系统缓存,然后触发os 刷新到硬盘,mysqld进程或者linux的崩溃会导致上一秒钟所有事务数据的丢失。
      1 代表mysql每个事务都会写入文件系统缓存刷新到硬盘, 当mysql/linux出现故障时最多损失一个事务(依赖mysql刷新函数,不依赖于系统刷新函数)
      2 代表mysql每个事务都会刷新到文件系统缓存,然后os 每秒刷新缓存到硬盘 当mysql挂掉后 最多损失一个事务,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失

    五  半同步复制

      after_commit 5.6
       1 客户端提交事务
        2 存储层提交事务
        3 sync binlog->slave
        4 收到ack-信息
        5 客户端返回-commitOK
    after_sync 5.7
       1 客户端提交事务
       2 sync binlog->slave
       3 收到ack-信息(独立ack应答线程)
       4 存储引擎层提交事务
       5 客户端返回-commitOK
    总结
      1 after_commit 在于先在存储引擎提交事务再等待ack信息,假如在发送binlog的时候就发生切换,但是这时候主库已经提交了事务,主库数据丢失
       2 在存储引擎层提交事务,当前事务看不到,但是其他事务是能发现的

    六MySQL online_ddl

    一 分类
       1 copy-server-临时表(不可见文件,阻塞读写,kill后会释放空间)
       2 inplace-innodb层(不阻塞读写)
          1 norebuild-在原表进行操作,消耗成本低,由于不涉及表的重建,除创建添加索引,会产生部分二级索引的写入操作外,其余操作均只修改元数据项,即只在原表路径下产生.frm文件,不会申请row log,不会消耗过多的IO,速度通常很快。
          2 rebuild-生成新的临时表,消耗成本高,INPLACE的rebuild table方式和COPY的rebuild table方式类似,都会扫描原表数据和构建临时文件。对于很大的表来说,这个操作是很消耗 IO 和 CPU 资源的。
    二 常见操作
         1 index操作-inplace-norebuild
         2 column操作
           1 增减普通列-inplace-rebuild
           2 更改列类型-inplace-rebuild-阻塞写
           3 varchar类型扩和缩
              inplace-rebuild 需要5.7+扩目标<256(字节) 否则就会锁表-走COPY
           4 更改列默认值-inplace-norebuild
       3 自增列和主键
         1 增加主键-inplace-rebuild
         2 增加自增列-inplace-rebuild-阻塞写

     七 mysql查询

       1 using index是利用覆盖索引,using where是在server层进行过滤,和是否回表没关系,所以是否回表只需要关注using index即可
       2 using temporary
        1 用到结果集存放子表数据就会出现临时表
        2 先使用内存临时表,如果超过tmp_table_size大小,就使用磁盘临时表
        3 可以观察Created_tmp_tables状态变量值会增加
        4 常见于group by,多表联查情况
    3 using filesort
      1 涉及到没有使用索引的排序字段一定会出现using filesort
      2 参数sort_buffer_size,超过参数的限制,则会使用磁盘临时文件进行排序
      3 排序的对象包括临时表和不使用临时表情况,所以(using filesort 和using tempoary并不是一起出现 )
      4 针对临时表的排序 会先使用using temporary保存临时数据,然后再在临时表上使用filesort进行排序,最后输出结果。
      5 MySQL filesort有两种使用模式:
        模式1: sort的item保存了所需要的所有字段,排序完成后,没有必要再回表扫描。
        模式2: sort的item仅包括,待排序完成后,根据rowid查询所需要的columns。
    4 NLJ和BNL
      NLJ 从驱动表取一条记录,然后同被驱动表进行索引过滤结果,再取下一条记录以此类推
      BNL 针对索引无效(索引失效和没有索引),将驱动表的一批数据放置在join_buffer中和被驱动表进行比较
      明显降低了回标的次数和IO访问-但是依然要进行优化
       hash join 针对索引无效(索引失效和没有索引),取代BNL(join_buffer内的无序数组,无法一次性定位)
    5 ICP特性
      1 在innodb存储引擎层实现索引的二次过滤,减少server层和innodb层的交互和回标的成本
      2 查询列必须属于索引列的一部分,如果不是依然要回表,我的理解是针对联合索引最左原则失效后的一种补充优化

    8 change buffer
       1 InnoDB在进行DML操作非聚集非唯一索引时,会先判断要操作的数据页是不是在Buffer Pool中,如果不在就会先放到Change Buffer进行操作,然后再以一定的频率将数据和辅助索引数据页进行merge。这时候通常都能将多个操作合并到一次操作,减少了IO操作,尤其是辅助索引的操作大部分都是IO操作,可以大大提高DML性能
      2 什么情况下change_buffer会失效
        1 如果 delete、update 是以普通二级索引做为筛选条件,不使用change buffer
        2 根据普通二级索引进行数据查询不可避免读取数据页
        3 对于唯一二级索引(unique key),由于索引记录具有唯一性,因此无法缓存插入操作,但可以缓存删除操作
      3 一些要点
        1 change buffer会定期刷新到系统表空间,会定期merge

     4 适合场景
       1   数据库大部分是非唯一索引;
       2   业务是写多读少,或者不是写后立刻读取;

  • 相关阅读:
    CF1537C Challenging Cliffs
    CF1454E Number of Simple Paths
    六、链表
    AOP中的一些概念
    Autowired查找顺序
    webpack配置babel
    selenium处理iframe下 #document 标签
    Soul 网关 Nacos 数据同步源码解析
    安装ssl证书后,部分浏览器提示你的链接不安全,服务器应使用tls1.2或更高版本
    php 安装 imagick扩展失败 ,phpinfo一直不显示
  • 原文地址:https://www.cnblogs.com/danhuangpai/p/16028241.html
Copyright © 2020-2023  润新知