oracle内存结构主要有两部分组成,一个是系统全局区(SYStem Global Area, SGA),所有进程都可以访问该内存区域。另外一个叫进程全局区(Process Global Area, PGA ),是一个进程专用的内存区域,其他进程不可以访问。使用oracle的自动内存管理(ASM)并设置MEMORY_TARGET参数,可以实现SGA和PGA大小的自动分配。
1 PGA介绍
一个进程专用的内存区域,其他进程不可以访问。每个进程的PGA结构不尽相同。简单介绍一下最常见的专用服务器进程的PGA。专用服务器进程是当oracle设置连接方式为专用服务器时,在用户登录时,oracle会建立一个专用服务器进程,在整个用户登录会话期间该进程都会专门为该用户服务。专用服务器进程的PGA由Private SQL Area, SQL Work Areas,Session Memory这三部分组成。
- Private SQL Area
Private SQL Area存储已经编译过SQL以及一些关于进行的会话信息。注意不要和SGA的共享池混淆。SGA的共享池是缓存程序的地方。多个Private SQL Area可能会指向同一个共享池的程序或者执行计划。 - SQL Work Areas
order by,group by,hash jion等操作是在SQL Work Areas执行的。所以SQL Work Areas的大小会影响排序,hash jion等操作 - Session Memory
存储一些会话变量的信息,例如登录用户信息
2 SGA介绍
oracle的SGA是一个很大的内存区域。实例中的每个进程都可以访问这个内存区域。SGA主要由数据库高速缓存(database buffer cache),重做日志缓存(Redo Log Buffers),共享池(shared pool),大池(large pool)组成。
2.1 数据库高速缓存(database buffer cache)
数据库高速缓存是缓存从磁盘读取到的块以及修改后写入磁盘前的块。
2.1.1 数据库高速缓存三个组成部分
- 默认池:所有段的块的一般缓存位置
- 保留池:如果一个段的块因为老化推出默认池,但是这些段的块又频繁使用,那么这些块会放在保留池中
- 回收池: 一个可选的内存区域。存储一些大段的块,避免这些大段的块挤出默认池和保留池中的其他块。
2.1.2 数据库高速缓存管理机制
有两个不同的列表指向这些数据库高速缓存的块
- 脏块列表:列表里面的块在检查点触发后,要写入磁盘
- 非脏块列表:数据库使用触点计数管理该列表的块,即在数据库的操作命中一次列表的块,则会增加与之关联的计数器的值
2.2 重做日志缓存(Redo Log Buffers)
重做日志缓存是在在线重做日志写入磁盘之前的缓存。数据库进程LGWR负责将在重做日志缓存的数据写入磁盘。触发重做日志从缓存写入磁盘有如下几种情况
- 当事务提交commit或者rollback时
- 每隔3秒会触发
- 重做日志缓存满1MB
- 在线重做日志切换
2.3 共享池(shared pool)
共享池是缓存pl/sql代码以及sql执行计划的区域。例如,使用一个sq查询时,oracle会去共享池查找是否相同的sql的执行计划,如果有,就引用执行计划,不用重新编译,生成执行计划。共享池使用最少使用原则(LRU)来进行缓存管理,当共享池的对象很少使用,它就会被使用使用较多的对象挤出共享池。
2.4 大池(large pool)
大池用于大块内存的分配。当数据库连接设为共享服务器连接时,就会使用到大池。在执行并行计算或者RMAN备份时,也会使用大池。