oracle数据库 内存结构,Oracle面试宝典-内存结构篇

Oracle

面试宝典

-

内存结构篇

一:Oracle

内存结构由哪几部分组成?

1

User global area (UGA)

2

Program global area (PGA)

3

System global area (SGA)

4

软件代码区Software code areas

二:请分别介绍下UGA

PGA

SGA

、软件代码区?

1 UGA

UGA

是用户全局区,主要存放用户会话的相关信息,比如登录信息。

在会话的生命周期内,UGA

必须对数据库会话可用。

所以,在连接模式是专用服务器连接模式时,也就是一个会话对应一个连接,UGA

存储在

PGA

中。

但是在连接模式是共享服务器时,也就是多个会话对应一个连接,UGA

存储在

SGA

中的

large pool

,如果

large pool

空间不够,

UGA

会存储在

shared pool

。大多情况下都使用专用服务器连接模式。

2 PGA

PGA(Process Global Area)

程序全局区,

PGA

是一个非共享内存区域,它包含

Oracle

进程专用的数据和控制信息。在

Oracle

进程启动时创建

PGA

。由每个服务进程和后台进程专有,所有单个

PGA

的集合就是总实例

PGA

大小。

PGA

内容:

PGA

主要有两个区域,

私有SQL

区域、

SQL

工作区域。

私有SQL

区域存储

SQL

的绑定变量值、查询执行状态信息,客户端进程负责管理私有

SQL

区域。分配的私有

SQL

区域的数量受初始化参数

OPEN_CURSORS

的限制。

SQL

工作区主要用于排序操作、

Hash

连接、位图合并连接时使用的内存。

比如 order by

group by

等操作。

PGA

管理:

在Oracle8i

中,

PGA

调整非常复杂,要调整

SORT_AREA_SIZE

HASH_AREA_SIZE

BITMAP_MERGE_AREA_SIZE

CREATE_BITMAP_AREA_SIZE

等参数。在

ORACLE9I

以后,只需要调整

PGA_AGGREGATE_TARGET

,这个值是个软限制,比如设置大小

2G

,只是一个目标值,实际上

PGA

大小可以超过

2G

。在

12C

开始引入

PGA_AGGREGATE_LIMIT

参数限制

Oracle

实例

PGA

使用内存的上限,如果超过限制就采取终止会话的方式来降低

PGA

内存的使用量。

3 SGA

系统全局区域(SGA)

,是一组共享内存结构,所有服务器和后台进程共享

SGA

与Oracle

后台进程一起构成数据库实例。

可以在V$SGASTAT

视图中查询关于

SGA

组件的信息。最重要的

SGA

组件如下

:

Database Buffer Cache

Shared Pool

Redo Log Buffer

In-Memory Area

Large Pool

Java Pool

Fixed SGA

•可选的与性能相关的

SGA

子区域

(1)Database Buffer Cache

数据库缓冲区缓存,也称为缓冲区缓存,是数据文件上的数据块在内存中的副本。主要是为了在内存中进行高速的数据查找和更新,

尽量减少磁盘的

IO

操作。也是

SGA

中占比比较大的一块内存区域。用户访问

DB Cache

的数据比访问磁盘上的数据速度更快数

(

内存的读取效率是磁盘读取效率约

14000

)

,因此应用系统应该尽可能多地从

DB Cache

中访问数据。在大多数情况下,

DB Cache

的命中率越高,访问性能就越好。

缓冲池包括:default

默认池、

keep

保留池、

recycle

回收池

Buffer Cache

管理:

通过三条链表进行管理:HASH

链表、检查点队列链表、

LRU

链表

HASH

链表

HASH

链表的作用是通过

HASH

算法

(

消耗

CPU

资源

)

,提高

DB Cache

中数据块的定位速度。也就是逻辑读。

比如,根据需要访问块的块号、文件号计算HASH

值,在通过

HASH

值找到对应的

HASH Bucket,

搜索

Buckect

后的链表,找到目标

BH(Buffer Header),

通过

BH

找到

BA(Buffer Address)

,按照

BA

访问具体的

Buffer,

这个就是逻辑读的过程。

检查点队列链表(CKPT-Q)

主要用于记录脏块。

Buffer Cache

其实就是磁盘数据文件的缓存,以修改块的操作为例,如

update

,只是修改

Buffer Cache

中的

Buffer,

修改完成后

,update

操作就算完工了。这样

Buffer

中的数据和磁盘中的

block

就不一致了,这样的

Buffer

就是脏

Buffer

,脏块由

DBWR

进程统一写磁盘,但是

Buffer Cache

通常很大,有几万或几十万

Bufeer

,怎么在

Buffer Cache

中找到哪些是脏

Buffer

呢,这就需要一个链表,将所有脏

Buffer

都串起来,

DBWR

写脏块时,就是按照这个串起来的链表的顺序来写,这样的脏链表有两个,一个是

LRUW

,另一个是

CKPT-Q。

buffer cache

中,修改完数据后,会将对应的数据块加入到检查点队列

(CKPT-Q)

LRU

链表

(

最近最少使用链表

)

物理读时,服务器进程将数据块从数据文件读进Buffer Cache

中,假如

Buffer Cache

10000

Buffer

,那么进程应该覆盖哪个

Buffer

呢?

简单说,就是进程将数据块读进Buffer Cache

的什么地方。

答案是,覆盖最不常用的Buffer

LRU

主要就是解决如何快速找到最不常用的

Buffer

在Oracle 8i

之前,

LRU

算法

,DB Cache

LRU

上是会移动的,常用的缓冲会被换到

LRU

的热端,不常用的缓冲会被挤到

LRU

的冷端,一般来说会话分配

Cache

时,会从

LRU

的冷端开始查找。这种

LRU

算法会产生性能瓶颈

从 Oracle 8i

开始,

LRU

的算法有所改进,

LRU

链上的缓冲不再需要移动了,而是通过

tch

计数器大小值来判断某个数据块是否为热块。

(2)Redo Log Buffer

重做日志缓冲区是SGA

中的一个循环缓冲区,它存储描述数据库更改的重做条目。

重做记录是一种数据结构,它包含重做DML

DDL

操作对数据库所做更改所需的信息。数据库恢复将重做项应用于数据文件以重构丢失的更改。

LGWR

按顺序将数据块写入磁盘,而

DBW

将数据块分散写入磁盘。分散写比顺序写要慢得多。因为

LGWR

允许用户避免等待

DBW

完成缓慢的写操作,所以数据库提供了更好的性能。

LOG_BUFFER

初始化参数指定

Oracle

数据库在缓冲重做条目时使用的内存量。与其他

SGA

组件不同,重做日志缓冲区和固定

SGA

缓冲区不会将内存分成颗粒。

(3)Shared Pool

相比于Buffer Cache

,共享池中的内容可谓是杂乱无章。

Oracle

基本上将不能放进

Buffer Cache

中的数据都扔进了共享池,使得共享池的分配和释放极为频繁。

共享池中最基本的内存分配单元成为Chunk,

相当于

Buffer Cache

中的

Buffer

或块的概念。

Chunk

的大小极不统一,最新的

Chunk

可以只有十来个字节,最大的

Chunk

有几十兆甚至几百兆。基本内存单元大小的不统一,再加上频繁进行分配、释放操作,使共享池中极易产生内存碎片。总的来说,共享池是

Oracle

中最复杂的内存池。

包括以下内容:

•Library Cache

•Data Dictionary Cache

•Server Result Cache

•Reserved Pool

1

Library Cache

库缓存

主要

存储

用户提交的

SQL

语句、SQL

语句相关解析数、

SQL

执行计划、

PL/SQL

程序块等

2

Data Dictionary Cache

dictionary cache

里存放了数据字典的内存结构,包括

表的定义、Storage

信息、用户权限信息、约束定义、表的统计信息等。

SQL

