第四讲 Buffer Pool

问题:DBMS 是如何管理其内存和磁盘之间来回移动数据的?

答案:在决定如何在磁盘中来回移动数据时,我们必须考虑两个关键方面:

空间控制【Spatial Control】:

  • 将页【pages】写在在磁盘的什么地方?
  • 以及如何布局它们,才可以使得我们最大化的利用串行IO,因为磁盘的顺序读取很快,但是随机读取很慢(因此我们的目标是使经常一起访问的页【pages】在磁盘上物理上尽可能靠近)。

时间控制【Temporal Control】:

  • 何时将页面读入内存,何时将其写入磁盘?
  • 目标是最大限度地减少因必须从磁盘读取数据而导致的停顿【stall】数量

解决方法是基于空间与时间的权衡~

面向磁盘的DBMS
面向磁盘的DBMS

注:为什么数据库不适用操作系统的虚拟内存,而要用Buffer Pool ?

因为我们对查询【query】想要做什么有更好的了解,因此我们可以做好准备,并从磁盘读取数据并将其写入内存,而因为操作系统只看到粒度级别的,比如在页【page】上的读【read】和写【write】,不了解实际查询【query】如何访问这些页面,毕竟操作系统对所有的页【pages】都一视同仁,而在数据库系统中,有的页【pages】对应的是所有,有的页【pages】对应的是数据,所以所有的页【page】不因该被视为是一样的。

1 Buffer Pool Manager

1.1 Buffer Pool organization

在高层次上,缓冲池【Buffer Pool】就是一个从操作系统分配得到的一个很大的内存区域【Memory Region】,并基于数据库的页大小(Postgres时8kb,Mysql是16kb),在逻辑上将它们分为固定大小的页。数据库将在它自己的地址空间中管理它,将用它来复制查询【query】所需从磁盘访问的页【page】,并将它们放入缓冲池【buffer pool】中(需要注意的是,内存中帧对应的页不需要像磁盘中那样连续)。

  • 内存区域【Memory Region】被组织为固定大小页【pages】的数组。
  • 该数组中的条目,也被称为帧【frame】,其大小等于页【page】的大小(至于为什么这么叫,因为别的术语都有其含义,比如page,slot,block)。
  • 当 DBMS 请求某个页【page】时,会将该页【page】的一个精确副本放入其中一个帧【frame】中,注意这里一般不涉及marshing或者序列化处理,它只是逐字节复制罢了。
  • 脏页会被缓冲,不会立即写入磁盘,后面我们会在讲持久化和恢复时重温。这里面涉及的时写通【write through】和写回的【write back】(有一个单独的日志文件,叫做预写日志【write ahead log】,它会跟踪我们所做的更改,我们会确保在脏页之前刷新到磁盘中)区别。


 

1.2 Buffer Pool Meta Data

页表【Page Table】(并非操作系统的页表)负责跟踪当前内存中的页【page】。你可以将页表想象为一个哈希Map,它将页ID【Page ID】映射到帧【frame】(其在缓冲池中的位置),如下所示:

当执行引擎请求访问某个页时,页表【page table】需要告知其在缓冲之中的位置,或者告知其不在缓冲池中。在这种情况下,我必须去我的页目录【page direction】找到那个页ID在磁盘上的位置,然后决定把它复制到哪个帧里。

需要注意的是,数据库是一个线程安全的应用,当多个线程同时访问一个页表中不存在的页面时,我们需要避免多线程对页表替换更新。因此,每当我们访问一个页面时,我们需要在页表【page table】中将他钉住【pin】,这特别像一个引用计数器【reference count】,该计数表明当前有多少活跃的查询正在访问该页。我们在页表【page table】中存储这个引用计数器,而不是在页【page】中,因此当某个页被驱逐出去时,我们也不需要额外再去存储其对应的引用计数器,它只会存在于内存中,也就是页表中。

同时页表【pge table】还为每个页【page】维护着附加元数据,这些元数据时负责记录在整个系统中如何使用这些页面:

  • dirty flag:告知有其他查询自加载到内存中后修改了该页【page】
  • pin/reference counter:跟踪需要此页面保留在内存中的工作线程的数量,因此当我们运行驱逐策略时,它不能被驱逐
  • access tracking information:记录谁正在访问过页面,最后一次页面访问的时间等等

所以,当我们访问某个不存在于缓冲池中的页【page】时,那么它需要将这个位置锁存【latch】起来,然后去后台检出该页【page】,更新页表,并释放锁存【latch】。

如果我要读它,我会把它钉住,即使我要给它写入的话,我也会把它钉住,但如果我只是读它,我不会保留任何额外的信息,一旦我完成了读取,我就可以把引脚扔掉,如果我在写它,我必须维护一个脏标志,表示我修改了这个东西,这是为了防止数据库系统把它写回磁盘时直接扔掉它,因为它知道当它访问时,其他查询修改了页面因此我们必须确保这些更改最终会回到磁盘。

1.3 Lock 和 Latch

锁【lock】:

  • 保护数据库的逻辑内容免受其他事务的影响。
  • 在事务期间内持有
  • 需要能够回滚更改

锁存器【latch】:

  • 护 DBMS 内部数据结构的关键部分免受其他线程的影响
  • 在操作期间持有
  • 不需要能够回滚更改

