Day 3 事物实现原理

事物优化

大/长事物影响 并发大容易撑爆连接池 数据锁太久容易造成阻塞和锁超时 执行时间长容易造成主从延迟 出错回滚时间长 undo log膨胀 容易造成死锁

  • 事物颗粒度最小化
  • 事物中避免远程调用,能异步就异步
  • 避免一次性处理大量数据,可拆分成多个小事物
  • 涉及更新加锁操作尽可能放在事务靠后位置
  • 应用侧保证数据一致性,非事物执行(并发是在太大的情况,尽可能减少事物操作,一般不推荐这么干,业务代码复杂度太高)

Undo Log和版本链

text
复制代码
- InnoDB每条记录里都有两个隐藏字段: trx_id 记录最后修改这条数据的事物ID,roll_pointer指向undo log。每次update不会覆盖原数据,而是把旧值存到undo log里,新值存到数据页。roll_pointer指向旧数据,形成一条完整的版本链 - 普通SELECT走快照读,不加锁,顺着版本链找到对自己可见的版本返回,写操作是当前写,读写各走各的。
  • Read View一致性视图

image.png

Redo Log重做日志

  • 重要参数

    • innodb_log_buffer_size 指定redo log buffer 大小
      • 查询 show variables like ‘%innodb_log_buffer_size%’ ;
      • 默认16M,最大值为4096M,最小值为1M
    • innodb_log_group_home_dir 指定redo log存储位置
      • 查看 show variables like ‘%innodb_log_group_home_dir%’;
    • innodb_log_files_in_group 指定redo log文件个数
      • show variables like ‘%innodb_log_files_in_group%’;
      • 默认两个,最大100个
    • innodb_log_file_size 指定单个redo log文件大小
      • show variables like ‘%innodb_log_file_size%’;
      • 默认48M,最大值为512G(是整个redo log文件之和)
  • 文件写入过程

    顺序循环写(类似于带双指针的循环队列)

    • write pos 是当前的位置 checkpoint 是当前要擦除的位置,两个指针之间的部分就是可写的位置
    • innodb_flush_log_at_trx_commit控制写入策略
      • 设成0 事物提交时只刷到redo log buffer里,由后台线程每秒刷一次到缓存里再转到硬盘,宕机会丢失1s数据
      • 设成1(默认值) 每次提交都将redo log持久化到磁盘,数据最安全,但性能最差
      • 设成2 每次提交记录redo log后,写到操作系统的page cache里,由后台线程每秒一次写入磁盘,库挂了数据还在,操作系统挂了没来得及写的话就会丢1s数据

image.png

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP