手机网站建设软件有哪些,内容营销的表现形式比较单一,域名备案查询系统,网站优化关键词排名怎么做参考何人听我楚狂声的代码#xff0c;深入理解数据库知识#xff0c;顺便作为自己项目的准备。
什么是事务
Transaction是关系型数据库的核心组成#xff0c;它将数据有条理地保存在储存介质(磁盘#xff09;中#xff0c; 并在逻辑上#xff0c;将数据以结构化的形态呈…参考何人听我楚狂声的代码深入理解数据库知识顺便作为自己项目的准备。
什么是事务
Transaction是关系型数据库的核心组成它将数据有条理地保存在储存介质(磁盘中 并在逻辑上将数据以结构化的形态呈现给用户。支持数据的增、删、改、查并在过程中保障数据的正确且可靠。 为了保证数据正确可靠对应的拥有四大特性
原子性Atomicity: 事务要么全部完成要么全部取消。 如果事务崩溃状态回到事务之前事务回滚。隔离性Isolation: 如果2个事务 T1 和 T2 同时运行事务 T1 和 T2 最终的结果是相同的不管 T1和T2谁先结束。持久性Durability: 一旦事务提交不管发生什么崩溃或者出错数据要保存在数据库中。一致性Consistency: 只有合法的数据依照关系约束和函数约束才能写入数据库。
如何保证原子性
begin; -- 开始一个事务
update table set A A - 1亿; -- 伪sql仅作示意
update table set B B 1亿;
-- 其他读写操作
commit; -- 提交事务要保证上面操作的原子性 就得等begin和commit之间的操作全部成功完成后才将结果统一提交给数据库保存如果途中任意一个操作失败就撤销前面的操作且操作不会提交数据库保存,这样就保证了同生共死。
如何保证隔离性
引入数据的隔离机制确保同时只能有一个事务在修改A一个修改完了另一个才来修改。 这需要对数据A加上互斥锁。在事务中更新某条数据获得的互斥锁只有在事务提交或失败之后才会释放在此之前其他事务是只能读不能写这条数据的。
这也就引出了隔离性的强度四大级别。不展开了
如何保证持久性
如果在事务提交后事务的数据还没有真正落到磁盘上此时数据库奔溃了事务对应的数据会不会丢
事务会保证数据不会丢当数据库因不可抗拒的原因奔溃后重启它会保证
成功提交的事务数据会保存到磁盘未提交的事务相应的数据会回滚
事务日志
数据库通过事务日志来达到这个目标。 事务的每一个操作增/删/改产生一条日志内容组成大概如下
LSN一个按时间顺序分配的唯一日志序列号靠后的操作的LSN比靠前的大。TransID产生操作的事务ID。PageID被修改的数据在磁盘上的位置数据以页为单位存储。PrevLSN同一个事务产生的上一条日志记录的指针。UNDO取消本次操作的方法按照此方法回滚。REDO重复本次操作的方法如有必要重复此方法保证操作成功。
磁盘上每个页保存数据的不是保存日志的都记录着最后一个修改该数据操作的LSN。数据库会通过解析事务日志将修改真正落到磁盘上(写盘)随后清理事务日志(正常情况下)。
这也是数据库在保证数据安全和性能这两个点之前的折中办法
如果每次更新都写盘由于数据是随机的会造成大量的随机IO性能会非常差如果每次更新不马上写盘那一旦数据库崩溃数据就会丢失
折中的办法就是
将数据的变更以事务日志的方式按照时间先后追加到日志缓冲区由特定算法写入事务日志这是顺序IO性能较好通过数据管理器解析事务日志由特定的算法择机进行写盘
数据库恢复
当数据库从崩溃中恢复时会有以下几个步骤
解析存在的事务日志分析哪些事务需要回滚哪些需要写盘(还没来得及写盘数据库就崩溃了)。Redo进行写盘。检测对应数据所在数据页的LSN如果数据页的LSN事务操作的LSN说明已经写过盘不然进行写盘操作。Undo, 按照LSN倒序进行回滚 经过这几个阶段在数据库恢复后可以达到奔溃前的状态也保证了数据的一致性。
XID
XID是什么
MySQL Binlog 文件由 event 组成event 有不同的类型而XID_EVENT 表示一个事务的提交操作。
当事务提交时在 binlog 依赖的内部 XA 中额外添加了 Xid 结构binlog 有多种数据类型
statement 格式记录为基本语句包含 Commitrow 格式记录为基于行mixed 格式日志记录使用混合格式
不论是 statement 还是 row 格式binlog 都会添加一个 XID_EVENT 作为事务的结束该事件记录了事务的 ID 也就是 Xid在 MySQL 进行崩溃恢复时根据 binlog 中提交的情况来决定如何恢复。
XID如何生成
MySQL 内部维护了一个全局变量 global_query_id每次执行语句的时候将它赋值给 Query_id然后给这个变量加 1。如果当前语句是这个事务执行的第一条语句那么 MySQL 还会同时把 Query_id 赋值给这个事务的 Xid。
XID是唯一的吗
global_query_id 是一个纯内存变量重启之后就清零了。所以在同一个数据库实例中不同事务的 Xid 也是有可能相同的。
但是 MySQL 重启之后会重新生成新的 binlog 文件这就保证了同一个 binlog 文件里Xid 一定是惟一的。
虽然 MySQL 重启不会导致同一个 binlog 里面出现两个相同的 Xid但是如果 global_query_id 达到上限后就会继续从 0 开始计数。从理论上讲还是就会出现同一个 binlog 里面出现相同 Xid 的场景。