zoukankan      html  css  js  c++  java
  • Oracle 体系结构二 内存结构

    Oracle实例由共享内存块(SGA)以及大量的后台进程构成。

    SGA必须包含的数据结构:

    • 数据库缓冲区缓存
    • 日志缓冲区
    • 共享池

    可选的数据结构:

    • 大池
    • JAVA池
    • 流池
    • 其他缓冲区缓存池

    用户会话还需要服务器端的内存。此内存是不共享的PGA。每个会话都有自己专用的PGA。

    数据库缓冲区缓存

    数据库缓冲区缓存是Oracle用来执行SQL的工作区域。

    在更新数据时,用户的会话不直接更新磁盘上的数据。包含相关数据的数据块首先复制到数据库缓冲区缓存。更改应用于数据库缓冲区缓存中的这些数据块的副本。此后,块将在缓存中保留一段时间,直至其占有的缓冲区需要缓存另一块为止。

    在查询数据时,数据也要经过缓存。会话计算出哪些块包含相关的行,并将它们复制到数据库缓冲区缓存。此后,相关行的投影列传输到会话的PGA作进一步处理。与上面一样,此后块会在数据库缓冲区缓存中保留一段时间。

    数据文件的格式被设置为固定大小的块。表行和其他数据对象存储在这些块中。数据库缓冲区缓存的格式被设置为内存缓冲区,每个可以容纳一个块。与块不同,行的长度取决于为表定义的列的数量(不管列是否真的包含内容,也不考虑包含什么内容)。根据块的大小(由DBA选择)和行的大小(取决于表设计和使用),每个块中可能有多个行,也可能有一个行延伸到多个块中。

    如果缓冲区的缓存中存储的块的映像与磁盘上的映像不同,那么这样的缓冲区常称为“脏缓冲区”。当块第一次复制到其中时,缓冲区是“干净缓冲区”:此时,缓冲区中的块的映像与磁盘上的块映像是相同的。当其中的块更新时,缓冲区将变脏。最终,脏缓冲区必须写回到数据文件,此时,缓冲区又变得干净了。即使在写入磁盘后,此块也仍保留在内存中,可能有一段时间,此缓冲区不会被另一个块所重写。缓冲区的更新频率(或COMMIT的数量)与何时写回数据文件没有任何关系:改变了的块可以在COMMIT命令之前或之后写入数据文件。在正常运行过程中,常常有未提交的数据要写入数据文件,或已提交的更改还没有写入。

    在缓冲区缓存中管理块: 

    缓冲区缓存中的块实质上在一个位置上管理,但有两个不同的列表指向这些块。 

    • 脏(dirty)块列表,其中的块需要由数据库块写入器(DBWn)写入磁盘
    • 非脏(nondirty)块列表 

    Oracle采用了一种接触技术(touch count,也称使用计数)算法,如果命中缓存中的一个块,则会增加与之关联的计数器。不是说每次命中这个块都会增加技术,而是大约3秒一次。有一组相当神奇的X$表,利用其中的某个表就可以看出这个算法是怎样工作的。X$BH表显示了块缓冲区缓存中块的有关信息(文档中有记录的V$BH视图也能提供块的有关信息,不过X$BH表提供的信息更多)。在这个表中可以看到,我们命中块是,接触技术会增加。可以对这个表运行一下查询,得到5个“当前最热的块”,并把这个信息与DBA_OBJECTS视图联结,得出这些块属于哪些段。

     1 select tch,
     2        file#,
     3        dbablk,
     4        case
     5          when obj = 4294967295 then
     6           'rbs/compat segment'
     7          else
     8           (select max('(' || object_type || ')' || owner || '.' ||
     9                       object_name) || decode(count(*), 1, '', ' maybe!')
    10              from dba_objects
    11             where data_object_id = x.obj)
    12        end what
    13   from (select tch, file#, dbablk, obj
    14           from x$bh
    15          where state <> 0
    16          order by tch desc) x

    如果想了解块关联的信息,可以使用查询

    select * from dba_extents where file_id = FILE# and block_id <= DBABLK and block_id+blocks-1 >= DBABLK

     对于重复查询的块,也可以观察Oracle如何递增这个块的接触计数

    1 select tch,file#,dbablk,DUMMY
    2   from x$bh,(select dummy from dual)
    3  where obj = (select data_object_id
    4                 from dba_objects
    5                where object_name = 'DUAL'
    6                  and data_object_id is not null)

     数据库缓冲区缓存的大小会对性能产生至关重要的影响。缓存应足够大,以便能缓存所有频繁访问的块,但也不能过大,以至于它会缓存极少使用的块。如果缓存过小,那么将导致磁盘活动过多,因为频繁访问的块持续从磁盘读取,并由其他块使用和重写,然后再从磁盘读取。如果需要格式化一个极大的数据库缓冲区缓存,则实例的启动速度会变慢。

    可以动态调整数据库缓冲区缓存的大小,也可以对其进行自动管理。

    日志缓冲区

    日志缓冲区是小型的临时区域,用于短期存储将写入到磁盘上的重做日志的变更向量。执行DML语句会生成应用于数据的变更向量。有了重做日志,数据库就可以确保数据永不丢失:每当数据块发生更改时,都会将应用于块的变更向量写到重做日志,如果需要还原数据文件,则通过重做日志,可以将变更向量提取并应用于数据文件备份。这样,数据文件就可能是最新的。

    会话服务器进程不将重做记录直接写入重做日志文件,否则,每当执行DML语句是,会话将不得不等待磁盘I/O操作完成。相反,会话将重做记录写入内存中的日志缓冲区。这样做的速度将远比写入磁盘快。此后,日志缓冲区写出到重做日志文件。因此,日志缓冲区对磁盘的一次写入是来自多个事务的一批变更向量。即使如此,日志缓冲区中的变更向量也是接近实时地写入磁盘,当会话发出COMMIT语句时,会实时执行日志缓冲区写操作。写操作由日志写入器后台进程(LGWR)完成。

    日志缓冲区默认值由Oracle服务器确定,而且取决于服务器节点中的CPU数量。默认值通常是合适的。

    理解COMMIT语句的处理过程非常重要。当发出commit语句时,一部分提交处理涉及将日志缓冲区内容写入磁盘上的重做日志文件。写操作实施执行,在其进行过程中,发出commit的会话将挂起。要确保提交的事务永不丢失,那么,在缓存中的数据块发生更改(意味着事务已完成)而且将变更向量写入磁盘上的重做日志前,不能讲完成提交的消息返回给会话。

    在Oracle体系结构中,将日志缓冲区转储到磁盘是基本瓶颈之一。DML的速度不能超过LGWR将变更向量转储到联机重做日志文件的速度。

    日志缓冲区的大小固定不变,在启动实例时被设置为固定值。无法对其进行自动管理。

    共享池

    共享池是最复杂的SGA结构。它分为许多子结构,这些子结构由Oracle服务器内部管理。

    库缓存

    库缓存是内存区域,按其已分析的格式存储最近执行的代码,可以在不重新分析的情况下重用,极大的提高性能。

    数据字典缓存

    数据字典缓存有时称为“行缓存”。存储最近使用的对象定义:表、索引、用户和其他元数据定义的描述。将此类定义放在SGA的内存中,以便使所有会话可以直接访问它们,而不是被迫从磁盘上的数据字典中重复读取它们,从而提高分析性能。缓存的对象定义可以用于分析许多不同的语句。

    SQL查询和PL/SQL函数结果缓存

    Oracle服务器可以将此类查询的结果存储在内存中。结果缓存机制具有足够的智能,跟踪查询运行所针对的表是否发生了更新。默认方式下,将禁用SQL查询和PL/SQL函数结果缓存,但如果以编程方式将其启用,就可以极大地提高性能。此缓存位于共享池中:DBA可以指定其最大容量。

    共享池在实例启动时分配。可以采用手动方式重新调整,也可以根据工作负荷自动重新调整大小(如果启动了自动化机制)。

  • 相关阅读:
    解决安装vmware-tools出现的“The path "" is not a valid path to the 3.2.0-4-amd64 kernel headers”问题
    页面布局
    CSS属性/尺寸/边框/背景 超级链接
    前端
    索引
    Pymysql
    单表查询,多表查询,子查询
    表的完整性约束
    文件库,文件表,记录的增删改查
    IO多路复用,数据库mysql
  • 原文地址:https://www.cnblogs.com/zhaochunyi/p/10614846.html
Copyright © 2011-2022 走看看