语句解析期间频繁地访问数据字典。构造

dictionary cache

的目的是为了加快

SQL解析过程中语义解析

的速度。

数据字典缓存也被称为行缓存(Row Cache

),因为它是以记录行为单元存储数据的,而不像

Buffer Cache

是以数据块为单元存储数据。

3

Server Result Cache

服务器结果缓存是共享池中的内存池。与缓冲池不同,服务器结果缓存保存结果集,而不是数据块。

执行查询时,数据库将确定查询结果是否存在于查询结果缓存中,

如果结果存在,那么数据库将从缓存中检索它,而不是执行查询。缓存使数据库能够避免重新读取数据块和重新计算结果的昂贵操作。

4

Reserved Pool

保留池是共享池中的一个内存区域,Oracle

数据库可以使用它来分配大的连续内存块。

如果Oracle

解析一个

PL/SQL

程序单元,也需要从共享池中分配内存给这些程序单元对象。由于这些对象本一般比较大(如包),所以分配的内存空间也相对较大。系统经过长时间运行后,共享池可能存在大量内存碎片,导致无法满足对于大块内存段的分配。为了使有足够空间缓存大程序块,

Oracle

专门从共享池内置出一块区域来来分配内存保持这些大块。

数据库以块的形式从共享池分配内存。分块允许将大对象(

超过

5 KB)

加载到缓存中,而不需要单个连续区域。通过这种方式,数据库减少了内存碎片的产生。

(4)Large Pool

大池是一个可选的内存区域,用于比共享池更大的内存分配。

大池可以为以下情况提供大内存分配:

用于共享服务器和

Oracle XA

接口

(

用于事务与多个数据库交互

)

并行执行中使用的消息缓冲区

用于恢复管理器

(RMAN) I/O

从属的缓冲区

(5)Java Pool

Java

池是存储

Java

虚拟机

(JVM)

中所有特定于会话的

Java

代码和数据的内存区域。此内存包括在调用结束时迁移到

Java

会话空间的

Java

对象。

对于专用服务器连接,Java

池包括每个

Java

类的共享部分,包括方法和只读内存

(

如代码向量

)

,但不包括每个会话的

Java

状态。

(6)

可选的与性能相关的SGA

子区域

一些SGA

子区域只针对特定的性能特性启用。本节包含以下主题

:

In-Memory Area

Memoptimize Pool

In-Memory

是12C

开始,在

SGA

中新增加的内存区域,可以实现表数据按列存储;

In-Memory

并没有取代传统的

Buffer Cache

,二者并存在

SGA

中。列式存储在访问多行、少列情况下性能更优。

memoptimize pool

大小通过MEMOPTIMIZE_POOL_SIZE

设置,其中存储着启用了

fast lookup

表的散列索引。

从18c

开始支持

Memoptimized Rowstore

,可用于提高查询性能。针对频繁基于主键查询的

SQL

语句的性能提高十分明显。可以通过

CREATE TABLE

ALTER TABLE

MEMOPTIMIZE FOR READ

语句来启用表的

fast lookup

(7)软件代码区概述

软件代码区是存储正在运行或可以运行的代码的内存的一部分。Oracle

数据库代码存储在一个软件区域中,这个软件区域通常比用户程序的位置更具排他性和受保护性。

软件区域的大小通常是静态的,只有在软件更新或重新安装时才会改变。这些区域所需的大小因操作系统而异。

软件区域是只读的,可以安装共享的,也可以安装非共享的。有些数据库工具和实用程序(

Oracle Forms

SQL*Plus)

可以安装为共享的,但有些则不能。在可能的情况下,数据库代码是共享的,这样所有用户都可以访问它,而不需要在内存中有多个副本,从而减少了主内存,并在总体上提高了性能。如果在同一台计算机上运行,数据库的多个实例可以将相同的数据库代码区域用于不同的数据库。

欢迎关注我的微信公众号"IT小Chen",共同学习,共同成长!!!

43cff9d8b6e30d59a7bbf3ab68bea21f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值