简单的讲,锁是用户空间下的,用户保护一个高级概念,比如元组【tuple】,表【table】,数据库【database】等,需要注意的是,锁是有死锁检查以及其他保护策略的,而锁存器是系统空间下,他是低级的原语,我们主要用它保护数据库系统内的临界区,主要是数据库开发使用,他本质上等同于mutext,而且它没有死锁检查以及其他保护策略。

1.3 页表和页目录

页目录【page dictionary】是从页ID【Page ID】到数据库文件中页位置【page location】的映射。 

  • 所有更改都必须记录在磁盘上,以便 DBMS 在重新启动时能够找到它


页表【page table】是从页ID【Page ID】到缓冲池的帧中该页副本的映射。 

  • 这是一个不需要存储在磁盘上的内存数据结构

2 分配策略

全局政策【Global Policy】:

  • 为所有活跃的查询做出决策

局部政策【Local Policy】:

  • 将帧分配给特定查询,而不考虑并发查询的行为
  • 但仍然需要支持共享页面

这两种策略各有优势,现代数据库是基本都是这两种策略的组合。

2.1 缓冲池优化

  • 多个缓冲池【Multi Buffer Pool】
  • 预取【Pre-Fetching】
  • 扫描共享【Scan-Sharing】
  • 缓冲池绕过【Buffer Pool Bypass】
2.1.1 多个缓冲池

DBMS 并不总是为整个系统提供一个缓冲池。

  • 多个缓冲池实例
  • 每个数据库一个缓冲池
  • 每种页类型一个缓冲池

将内存分区到多个池有助于减少锁存器【Latch】争用(因为锁存器是锁整个页表,所以他会成为性能瓶颈),并提高局部性。

方法1 Object ID --- SQL Server的方案

在记录 id 【record ids】中嵌入对象标识符【object identifier】,然后维护从对象到特定缓冲池的映射。

方法2 Object ID --- MySQL的方案
  • 对页 ID 进行 hash,以选择要访问的缓冲池。

2.1.2 预取

DBMS还可以根据查询计划预取页面:

  • 顺序扫描 
  • 索引扫描

顺序扫描预取前(栗子里是游标分页):

顺序扫描预取后:

索引扫描预取前:

索引扫描预取前后:

根据查询计划,我们 需要页0,页1,而根据条件,我们需要检出页3,以及预取页5,而操作系统是无法做到的,因为页3和页5是不连续的。数据系统能知道这样的原因是,每一个页节点都有一对兄弟节点的指针,页3的兄弟节点是页5,因此数据库系统可以提前预取。

2.1.3 扫描共享(也叫同步扫描)

这里的基本思想是出现了一堆查询,它们想要访问同一个表,其中一个开始,它开始扫描页面,,我们可以识别出它们需要相同的数据,我们背靠背,我们的游标连接到它们的游标上,我们就可以同时读取相同的页。

扫描共享实际上处于访问方法【access method】最低的物理层。

如果一个查询想要扫描表,而另一个查询已经在执行此操作,则 DBMS 会将第二个查询的游标附加到现有游标上。
例子:

  • 完全支持 DB2、MSSQL、Teradata 和 Postgres,即对于不完全相同但读取相同页【page】的查询,这种完全扫描共享。
  • Oracle 仅支持相同查询的游标共享,简而言之,他是通过对查询座字符串hash,因此任何不一样,都会的导致无法命中。

栗子:

我们针对A表的val字段做加和【sum】,

它把游标【Cursor】移到页面上,开始读取它们,把它们取到缓冲池中,首先它得到第0页,它不在那里,所以它把它放到内存中,然后是第1页,以此类推。现在我们到第三页,我们还没有讨论过驱逐政策,但第0页是最后一个被使用的,所以我们继续把第0页驱逐出去,以放置第3。

现在Q2出现了,操作相同的表,但Q2不是加和,而是求平均值,最笨的办法,就是让 Q2 的游标到最开始。而聪明的办法是让Q2的游标附着到Q1的游标上,随着Q1指定到最后并结束,Q2会再回过头来把前面漏掉的页重新检索出来计算。

但是如果Q2里面有limit或者窗口函数,那么共享就会变得棘手!!

还有一种极端的扫描共享,叫做持续扫描共享【CONTIONOUS  SCAN SHARING】,但是没人实现过。

2.1.4 缓冲池绕过

顺序扫描操作符不会将获取的页面存储在缓冲池中以避免开销,而是放在一小块砖为该查询创建的一个工作内存中。
→ 内存被看作是运行的查询【query】的本地内存【local memory】。
→ 如果操作符需要读取磁盘上连续的大量页面,则效果很好。
→ 也可用于临时数据【temporary data】(排序【sort】、连接【join】)。
在 Informix 中称为“轻扫描【Light Scan】”

3 替换策略

当 DBMS 需要释放帧以为新页面腾出空间时,它必须决定从缓冲池中逐出哪个页面。
替换策略的目标:

  • 正确性【Correctness】
  • 准确度【Accuracy】
  • 速度【Speed】
  • 元数据开销【Meta-data overhead】:维护元数据的成本很高,我们需要跟踪页面的访问方式,这样我们就可以决定删除哪些内容
     

3.1 LRU

维护每个页面上次访问时间的单个时间戳。 当 DBMS 需要逐出一页时,选择时间戳最旧的一页。

  • 保持页面排序,以减少驱逐时的搜索时间

3.2 C LO C K

