Oracle核心技术
文件夹 |
開始
- SGA/SCN
- 真正须要理解的只3个进程:lgwr、dbwr、dbwN
redo和undo
- Oracle v6:改变向量(change vector)
- 两份存储:当前状态 + redo日志
- 改变数据的方法:4步关键步骤(这使得数据改动是可逆的)
- 创建改变操作的描写叙述(redo change vector)
- undo描写叙述(插入到undo表空间的undo块中)
- undo描写叙述的描写叙述(此undo的redo change vector)
- 改变数据项
- 实际的顺序变成3 1 2 4,2条redo被合并为一条日志记录,写入到redo缓冲区
- 事务中的第一次改动包括一些特殊步骤*
- (我的小结)理论上说来,redo日志写成功即意味着事务已经成功提交。这时假设数据库崩溃导致内存中的当前状态没有更新到数据库存储中时,就能够通过redo再做一次以确保事务完毕;另外一方面,因为一个嵌套事务的失败,导致已完毕的数据库更新须要回退。这时就须要undo,而undo本身有可能因存储于易失性区域崩溃而丢失。这时就须要把undo再通过undo的redo日志再做一遍以恢复数据到前一个一致状态
- 从上面的描写叙述能够看到,事务的实现依赖于数据改动是可逆的这一点,否则状态易失(如赋值操作、文件写操作)就不可能做到一致性恢复
- 而一致性恢复依赖于全局一致性快照(即MVCC)的创建。为此须要事务号、时间戳这些特殊的底层属性来实现。这能够參考CLojure语言中相关概念
- why?undo记录阻止了其它用户查看我们正在改变的数据(中间暂时状态)
- 其它用户能够通过undo得到记录的之前的一个版本号(与他的事务视图相一
- redo allocation latch:保护redo日志缓冲区(由于仅仅有一个lgwr进行着串行的写操作)
- 所谓的latch事实上就是Linux Kernel里类似spin_lock(自旋锁)的东西
- p17 每一个人都做一点点“额外的”工作(协作的开销?),就意味着他们能够在不同的地方同一时候工作,而不必常常在同一个地方竞争(contention)
- redo simplicity
- undo complexity
- undo的存在可以让会话在不应该看到数据的最新版本号(未事务提交。)时去訪问更旧的版本号(与会话的一致性相符合)
- 读一致性:有限的ITL entries,超出的作为undo记录保存(往回倒带~)
- 回滚:将产生新的redo。(请对比代码管理系统里的revert操作。revert实际上产生一个新的commit)
- 消除回滚成本:全局暂时表
事务与一致性
- 让提交尽可能快*,让回滚慢慢来
- *而且尽可能频繁?细粒度的提交对VCS而言有助于连续集成,对于DBMS呢?
- 事务与undo
- undo段:段头、extent map、extent control header
- 事务表TRN TBL:,wrap#列?
- 事务表中条目,在v$transaction视图里称‘槽’(slot)
- x$ktuxe
- newing, & 闪回。。。
- 单个undo块可包括多个事务的undo记录
- 数据块訪问与undo
- 本节包括的内容相当重要,但因为涉及大量细节,仅仅能等有时间的时间再细看了
- 提交SCN
- 提交清除
- 延迟块清除:通过“均摊”的方式来‘隐藏’工作量
- 事务表回滚
- ORA-1555 “快照太旧”
- 大对象(LOB)
- 仅仅需关心索引的事务和读一致性处理,特例:ORA-22924
- 小结
- 一个ITL条目:xid: uba: SCN
锁与闩
- 锁和pin:FCFS。闩和Mutex(10g+,替换pin):随机抢占策略
- 闩:保护共享内存
- 可共享
- 本质上是一个内存位置和一个test-and-set的CPU原子操作的组合(#see Lock-Free数据结构)
- 相当于Linux内核里的spin_lock。spin_lock在单核CPU下不起作用
- 活动统计:v$latch_parent v$latch_children
- gets、misses、spin_gets、sleeps、sleepN、immediate_gets、immmediate_misses、wait_time
- 等待唤醒机制(相当于Linux内核里的信号量?)
- library cache latch
- 大部分闩锁在11g中取消了(仅仅剩library cache load lock)
- 锁:保护对象(锁=排队?)
- 基础结构:x$ksqrs(v$resource,标记资源) x$ksqeq(设置锁模式)
- v$lock
- “锁定”某个对象:增加到等待队列某尾。直到等待队列和转换队列之间没有会话在你前面。这时附加自己到拥有者队列
- 死锁
- TX/4等待?
- 锁模式
- NL SS RS SX RX S SSX SRX X
- 保护锁的闩锁*
- KGL锁(和pin)
- 锁和pin=〉11g后逐步被Mutex替代
缓存和复制
- 内存管理
- 10g ASMM:db_cache_size/shared_pool_size ==> 固定大小的granule
- 多个数据块缓存
- 8种类型:db_cache_size db_keep_cache_size db_recycle_cache_size db_2k_cache_size(这什么破命名) ...
- 更小的chunk
- 工作集
- x$kcbwds
- LRU/TCH算法
- 似乎比較重要,待有时间又一次细读
- REPL_AUX
- --> REPL_MAIN?
- 查找数据
- pin住缓存区
- 逻辑IO
- 更新
- 加载hash链
- 读一致性拷贝
- 物理IO
- 表扫描
写入和恢复
- lgwr
- redo sync writes和log file sync
- 10g+ 新的commit选项
- 重做日志浪费(redo wastage)
- 私有重做(private redo threads)
- dbwr
- 缓冲区头部
- 检查点队列
- 增量检查点
- 写进程的交互
- ?相对文件号()/绝对文件号(afn:)
- 恢复
解析与优化
- 数据字典缓存:v$sgastat
- 8i+ cursor_sharing
- parse活动和parse call?
- 库缓存
- 共享池
- 解析和优化(略)
- executing、locking和pinning
RAC及‘缺陷’
- GRD
- p178 虚拟IP和SCAN
- p183 至少须要从4个实例開始
- Master和Shadow
- GCS和GES
- 缓存融合