oracle 好书 05 ( 内存组件与 oracle 进程 )

实例 instance: 包括 内存组件 和 进程.

必须通过实例访问数据库.

用户与数据库服务器建立连接

Oracle 提供了两种连接方式: 专用连接和共享连接( dedicate, share )

一般使用 专用 连接, 用户在客户端启动了一个应用程序, 比如 SQL*PLUS, 于是就在可与段本地启动了一个用户进程, 与 oracle服务器建立连接后, 就会在服务器端生成一个对应的服务器进程, 该进程作为用户进程的代理进程, 也叫影子进程, 从而代替客户端去执行各种命令并返回结果.也就是说, 用户在客户端输入的各种命令, 都是通过位于客户端的用户进程发送到服务器端对应的服务器进程, 并由服务器进程代替用户进程去执行具体的命令及返回结果. 在专用连接模式下, 用户进程与服务器进程是一一对应, 用户进程一旦终止, 服务器进程也随之终止.

session 和 连接 的区别:

连接: 指物理概念, 从客户端到服务器端的通信通道. 分为以下 3 种:

  • 本地登录: 从数据库服务器登录服务器, 内部通信机制.
  • C/S模式: 客户机和服务器在同一个局域网内, 借助oracle 网络组件, 通过网络设备和服务器建立连接.
  • B/S模式: 浏览器->应用服务器->数据库服务器.( 前面一层是 http, 后面一层是网络连接, tcp/ip )

深入 Shared Pool

oracle 在准备执行用户提交的 SQL 语句时, oracle 首先需要解析该语句, 而SQL语句分为两部分, 动态和静态语句, 其中静态语句难以解析, 动态语句是指, where name = ‘value’ 这个 value 就是需要动态的, 而剩下所有的都属于静态的,所以每次 oracle 会先将 SQL 语句放在内存中, 查看内存中是否有一样的静态语句, 如果有, 只是动态语句不一样, 就不需要再花大量的时间进行解析, 直接执行. 这个被放置SQL语句的内存就是 shared pool. 当然还有 pl/sql 执行计划等等也在该内存中.

如果 sql 语句使用绑定变量, 那么在 shared pool 中查找到相同的SQL语句概率就打,例如 select c1 from t1 where c2 = 1;

select c1 from t1 where c2 = 2; 如果把 1, 2 换成变量, 例如 v1, 写成 select c1 from t1 where c2 = :v1;

shared pool 内存结构

shared pool: 分为 library cache, dictionary cache

library cache: 存放了最近执行sql 语句, 存储过程, 函数, 解析树以及执行计划.

dictionary cache:  存放了 在执行SQL语句过程中, 所参照的数据字典, 包括SQL语所涉及的表名, 列名, 权限等. 这里的信息都是以数据行形式存储, 所以又叫 row cache.

内存情况: chunk 是 shared pool 中最小的内存单位, 它有时候存储 library cache 中的内容, 有时候存储 dictionary cache中的内容.

可以通过 x$ksmps 查看当前 shared pool 情况, 每条记录都表示一个 chunk.

chunk 状态:

  • free: 不包含有效对象, 可以不受限制的被分配
  • recr: recreatable, 包含的对象可以在需要的时候被临时移走, 并在需要时重建.
  • freeabl: 包含对象都是曾经被 session 用过, 并且随后会被完全或部分释放.
  • perm: permanent, 永久对象.

在 shared pool 里,可用的chunk(free类型) 会被串起来称为可用链表( free list), 也叫 bucket, 当某个进程需要 shared pool 中的一个 chunk时, 则该进程首先到符合所需空间大小的 bucket 上扫描, 找到一个尺寸最合适的 chunk, 扫描会持续到 bucket 的最末端, 知道找到完全符合尺寸的 chunk . 如果找到的chunk比需要的尺寸大, 则该 chunk 就会被分成 两个 chunk, 一个用来存放数据, 另一个则成为free类型的 chunk, 并挂到当前该 bucket上. 如果全部 free 都没有了, 则扫描已经使用过的 recreatable 类型的 chunk 链表, 释放一部分 chunck来使用. 如果还是找不到, 就会发出 ORA-4031的错误消息.  当出现4031错误时, 我们查询 v$sgastat 里可用的 shared pool空间时, 可能会发现 name 为 “free memory”的可用内存还足够大, 但是为何会报4031错呢, 事实上, 在 oracle发出 4031错误之前, 已经释放了不少的recreatable类型的chunk,因此会产生不少可用内存, 但是这些可用的chunk,没有一个chunk能够以连续的物理内存提供所需的内存空间,所以发生了4031错误.

image

对于非常大的对象, 我们可以让 oracle为它们单独从保留区域分配空间, 而不是从可用的chunk链表分配空间, shared_pool_reserved_size决定这部分空间大小, 默认为 shared_pool_size 的 5%, 这块保留区与正常 chunk 管理是完全分开的. 这块保留区的使用情况 v$shared_pool_reserved.

当用户提交SQL或PL/SQL 到 shared pool 以后, 会在library cache中生成一个可执行对象, 叫做游标( cursor), 注意: 这个游标和传统意义的游标不一样,每个游标至少由两个对象组成, 父游标( 包含名称及提交用户信息, 从 v$sqlarea视图里都是父游标的信息), 子游标

image

当一条SQL语句进入 library cache 时, 先将 SQL 文本转化为对应的 ASCII数值, 然后对这些ASCII进行 hash函数运算, 得到 hash bucket号码, 从而该SQL语句被分配到该号得 hash bucket中.