它类似于LRU,但是它不用为每一个页维护一个时间戳:

  1. 每一页都有一个引用位
  2. 当某个页被访问时,对应的引用位设置为1

用“时钟指针”组织环形缓冲区【circular buffer】中的页面:

  • 扫描时,检查页面的位是否设置为 1。
  • 如果是,则设置为0。 如果不是,那就驱逐。

缺点:

LRU + CLOCK 替换策略容易受到顺序洪泛【sequential flooding】的影响。

  • 比如某个查询【query】执行了一个读取每个页面的顺序扫描
  • 这会污染缓冲池,因为页面被读取一次,然后就不再读取了
  • 在 OLAP 工作负载中,最近使用的页面通常是最好驱逐的页面。

LRU + CLOCK 仅跟踪页面上次访问的时间,但不跟踪页面访问的频率。

顺序洪泛:

Q1访问页1

Q2顺序访问所有页,当缓冲池不足时,页1由于是最早访问的页面,因此会被驱逐

Q3访问页1,而刚被驱逐!!!

3.3 LRU-K

以时间戳的形式跟踪对每个页面的最后 K 次引用的历史记录,并计算后续访问之间的间隔。

  • 可以很好地区分引用类型

然后,DBMS 使用此历史记录来估计下次访问该页面的时间。

  • 逐出具有最长预期间隔的页面。
  • 为最近被驱逐的页面维护一个临时的内存缓存,以防止它们总是被驱逐。

3.4 MYSQL近似LRU-K

它使用单个 LRU 链表,但有两个入口点(“okd”与“young”)。
→ 新页面总是插入到old列表的头部。
→ 如果old链表中的页面再次被访问,则插入到young'链表的头部。

此时,我要访问页1,而它不在buffer pool中,我们将其加载到内存中,因为没空间了,我们需要驱逐页8,并将页1放在old链表的头部:

假设只页1再次被访问,我们可以识别到它已经在jold链表里了,因此我们将其放到young的头部,并滑动所有链表:

该方案于LRU不同点在于它ing不是维护之前访问之间的间隔, 但只要知道它在old和young链表的界限之内,那很可能是最近被访问的。

3.5 本地化LO C A L I Z AT I O N

DBMS 根据每个查询【Query】选择要驱逐的页面。 这最大限度地减少了每个查询对缓冲池的污染。

  • 跟踪每个查询【Query】访问过的页面

示例:Postgres 维护一个查询专用的小型环形缓冲区【ring buffer】。

3.6 优先级提示【Priority Hint】

DBMS 了解查询【Query】执行期间每个页面的上下文。
它可以向缓冲池提供有关某个页面是否重要的提示。

3.7 脏页

快速路径【Fast Path】:如果缓冲池中的页面不是脏的,那么 DBMS 可以简单地“删除”它。
慢速路径【Slow Path】:如果页脏了,则 DBMS 必须写回磁盘以确保其更改得以保留。


快速驱逐【n fast evictions】与将来不会再次读取的脏写页面之间的权衡。

3.8 后台写【Backgroung Write】

DBMS 可以定期遍历页表并将脏页写入磁盘。
当脏页被安全写入时,DBMS 可以逐出该页或只是取消设置dirty标志。
需要小心的是,系统在写入日志记录之前不会写入脏页......

3.9 问题

操作系统/硬件尝试通过重新排序和批处理 I/O 请求来最大化磁盘带宽。
但他们不知道哪些 I/O 请求比其他请求更重要。
许多 DBMS 告诉您切换 Linux 以使用截止日期【deadline】或 noop (FIFO) 调度程序。
→ 示例:Oracle、Vertica、MySQL

3.10 DISK I/O SCHEDULING

很多数据库在操作系统之上还有一个小的填充层,它将负责跟踪缓冲池管理器关于读取和写入的未完成的请求(DBMS 维护内部队列来跟踪来自整个系统对页的读/写请求),并决定如何将它们组合在一起以优化性能。


它本质上类似于基于不同的因素,决策不同IO请求的优先级:

  • 顺序 I/O 与随机 I/O
  • 关键路径任务【Critical Path Task】与后台任务【Background Task】
  • 表、索引、日志、临时数据【Table vs. Index vs. Log vs. Ephemeral Data】
  • 事务信息【Transaction Information】
  • 基于用户的 SLA

操作系统不知道这些事情并且可能会妨碍。

3.11 OS PAGE CACHE

大多数磁盘操作都是通过操作系统 API 进行的。 除非 DBMS 告诉它不要这样做,否则操作系统会维护自己的文件系统缓存(也称为页面缓存【page cache,】、缓冲区缓存【buffer cache】)。


大多数 DBMS 使用直接 I/O (O_DIRECT) 来绕过操作系统的缓存。我们不希望操作系统缓存我们读写的页面,因为我们想要自己来处理。如果我们使用OS的缓存,那么带来的问题有:

  • 页面的冗余副本:OS的页缓存【page cache】和数据库的buffer pool都有相同的页
  • 不同的驱逐政策。
  • 失去对文件 I/O 的控制:如果你不小心,你也会失去对磁盘上的内容何时被刷新的控制

3.12 FSYNC PROBLEMS

如果 DBMS 掉用 fwrite 会发生什么?

文件会被写入 OS 的页缓存【page cache】中,因为 OS 尝试智能,以使得速度变得更快,因此当 fwrite。返回时,页不一定被写入到磁盘中,它可能还在页缓存【page cache】中,至于什么时候会被写入磁盘,那完全是操作系统决定的。

