Xinu

mysql学习笔记一-redolog、事务隔离
第一讲 整体流程学习极客时间 《MySQL实战45讲》# 查看连接状态 show processlist;长连接内...
扫描右侧二维码阅读全文
15
2020/01

mysql学习笔记一-redolog、事务隔离

第一讲 整体流程

学习极客时间 《MySQL实战45讲》

UTOOLS1577696673237.png

# 查看连接状态
show processlist;

长连接内存占用大如何解决?

  1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。
  2. 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

第二讲 redo log 与binlog

更新操作的流程

UTOOLS1577699946352.png

redo log

物理日志 redo log 用于保证 crash-safe 能力

binlog

归档日志

区别:

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

参数设置:

# 表示每次事务的 redo log 都直接持久化到磁盘。
innodb_flush_log_at_trx_commit=1 
# 表示每次事务的 binlog 都持久化到磁盘。
sync_binlog=1

第三讲 事务隔离

  1. 事务的特性:原子性、一致性、隔离性、持久性
  2. 多事务同时执行的时候,可能会出现的问题:脏读、不可重复读、幻读
  3. 事务隔离级别:读未提交、读提交、可重复读、串行化

    READ-UNCOMMITTED 
    READ-COMMITTED 
    REPEATABLE-READ
    SERIALIZABLE 
  4. 配置方法:启动参数 transaction_isolation
  5. 事务隔离的实现:每条记录在更新的时候都会同时记录一条回滚操作。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。
  6. 回滚日志什么时候删除?系统会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。
  7. 什么时候不需要了?当系统里么有比这个回滚日志更早的read-view的时候。
  8. 为什么尽量不要使用长事务。长事务意味着系统里面会存在很老的事务视图,在这个事务提交之前,回滚记录都要保留,这会导致大量占用存储空间。除此之外,长事务还占用锁资源,可能会拖垮库。
  9. 事务启动方式:

    1. 显式启动事务语句,begin或者start transaction,提交commit,回滚rollback
    2. set autocommit=0,该命令会把这个线程的自动提交关掉。这样只要执行一个select语句,事务就启动,并不会自动提交,直到主动执行commit或rollback或断开连接。
  10. 建议使用方法一,如果考虑多一次交互问题,可以使用commit work and chain语法。在autocommit=1的情况下用begin显式启动事务,如果执行commit则提交事务。如果执行commit work and chain则提交事务并自动启动下一个事务。

读取异常

脏读,一个事务中读取到另一个事务未提交的数据。例如,事务 T1 读取到另一个事务 T2 未提交的数据,如果 T2 回滚,则 T1 相当于读取到了一个被认为不可能出现的值。

不可重复读,在一个事务中,当重复读取同一条记录时,发现该记录的结果不同或者已经被删除了;如在事务 T1 中读取了一行,接着 T2 修改或者删除了该行 并提交,那么当 T1 尝试读取新的值时,就会发现改行的值已经修改或者被删除。

幻读,通常是指在一个事务中,当重复查询一个结果集时,返回的两个不同的结果集,可能是由于另一个事务插入或者删除了一些记录。例如,事务 T1 读取一个结果集,T2 修改了该结果集中的部分记录 (例如插入一条记录),T1 再次读取时发现与之前的结果不同 (多出来一条记录),就像产生幻觉一样。

在可重复读隔离级别下,普通查询是快照读,只有当前读情况下,才可能出现幻读这种情况!!

幻读仅专指“新插入的行”,读取到行的更新不算幻读!!

隔离级别与读现象

隔离级别与读现象,性能依次下降。

隔离级别脏读不可重复读取幻影数据行隔离表现
READ UNCOMMITTEDYESYESYES别人改数据的事务尚未提交,我在我的事务中也能读到。
READ COMMITTEDNOYESYES别人改数据的事务已经提交,我在我的事务中才能读到。
REPEATABLE READNONOYES别人改数据的事务已经提交,我在我的事务中也不去读。
SERIALIZABLENONONO我的事务尚未提交,别人就别想改数据。

事务的启动时机

start transaction; # 1 并不是事务的起点

update xx set xx=xx; # 2

rollback; #3

在上面的语句中,实际上在语句2开始执行的时候,事务才正式启动。事务开始就立刻启动,用下面的语句

start transaction with consistent snapshot; # 直接开启事务

事务隔离级别总结

  1. 对于可重复读,查询只承认在事务启动前就已经提交完成的数据;
  2. 对于读提交,查询只承认在语句启动前就已经提交完成的数据(读提交每次在语句启动前都会生成新的readview);
  3. 更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read);
  4. 更新时,如果当前的记录的行锁被其他事务占用的话,就需要进入锁等待;
  5. 事务启动以前所有还没提交的事务,它都不可见。
Last modification:February 24th, 2020 at 09:49 pm

Leave a Comment