当某个进程需要处理某个对象时, 比如处理一条新进入的SQL语句时,它会对该SQL语句应用hash函数算法, 这样能够知道该对象的 hash bucket 号码, 然后进入该 hash bucket 进行扫描以确定是否存在相同的SQL语句. 如果不存在或以前存在后来又交换出内存, 就再次装载 reload.

可以通过查询 v$db_object_cache来显示 library cache 中有哪些对象被缓存, 一级对象的大小尺寸.

dictionary cache 专门用来存放 SYS schema 所拥有的对象的内存区域. 为了更快的解析 SQL 语句速度, 不用过多担心.

解析SQL语句过程

硬解析 和 软解析 ( 一条SQL语句在第一次被执行时必须进行硬解析 )

image

image

这里的 shared pool latch, 是锁.

image

image

image

image

设置 shared pool

“不要太大, 也不要太小”的原则, 然后, 让系统运行一段事件, 监控 shared pool 使用情况, 最后给出一个比较合理的值. 一般 shared pool 是 SGA 的 10%, 但是不要超过 1GB, 只要将 statistics_level 设置为typical( 默认) 或 all, 就能启动对 shared pool的建议功能, 如果设置为 basic, 则关闭建议功能.

深入 Log Buffer

一个日志文件写满以后转换到另外一个日志文件继续写的过程叫日志切换 log switch.

归档的过程就是将写满的联机日志文件复制到预先指定的目录的过程.

强烈建议在生产库中选择这种归档方式, 只有当一个联机日志文件完成归档以后, 该联机日志文件才能够被再次循环使用.

只有被修改的数据块的日志信息写入了联机日志文件以后, 该被修改的数据块才可以说是安全的, 如果日志信息在没有被写入日志文件时发生实例崩溃, 这时对数据的修改仍将丢失. LGWR 负责将 Log Buffer中的内容写入联机日志文件.

image

从以上内容可知, oracle中写 lgwr 即日志文件与 dbwn 数据文件是独立的,也就是说, 当把数据写到真正的磁盘上的时候,未必它的日志文件就写到了磁盘的日志文件中,没准还在内存的日志缓冲区,这也就是证明了,为什么恢复数据库时要有前滚和后滚。

log buffer 内存结构

image

image

Buffer Cache 的管理机制

LRU 链表结构介绍 ( Least recently used )

dirty buffer, free buffer, clean buffer( buffer 内容与数据文件一致), pin buffer(当前正在更新的内存数据块)

对于 clean buffer, free buffer 我们都统称 为可用数据块, 因为其中的内容可以被新的数据内容覆盖.

image

image

配置多个 DBWn 进程, 参数 db_writer_processe

image

DBWn , CKPT, LGWR 进程之间的合作

image

image

image

image

这个点应该就是检查点.

image

image

检查点:

完全检查点: ( 触发完全检查点 )

1. alter system checkpoint 命令

2. shutdown abort 以外的正常关闭数据库

日志切换触发的是增量检查点

image

image

image

image

- large pool

  主要用于分担 shared pool 的压力。这块内存区域直接从SGA划分,large_pool_size参数决定大小。

  作用:

  ~ 为并行查询所派生出来的从属进程提供空间

  ~ 如果在备份和恢复时,启用了异步I/O, 则备份和恢复操作会在large pool中完成

  ~ 如果采用了并行连接方式(shared server), 则session所占用的共享内存从 large pool里进行分配。

- 自动共享内存管理

  从 oracle 10g开始,oracle提供了自动 SGA 的管理 (ASSM), 自动管理我们只要设置一个SGA总大小就可以了。

  sga_target 来启动 ASSM,该参数定义了SGA总容量.

  statistics_level 必须设置为 typical 或 all

  sga_max_size, sga_target 不能超过 sga_max_size.

  ASSM 只能自动调整5个内存池大小,shared pool, buffer cache, large pool, java pool, stream pool.

  而 log buffer, keep buffer cache 仍然需要DBA设置

  image

  image

  image

  将 sga_target 参数设置成 0 ,可以禁用 ASSM, ORACLE 会自动将当前内存池的大小赋给对应的初始化参数(shared_pool_size, db_cache_size)

- PGA 管理

  是一个内存区域,该区域中包含了与某个特定服务器进程相关的数据和控制信息,每个进程都具有自己私有的PGA,(比如 对于纳西需要执行比较复杂的SQL的session来说,比如需要进行排序,hash连接(hash join))

笼统的讲,PGA 里包含了当前进程所使用的有关操作系统资源的信息( 比如打开文件句柄 ) 以及一些与当前进程相关的一些私有状态信息. 每个PGA分两部分

  > 固定PGA( fixed PGA )

  > 变化PGA, PGA堆

  > 还有别的,就不一一列举了

  ~ PGA 自动管理

  设置 workarea_size_policy 为 auto, 分配内存总和 pga_aggregate_target

  PGA 分不同用途设置不同大小,默认先设置 总内存的 40% 看看运行情况,可以适当调整 30%~50%

  DBA需要不断监控,调整,oracle为了帮助我们确定这个参数,引入了一个新的视图 v$pga_target_advice

  为了使用该视图,必须将初始化参数 statistics_level设置成 typical 或 all.

  image

posted @ 2013-03-20 08:38  神之一招  阅读(497)  评论(0编辑  收藏  举报