那么如果 DBMS 调用 fsync 呢?

调用会阻塞,直到硬件返回数据已经被持久化,但是,硬件也会耍一些小游戏。

如果 fsync 失败(EIO),会发生什么?
→ Linux 将脏页标记为干净页,因为这并不是linux的panic,
→ 如果DBMS再次调用fsync,那么Linux告诉你flush成功了,但它其实在撒谎.

4 其他内存池

DBMS 需要内存来存储元组【tuples】和索引【index】以外的内容。


这些其他内存池可能并不总是由磁盘支持。取决于实现。
→ 排序 + 连接缓冲区【Sorting + Join Buffers】
→ 查询缓存【Query Caches】
→ 维护缓冲器【Maintenance Buffers】
→ 日志缓冲区【Log Buffers】
→ 字典缓存【Dictionary Caches】

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 android,后起之秀  1.1 android简介  1.2 版本分裂  1.3 谷歌的角色  1.3.1 android开源项目  1.3.2 android market  1.3.3 挑战赛、设备播种计划和谷歌i/o  1.4 android的功能和体系结构  1.4.1 内核  1.4.2 运行库和dalvik虚拟机  1.4.3 系统库  1.4.4 应用程序框架  1.5 软件开发工具包  1.6 开发人员社区  1.7 设备,设备,设备  1.7.1 硬件  1.7.2 设备的范围  1.8 所有设备之间的兼容性  1.9 不同的手机游戏  1.9.1 人手一台游戏机  1.9.2 随时上网  1.9.3 普通用户与游戏迷  1.9.4 市场很大,开发人员很少  1.10 小结 第2章 从android sdk开始  2.1 搭建开发环境  2.1.1 安装jdk  2.1.2 安装android sdk  2.1.3 安装eclipse  2.1.4 安装adt eclipse插件  2.1.5 eclipse快速浏览  2.1.6 一些实用的eclipse快捷键  2.2 android环境下的hello world  2.2.1 创建项目  2.2.2 进一步分析项目  2.2.3 编写应用程序代码  2.3 运行和调试android应用程序  2.3.1 连接设备  2.3.2 创建一个android虚拟设备  2.3.3 运行应用程序  2.3.4 调试应用程序  2.3.5 logcat和ddms  2.3.6 使用adb  2.4 小结 第3章 游戏开发基础  3.1 游戏类型  3.1.1 休闲游戏  3.1.2 益智游戏  3.1.3 动作和街机游戏  3.1.4 塔防游戏  3.1.5 创新  3.2 游戏设计:笔比代码更强大  3.2.1 游戏的核心机制  3.2.2 一个故事和一种艺术风格  3.2.3 画面和切换  3.3 代码:具体细节  3.3.1 应用程序和窗口管理  3.3.2 输入  3.3.3 文件i/o  3.3.4 音频  3.3.5 图形  3.3.6 游戏框架  3.4 小结 第4章 面向游戏开发人员的android  4.1 定义一个android应用程序:清单文件  4.1.1 [manifest]元素  4.1.2 [application]元素  4.1.3 [activity]元素  4.1.4 [uses-permission]元素  4.1.5 [uses-feature]元素  4.1.6 [uses-sdk]元素  4.1.7 10个简单步骤建立android游戏项目  4.1.8 市场过滤器  4.1.9 定义游戏图标  4.2 android api基础  4.2.1 创建测试项目  4.2.2 活动的生命周期  4.2.3 处理输入设备  4.2.4 文件处理  4.2.5 音频编程  4.2.6 播放音效  4.2.7 音乐流  4.2.8 基本图形编程  4.3 最佳实践  4.4 小结 第5章 android游戏开发框架  5.1 制定计划  5.2 androidfileio类  5.3 androidaudio、androidsound和androidmusic  5.4 androidinput和accelerometer-handler  5.4.1 accelerometerhandler:手机哪一面朝上  5.4.2 compasshandler  5.4.3 pool类:重用相当有用  5.4.4 keyboardhandler  5.4.5 触摸处理程序  5.4.6 androidinput:优秀的协调者  5.5 androidgraphics和androidpixmap  5.5.1 处理不同屏幕大小和分辨率的问题  5.5.2 androidpixmap:人物的像素  5.5.3 androidgraphics:满足绘图需求  5.5.4 androidfastrenderview  5.6 androidgame:合并所有内容  5.7 小结 第6章 mr. nom入侵android  6.1 创建资源  6.2 建立项目  6.3 mrnomgame:主要活动  6.3.1 资源:便捷的资源存储  6.3.2 设置:跟踪用户的选项设置和高分榜  6.3.3 loadingscreen:从磁盘获取资源  6.4 主菜单画面  6.5 helpscreen类  6.6 高分榜画面显示  6.6.1 渲染数字  6.6.2 画面的实现  6.7 抽象  6.7.1 抽象mr. nom的世界:模型、视图、控制器  6.7.2 gamescreen类  6.8 小结 第7章 opengl es介绍  7.1 opengl es概述以及关注它的原因  7.1.1 编程模型:一个比喻  7.1.2 投影  7.1.3 规范化设备空间和视口  7.1.4 矩阵  7.1.5 渲染管道  7.2 开始之前  7.3 glsurfaceview:从2008年开始,事情变得简单了  7.4 glgame:实现游戏接口  7.5 绘制一个红色的三角形  7.5.1 定义视口  7.5.2 定义投影矩阵  7.5.3 指定三角形  7.5.4 综合示例  7.6 指定每个顶点的颜色  7.7 纹理映射:轻松地创建壁纸  7.7.1 纹理坐标  7.7.2 上传位图  7.7.3 纹理过滤  7.7.4 释放纹理  7.7.5 有用的代码片段  7.7.6 启用纹理  7.7.7 综合示例  7.7.8 texture类  7.8 索引顶点:重用是有好处的  7.8.1 代码整合  7.8.2 vertices类  7.9 半透明混合处理  7.10 更多图元:点、线、条和扇  7.11 2d变换:操作模型视图矩阵  7.11.1 世界空间和模型空间  7.11.2 再次讨论矩阵  7.11.3 第一个使用平移的示例  7.11.4 更多的变换  7.12 性能优化  7.12.1 测量帧率  7.12.2 android 1.5平台下hero的奇特案例  7.12.3 使opengl es渲染如此慢的原因  7.12.4 移除不必要的状态改变  7.12.5 减小纹理大小意味着需要获取更少的像素  7.12.6 减少opengl es/jni方法的调用  7.12.7 绑定顶点的概念  7.12.8 写在结束之前  7.13 小结 第8章 2d游戏编程技巧  8.1 写在开始  8.2 向量  8.2.1 使用向量  8.2.2 一点三角学的知识  8.2.3 实现一个向量类  8.2.4 一个简单的用法示例  8.3 2d物理定律浅析  8.3.1 牛顿和欧拉,永远的好朋友  8.3.2 力和质量  8.3.3 理论上的运动  8.3.4 运动的实现  8.4 2d碰撞检测和对象表示  8.4.1 边界形状  8.4.2 构造边界形状  8.4.3 游戏对象的属性  8.4.4 宽阶段和窄阶段碰撞检测  8.4.5 一个详细的示例  8.5 2d照相机  8.5.1 camera2d类  8.5.2 示例  8.6 纹理图集  8.7 纹理区域、精灵和批处理:隐藏opengl es  8.7.1 textureregion类  8.7.2 spritebatcher类  8.8 精灵动画  8.8.1 animation类  8.8.2 示例  8.9 小结 第9章 super jumper:一个2dopengl es游戏  9.1 核心游戏机制  9.2 背景故事和艺术风格  9.3 画面和切换  9.4 定义游戏世界  9.5 创建资源  9.5.1 ui元素  9.5.2 使用点阵字体处理文本  9.5.3 游戏元素  9.5.4 用于救援的纹理图集  9.5.5 音乐与音效  9.6 实现super jumper  9.6.1 assets类  9.6.2 settings类  9.6.3 主活动  9.6.4 font类  9.6.5 glscreen  9.6.6 主菜单画面  9.6.7 帮助画面  9.6.8 高分画面  9.6.9 模拟类  9.6.10 游戏画面  9.6.11 worldrenderer类  9.7 是否需要优化  9.8 小结 第10章 opengl es:进入3d世界  10.1 准备工作  10.2 3d中的顶点  10.2.1 vertices3:存储3d空间位置  10.2.2 示例  10.3 透视投影:越近则越大  10.4 z-buffer:化混乱为有序  10.4.1 完善上一个例子  10.4.2 混合:身后空无一物  10.4.3 z-buffer精度与z-fighting  10.5 定义3d网格  10.5.1 立方体:3d中的“helloworld”  10.5.2 一个示例  10.6 矩阵和变换  10.6.1 矩阵堆栈  10.6.2 用矩阵堆栈实现分层系统  10.6.3 木箱太阳系的简单实例  10.7 小结 第11章 3d编程技巧  11.1 准备工作  11.2 3d中的向量  11.3 opengl es中的光照  11.3.1 光照的工作机制  11.3.2 光源  11.3.3 材质  11.3.4 opengl es中如何对光照过程进行运算:顶点法线  11.3.5 实践  11.3.6 关于opengl es中光照应用的一些建议  11.4 材质变换(mipmapping)  11.5 简单的照相机  11.5.1 第一人称照相机或欧拉照相机  11.5.2 一个欧拉照相机的示例  11.5.3 跟随照相机  11.6 加载模块  11.6.1 wavefront obj格式  11.6.2 obj加载器的实现  11.6.3 使用obj加载器  11.6.4 关于加载模型的一些建议  11.7 3d中的一些物理知识  11.8 碰撞检测与3d中的对象表达法  11.8.1 3d中的边界形状  11.8.2 边界球重叠测试  11.8.3 gameobject3d与dynamic-gameobject3d  11.9 小结 第12章 droid invaders游戏  12.1 游戏的核心机制  12.2 游戏的故事背景与艺术风格  12.3 屏幕与场景切换  12.4 定义游戏世界  12.5 创建资源  12.5.1 用户界面的资源  12.5.2 游戏资源  12.5.3 音效与音乐  12.6 开始编写代码  12.7 assets类  12.8 settings类  12.9 主活动  12.10 主菜单  12.11 游戏设置画面  12.12 模拟类  12.12.1 shield类  12.12.2 shot类  12.12.3 ship类  12.12.4 invader类  12.12.5 world类  12.13 gamescreen类  12.14 worldrender类  12.15 游戏优化  12.16 小结 第13章 发布游戏  13.1 关于测试  13.2 成为注册开发人员  13.3 给游戏的apk包签名  13.4 将游戏发布至market  13.4.1 上传资源  13.4.2 产品详情  13.4.3 发布选项  13.4.4 发布  13.4.5 市场推广  13.5 开发人员控制台  13.6 小结 第14章 进阶内容  14.1 社交网络  14.2 位置识别  14.3 多玩家功能  14.4 opengl es 2.0以及更多内容  14.5 框架及引擎  14.6 网络资源  14.7 结束语
深入解析OracleDBA入门进阶与诊断案例 扫描版 作  者:盖国强 著 出 版 社:人民邮电出版社 出版时间:2009-1-1 页  数:527 内容简介   针对数据库的启动和关闭、控制文件与数据库初始化、参数及参数文件、数据字典、内存管理、Buffer Cache与Shared Pool原理、重做、回滚与撤销、等待事件、性能诊断与SQL优化等几大Oracle热点主题,本书从基础知识入手,深入研究相关技术,并结合性能调整及丰富的诊断案例,力图将Oracle知识全面、系统、深入地展现给读者。   本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和方法,包括详细的操作步骤,具有很强的实战性和可操作性,适用于具备一定数据库基础、打算深入学习Oracle技术的数据库从业人员,尤其适用于入门、进阶以及希望深入研究Oracle技术的数据库管理人员。 目录 第1章 数据库的启动和关闭   1.1 数据库的启动   1.2 数据库的访问   1.3 数据库的关闭  第2章 控制文件与数据库初始化   2.1 控制文件的内容   2.2 SCN   2.3 检查点(Checkpoint)   2.4 数据库的初始化  第3章 参数及参数文件   3.1 初始化参数的分类   3.2 参数文件   3.3 诊断案例之一:参数文件   3.4 诊断案例之二:RAC环境参数文件  第4章 数据字典   4.1 数据字典概述   4.2 内部RDBMS(X$)表   4.3 数据字典表   4.4 静态数据字典视图   4.5 动态性能视图   4.6 最后的验证  第5章 内存管理   5.1 PGA管理   5.2 SGA管理   5.3 Oracle的内存分配和使用  第6章 Buffer Cache与Shared Pool原理   6.1 Buffer Cache原理   6.2 Shared Pool的基本原理  第7章 重做(Redo)   7.1 Redo的作用   7.2 Redo的原理   7.3 Redo与Latch   7.4 Oracle 9i Redo的增强   7.5 Oracle 10g Redo的增强   7.6 Redo的内容   7.7 产生多少Redo   7.8 Redo写的触发条件   7.9 Redo Log Buffer的大小设置   7.10 commit做了什么?   7.11 日志的状态   7.12 日志的块大小   7.13 日志文件的大小   7.14 如何调整日志文件大小   7.15 为什么热备份期间产生的Redo要比正常的多   7.16 能否不生成Redo   7.17 Redo故障的恢复   7.18 诊断案例一:通过Clear日志恢复数据库   7.19 诊断案例二:日志组过度激活的诊断   附录 数值在Oracle的内部存储  第8章 回滚与撤销   8.1 什么是回滚和撤销   8.2 回滚段存储的内容   8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表空间备份增强   8.9 回滚机制的深入研究   8.10 Oracle 9i闪回查询的新特性   8.11 使用ERRORSTACK进行错误跟踪   8.12 Oracle 10g闪回查询特性的增强   8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊情况的恢复   8.19 诊断案例之二:回滚段损坏的恢复  第9章 等待事件   9.1 等待事件的源起   9.2 从等待发现瓶颈   9.3 Oracle 10g的增强   9.4 顶级等待事件   9.5 重要等待事件  第10章 性能诊断与SQL优化   10.1 使用AUTOTRACE功能辅助SQL优化   10.2 获取SQL执行计划的方法   10.3 捕获问题SQL解决过度CPU消耗问题   10.4 使用SQL_TRACE/10046事件进行数据库诊断   10.5 使用物化视图进行翻页性能调整   10.6 一次横跨两岸的问题诊断   10.7 总结
深入解析OracleDBA入门进阶与诊断案例 扫描版 作  者:盖国强 著 出 版 社:人民邮电出版社 出版时间:2009-1-1 页  数:527 内容简介   针对数据库的启动和关闭、控制文件与数据库初始化、参数及参数文件、数据字典、内存管理、Buffer Cache与Shared Pool原理、重做、回滚与撤销、等待事件、性能诊断与SQL优化等几大Oracle热点主题,本书从基础知识入手,深入研究相关技术,并结合性能调整及丰富的诊断案例,力图将Oracle知识全面、系统、深入地展现给读者。   本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和方法,包括详细的操作步骤,具有很强的实战性和可操作性,适用于具备一定数据库基础、打算深入学习Oracle技术的数据库从业人员,尤其适用于入门、进阶以及希望深入研究Oracle技术的数据库管理人员。 目录 第1章 数据库的启动和关闭   1.1 数据库的启动   1.2 数据库的访问   1.3 数据库的关闭  第2章 控制文件与数据库初始化   2.1 控制文件的内容   2.2 SCN   2.3 检查点(Checkpoint)   2.4 数据库的初始化  第3章 参数及参数文件   3.1 初始化参数的分类   3.2 参数文件   3.3 诊断案例之一:参数文件   3.4 诊断案例之二:RAC环境参数文件  第4章 数据字典   4.1 数据字典概述   4.2 内部RDBMS(X$)表   4.3 数据字典表   4.4 静态数据字典视图   4.5 动态性能视图   4.6 最后的验证  第5章 内存管理   5.1 PGA管理   5.2 SGA管理   5.3 Oracle的内存分配和使用  第6章 Buffer Cache与Shared Pool原理   6.1 Buffer Cache原理   6.2 Shared Pool的基本原理  第7章 重做(Redo)   7.1 Redo的作用   7.2 Redo的原理   7.3 Redo与Latch   7.4 Oracle 9i Redo的增强   7.5 Oracle 10g Redo的增强   7.6 Redo的内容   7.7 产生多少Redo   7.8 Redo写的触发条件   7.9 Redo Log Buffer的大小设置   7.10 commit做了什么?   7.11 日志的状态   7.12 日志的块大小   7.13 日志文件的大小   7.14 如何调整日志文件大小   7.15 为什么热备份期间产生的Redo要比正常的多   7.16 能否不生成Redo   7.17 Redo故障的恢复   7.18 诊断案例一:通过Clear日志恢复数据库   7.19 诊断案例二:日志组过度激活的诊断   附录 数值在Oracle的内部存储  第8章 回滚与撤销   8.1 什么是回滚和撤销   8.2 回滚段存储的内容   8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表空间备份增强   8.9 回滚机制的深入研究   8.10 Oracle 9i闪回查询的新特性   8.11 使用ERRORSTACK进行错误跟踪   8.12 Oracle 10g闪回查询特性的增强   8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊情况的恢复   8.19 诊断案例之二:回滚段损坏的恢复  第9章 等待事件   9.1 等待事件的源起   9.2 从等待发现瓶颈   9.3 Oracle 10g的增强   9.4 顶级等待事件   9.5 重要等待事件  第10章 性能诊断与SQL优化   10.1 使用AUTOTRACE功能辅助SQL优化   10.2 获取SQL执行计划的方法   10.3 捕获问题SQL解决过度CPU消耗问题   10.4 使用SQL_TRACE/10046事件进行数据库诊断   10.5 使用物化视图进行翻页性能调整   10.6 一次横跨两岸的问题诊断   10.7 总结
题目1、系统为了使性能最好和协调多个用户,在多进程系统中使用一些附加进程,称为 ( A)。 选择一项: a. 后台进程 b. 单进程 c. 用户进程 d. 例程 题目2、在创建用户的命令中,下列哪个关键字是限制用户可以使用的存储空间的?(C ) 选择一项: a. MAX__EXTENTS b. NEXT_EXTENT c. QUOTA d. SIZE 题目3、数据字典由以下哪项组成?(D) 选择一项: a. 用户和权限 b. 用户与表 c. 角色与视图 d. 表和视图 题目4、Bob 想要正常关闭数据库,他执行了shutdown normal命令,但 Oracle提示该命令无效;然后他想要启动数据库, 但 Oracle提示数据库已经启动。Bob应采用什么方式才能强制关闭服务器上的数据库?( B ) 选择一项: a. NORMAL b. IMMEDIATE c. ABORT d. NONE 题目5、以下哪个不是创建用户过程中必要的信息?( D) 选择一项: a. 口令 b. 用户名 c. 临时表空间 d. 用户权限 题目6、通过执行以下哪项命令来使example表空间处于在线备份模式?(A) 选择一项: a. ALTER TABLESPACE example BEGIN BACKUP b. ALTER TABLESPACE example END BACKUP c. ALTER TABLESPACE example BEGIN d. ALTER TABLESPACE example END 题目7、数据库启动过程中何时读参数文件?(B ) 选择一项: a. 装载数据库时 b. 实例启动时 c. 每个阶段都要读 d. 打开数据库时 题目8、后台进程的跟踪文件存放于何处?(D ) 选择一项: a. ORACLE_HOME b. CORE_DUMP_DEST c. LOGFILE_DEST d. BACKGROUND_DUMP_DEST (bdump) 题目9、回退段用于存储(C )。 选择一项: a. 事务修改后的新值 b. 事务修改前后的旧值和新值 c. 事务修改前的旧值 d. 这些选项都不对 题目10、用来存储最近被SQL语句访问过的数据块的区域是( A )。 选择一项: a. Database Buffer Cache b. PGA c. Shared Pool d. UGA 题目11、以下哪个不是系统权限?(C ) 选择一项: a. DROP ANY INDEX b. CREATE VIEW c. SELECT d. CREATE SESSON 题目12、数据库实例启动的三个阶段依次是( B)。 选择一项: a. MOUNT,OPEN,NOMOUNT b. NOMOUNT,MOUNT,OPEN c. NOMOUNT,OPEN,MOUNT d. OPEN,NOMOUNT,MOUNT 题目13、在重启数据库时除了必须输入主机身份证明,还必须输入哪项内容?(A ) 选择一项: a. 数据库身份证明 b. 系统身份证明 c. ORACLE身份证明 d. 权限身份证明 题目14、直到以下哪个操作完成后,Oracle才认为事务已经提交?( C) 选择一项: a. 被修改的数据已由DBWR进程写入磁盘 b. SMON进程提交了对数据所做的修改 c. 事务所做的修改已由LGWR进程成功写入Redo Log 文件 d. PMON进程提交了对数据所做的修改 题目15、如果发生实例故障,何时会用到回退信息?( B) 选择一项: a. 实例恢复之后 b. 数据库重启后立即使用(在实例恢复之前) c. 故障发生之前 d. 回滚信息不会用于故障和恢复过程中 题目16、以下哪个不是预定义角色?(D ) 选择一项: a. DBA b. RESOURCE c. CONNECT d. CREATE SESSON 题目17、Diane 是一个新入行的DBA,当数据库服务器正在运行时,她执行了shutdown命令,然后她发现 Oracle在等待所有已连接到数据库的用户断开连接。请问她是采用哪种方式关闭数据库 的?( D) 选择一项: a. NONE b. IMMEDIATE c. ABORT d. NORMAL 题目18、一个事务中所有对数据库的操作是一个不可分割的操作序列,这个性质称为事 务的( A )。 选择一项: a. 原子性 b. 隔离性 c. 独立性 d. 孤立性 题目19、当Oracle数据库启动时,如果由于操作系统的原因,一个数据文件或重做日志 文件无法正常打开或发生故障,将发生怎样的情况?( D) 选择一项: a. Oracle将忽略这些文件,进入正常工作状态 b. Oracle将返回错误信息,并自动启动数据库恢复程序 c. Oracle将返回错误
深入解析OracleDBA入门进阶与诊断案例 扫描版 作  者:盖国强 著 出 版 社:人民邮电出版社 出版时间:2009-1-1 页  数:527 内容简介   针对数据库的启动和关闭、控制文件与数据库初始化、参数及参数文件、数据字典、内存管理、Buffer Cache与Shared Pool原理、重做、回滚与撤销、等待事件、性能诊断与SQL优化等几大Oracle热点主题,本书从基础知识入手,深入研究相关技术,并结合性能调整及丰富的诊断案例,力图将Oracle知识全面、系统、深入地展现给读者。   本书给出了大量取自实际工作现场的实例,在分析实例的过程中,兼顾深度与广度,不仅对实际问题的现象、产生原因和相关的原理进行了深入浅出的解,更主要的是,结合实际应用环境,提供了一系列解决问题的思路和方法,包括详细的操作步骤,具有很强的实战性和可操作性,适用于具备一定数据库基础、打算深入学习Oracle技术的数据库从业人员,尤其适用于入门、进阶以及希望深入研究Oracle技术的数据库管理人员。 目录 第1章 数据库的启动和关闭   1.1 数据库的启动   1.2 数据库的访问   1.3 数据库的关闭  第2章 控制文件与数据库初始化   2.1 控制文件的内容   2.2 SCN   2.3 检查点(Checkpoint)   2.4 数据库的初始化  第3章 参数及参数文件   3.1 初始化参数的分类   3.2 参数文件   3.3 诊断案例之一:参数文件   3.4 诊断案例之二:RAC环境参数文件  第4章 数据字典   4.1 数据字典概述   4.2 内部RDBMS(X$)表   4.3 数据字典表   4.4 静态数据字典视图   4.5 动态性能视图   4.6 最后的验证  第5章 内存管理   5.1 PGA管理   5.2 SGA管理   5.3 Oracle的内存分配和使用  第6章 Buffer Cache与Shared Pool原理   6.1 Buffer Cache原理   6.2 Shared Pool的基本原理  第7章 重做(Redo)   7.1 Redo的作用   7.2 Redo的原理   7.3 Redo与Latch   7.4 Oracle 9i Redo的增强   7.5 Oracle 10g Redo的增强   7.6 Redo的内容   7.7 产生多少Redo   7.8 Redo写的触发条件   7.9 Redo Log Buffer的大小设置   7.10 commit做了什么?   7.11 日志的状态   7.12 日志的块大小   7.13 日志文件的大小   7.14 如何调整日志文件大小   7.15 为什么热备份期间产生的Redo要比正常的多   7.16 能否不生成Redo   7.17 Redo故障的恢复   7.18 诊断案例一:通过Clear日志恢复数据库   7.19 诊断案例二:日志组过度激活的诊断   附录 数值在Oracle的内部存储  第8章 回滚与撤销   8.1 什么是回滚和撤销   8.2 回滚段存储的内容   8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表空间备份增强   8.9 回滚机制的深入研究   8.10 Oracle 9i闪回查询的新特性   8.11 使用ERRORSTACK进行错误跟踪   8.12 Oracle 10g闪回查询特性的增强   8.13 ORA-01555成因与解决   8.14 Oracle 11g闪回数据归档   8.15 AUM下如何重建UNDO表空间   8.16 使用Flashback Query恢复误删除数据   8.17 诊断案例之一:释放过度扩展的UNDO空间   8.18 特殊情况的恢复   8.19 诊断案例之二:回滚段损坏的恢复  第9章 等待事件   9.1 等待事件的源起   9.2 从等待发现瓶颈   9.3 Oracle 10g的增强   9.4 顶级等待事件   9.5 重要等待事件  第10章 性能诊断与SQL优化   10.1 使用AUTOTRACE功能辅助SQL优化   10.2 获取SQL执行计划的方法   10.3 捕获问题SQL解决过度CPU消耗问题   10.4 使用SQL_TRACE/10046事件进行数据库诊断   10.5 使用物化视图进行翻页性能调整   10.6 一次横跨两岸的问题诊断   10.7 总结

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值