Oracle DB 内存参数
自动内存管理是用两个初始化参数进行配置的:
MEMORY_TARGET:动态控制SGA和PGA时,Oracle总共可以使用的共享内存大小,这个参数是动态的,因此提供给Oracle的内存总量是可以动态增大,也可以动态减小的。它不能超过MEMORY_MAX_TARGET参数设置的大小。默认值是0。
MEMORY_MAX_TARGET:这个参数定义了MEMORY_TARGET最大可以达到而不用重启实例的值,如果没有设置MEMORY_MAX_TARGET值,默认等于MEMORY_TARGET的值。
使用动态内存管理时,SGA_TARGET和PGA_AGGREGATE_TARGET代表它们各自内存区域的最小设置,要让Oracle完全控制内存管理,这两个参数应该设置为0。
Oracle DB 内存大小设置参数
上图展示了内存初始化参数的层次结构。虽然仅需要设置MEMORY_TARGET 来触发自动内存管理,但仍可以为各种高速缓存设置下限值。因此,如果子参数是用户设置的,则这些参数值将是Oracle DB Server 自动优化该组件时的下限值。
• 如果将SGA_TARGET和PGA_AGGREGATE_TARGET设置为非零值,则可将其分别视为SGA 和PGA 大小的下限值。MEMORY_TARGET 可以采用从SGA_TARGET+PGA_AGGREGATE_TARGET到MEMORY_MAX_SIZE的值。
• 如果设置了SGA_TARGET,则数据库将仅自动优化SGA 的子组件的大小。PGA 的自动优化与是否显式设置PGA 无关。但是,不会自动优化整个 SGA (SGA_TARGET) 和PGA ( PGA_AGGREGATE_TARGET) ,即不自动增长或收缩。
监视自动内存管理
在EM 主页(“Related Links(相关链接)”部分)中,导航到“Advisor Central> Memory Advisors(指导中心 > 内存指导)”。此时,将显示“Memory Advisors(内存指导)”页。
启用了自动内存管理后,可以在“Memory Advisors(内存指导)”页的“Allocation History(分配历史记录)”部分看到以图形方式显示的内存大小组件历史记录。第一个矩形图的上部为可优化的那部分PGA ,其下部是所有SGA 。
第二个矩形图的上部为共享池大小,其下部对应于缓冲区高速缓存大小。
在此页上,还可以通过单击“Advice (建议)”按钮访问内存目标指导。此指导将提供各种内存总大小可能实现的DB 时间改善。
注:您也可以使用V$MEMORY_TARGET_ADVISOR 视图查看内存目标指导。
如果要通过命令行监视自动内存管理做出的决定:
• V$MEMORY_DYNAMIC_COMPONENTS包含所有内存组件的当前状态
• V$MEMORY_RESIZE_OPS 包含最近完成的800 个内存大小调整请求的循环历史记录缓冲区
• V$MEMORY_TARGET_ADVICE提供针对MEMORY_TARGET 初始化参数的优化建议
动态性能视图V$MEMORY_DYNAMIC_COMPONENTS显示所有动态优化的内存组件的当前大小,其中包括SGA 和实例PGA 的总大小。V$MEMORY_TARGET_ADVICE视图提供针对MEMORY_TARGET 初始化参数的优化建议。
查看V$MEMORY_TARGET_ADVICE视图时,MEMORY_SIZE_FACTOR 为1 的行显示当前的内存大小(由MEMORY_TARGET 初始化参数设置)以及完成当前工作量所需的DB 时间量。在之前以及之后的行中,将显示使用一组替代MEMORY_TARGET 大小的结果。如果将MEMORY_TARGET 参数更改为替代大小中的任何一个,那么数据库将显示大小因子(当前大小的乘数)以及完成当前工作量的估计DB 时间。请注意,如果内存总大小小于当前MEMORY_TARGET 大小,则估计的DB 时间会增加。
sys@TEST0924> descV$MEMORY_TARGET_ADVICE
Name Null? Type
------------------------------------------------------------- ------------------------------------
MEMORY_SIZE NUMBER
MEMORY_SIZE_FACTOR NUMBER
ESTD_DB_TIME NUMBER
ESTD_DB_TIME_FACTOR NUMBER
VERSION NUMBER
sys@TEST0924> select * fromV$MEMORY_TARGET_ADVICE;
MEMORY_SIZE MEMORY_SIZE_FACTORESTD_DB_TIME ESTD_DB_TIME_FACTOR VERSION
----------- ------------------------------ ------------------- ----------
2400 .75 326 1 0
3200 1 326 1 0
4000 1.25 326 1 0
4800 1.5 326 1 0
5600 1.75 326 1 0
6400 2 326 1 0
6 rows selected.
sys@TEST0924> show parameter memory
NAME TYPE VALUE
----------------------------------------------- ------------------------------
hi_shared_memory_address integer 0
memory_max_target big integer 3200M
memory_target big integer 3200M
shared_memory_address integer 0
有效使用内存:准则
• 使SGA 适合物理内存。
• 优化以实现高缓冲区高速缓存命中率,但要注意以下几点:
– 即使有效且必需的全表扫描也会降低命中率。
– 可能存在因不必要地重复读取同一块而出现命中率虚升的情况。
• 使用内存指导。
如果可能,最好使SGA 适合物理内存,以便提供最快的访问速度。即使操作系统可能提供额外的虚拟内存,该内存也经常会因其性质而换出到磁盘。在某些平台上,可以使用LOCK_SGA 初始化参数将SGA 锁定到物理内存中。此参数不能与 AMM 或ASMM 一起使用。
执行SQL 语句时,将请求数据块进行读、写或读写操作。这被认为是一个逻辑I/O。请求某个块时,会先查看它是否已在内存中。如果不在内存中,则从磁盘中读取块,这称为物理I/O。在内存中发现块的次数与逻辑I/O 的总次数之比,称为缓冲区高速缓存命中率。
通常,命中率越高越好,因为这意味着在内存中找到了更多的块,而不必进行磁盘I/O 操作。
缓冲区高速缓存命中率高于99% 的情况不罕见,但这并不总表示系统优化好了。如果某个查询的执行频率超过了必要的次数,而且它不断地反复请求相同的块,则命中率就会提高。如果这是个低效或不必要的查询,则会虚升命中率。这是因为它首先不应以这种方式执行或不应如此频繁地执行。
此外,考虑到大型全表扫描(完全读取整个表)会降低此命中率,因为可能要从磁盘中读取整个表;此类扫描可能不会利用某些已在缓冲区高速缓存中的块。所以,如果应用程序中有一些必要的大型全表扫描,则即使是优化良好的数据库,其数据库缓冲区高速缓存命中率也可能始终很低。
使用Oracle EnterpriseManager 内存指导。这些指导可以帮助您基于特定数据库中的活动调整SGA 的大小。
库高速缓存的内存优化准则
• 为开发人员制定格式使用约定,以便SQL 语句符合高速缓存的要求。
• 使用绑定变量。
• 消除不必要的重复SQL。
• 考虑使用CURSOR_SHARING。
• 尽可能使用PL/SQL。
• 缓存序列号。
• 连接库高速缓存中的对象。
库高速缓存是共享池的一部分,它是Oracle DB 用于存储所有SQL 、Java 代码、PL/SQL 过程和程序包以及控制结构(如锁定和库高速缓存句柄)的地方。这些代码进入此中央位置的目的是为了能够让所有用户共享。共享的好处在于,所有用户都能利用SQL 代为执行的工作。因此,对于每条语句,不论它执行多少次,也不管有多少用户执行它,对语句进行语法分析和确定数据访问路径(也称为“解释计划”)之类的任务都只执行一次。
如果库高速缓存过小,则没有空间容纳所有要执行的语句,因此对于某些语句,也就无法利用此工作共享的优势。如果库高速缓存过大,又会给系统带来管理其内容的负担。
因为库高速缓存中最终可能会填满一些看似不同、实际却是同一语句副本的语句。导致此问题的一个常见原因是每条语句的格式稍有不同。如果字符串不完全比较就没有匹配项。另一个原因是使用了文字而不是绑定变量。当两条语句之间的唯一差别是文字值时,如果用绑定变量替换这些文字,则大多数情况下,这些语句的每次执行和整个系统都将受益。
可以设置CURSOR_SHARING 初始化参数,指示系统在语句的其它部分都匹配时自动用绑定变量替换文字。通常,在适当时使用绑定变量更正应用程序之前,应将此设置作为临时手段。与所有这些准则一样,使用此变量也可能有其它负面影响,这一点应该调查清楚。
避免从应用程序中的几个不同位置发出同一SQL 语句,而是使用PL/SQL 将一条或多条语句放置在一个存储过程中。以后只需调用该存储过程。这样可保证该SQL 语句是共享的,因为它只位于一个地方。同样,该SQL 语句也已经过语法分析并有了解释计划,因为它位于一个已编译的存储过程中。
序列号可以缓存。因此,如果某些序列的活动频繁,请为其设置一个合适的高速缓存大小,然后利用它。
可以使用DBMS_SHARED_POOL 程序包来连接库高速缓存中的对象。这样可减少重新加载和重新编译对象的几率。
自动共享内存管理:概览
• 自动根据工作量变化调整
• 最大程度地提高内存利用率
• 有助于消除内存不足的错误
如果AMM 不能正常工作,因为需要一个固定的PGA ,考虑使用可简化 SGA 内存管理的自动共享内存管理(ASMM) 。可以使用 SGA_TARGET初始化参数指定实例的可用SGA 内存总量,然后,Oracle DB 会自动在各个SGA 组件间分配该内存,从而确保内存的高效利用。
例如,对于白天运行大型联机事务处理(OLTP) 作业(要求大型缓冲区高速缓存)和夜晚运行并行批处理作业(要求大型池的内存空间比较大)的系统,就必须同时配置缓冲区高速缓存和大型池,以便适应峰值需求。
有了ASMM 功能,当 OLTP 作业运行时,缓冲区高速缓存会获取大部分内存来保证良好的I/O 性能。以后启动数据分析和报告批处理作业时,内存又会自动迁移到大型池,供并行查询操作使用,而不会产生内存溢出错误。
如果使用的是服务器参数文件(SPFILE) ,则Oracle DB 会在每次关闭实例时记住自动优化的组件的大小。因此,系统不需要在每次启动实例时都重新了解工作量的特性。它可以利用从以前的实例中获取的信息,从上次关闭时中断的位置开始继续评估工作量。
ASMM 的工作原理
• ASMM 以MMON 在后台捕获的工作量信息为基础。
• MMON 使用内存指导。
• 将内存移到MMAN 最迫切需要的地方。
• 如果使用SPFILE(推荐):
– 在关闭时保存组件大小
– 保存的值用于引导程序组件大小
– 无需再确定最佳值
自动共享内存管理功能使用SGA 内存中介,此内存中介由可管理性监视器( MMON) 和内存管理器( MMAN) 这两个后台进程实施。统计信息和内存指导数据由MMON 定期在内存中捕获。MMAN 根据MMON 决策来协调内存组件的大小。SGA 内存中介会不断跟踪组件的大小和待处理的大小调整操作。
SGA 内存中介会观察系统和工作量,以便确定理想的内存分配方案。SGA 内存中介每隔几分钟就执行一次这种检查,使内存始终用在需要的地方。如果没有自动共享内存管理功能,必须分别预计各组件在峰值时的内存需求,然后对其内存大小进行调整。
在工作量信息基础上,自动共享内存管理功能会:
• 定期在后台捕获统计信息
• 使用内存指导
• 进行假设分析,确定最佳内存分配方案
• 将内存移到最迫切需要的地方
• 如果使用了SPFILE,则在关闭时保存组件大小(这些大小可以在最后一次关闭前重新起用)
启用自动共享内存管理功能
要从手动共享内存管理模式下启用ASMM,执行以下操作:
1. 获取SGA_TARGET的值:
SELECT ((SELECT SUM(value) FROM V$SGA) - (SELECTCURRENT_SIZE
FROM V$SGA_DYNAMIC_FREE_MEMORY))"SGA_TARGET" FROM DUAL;
sys@TEST0924> SELECT ((SELECTSUM(value) FROM V$SGA) - (SELECT CURRENT_SIZE
2 FROMV$SGA_DYNAMIC_FREE_MEMORY)) "SGA_TARGET" FROM DUAL;
SGA_TARGET
----------
2501591040
sys@TEST0924> select2501591040/1024/1024 from dual;
2501591040/1024/1024
--------------------
2385.70313
2. 使用该值设置SGA_TARGET。
3. 将自动设置大小的SGA 组件的值设置为0。
要从自动内存管理模式切换到ASMM,请执行以下操作:
1. 将初始化参数MEMORY_TARGET 设置为0。
2. 将自动设置大小的SGA 组件的值设置为0。
启用ASMM 的具体过程取决于是从手动共享内存管理模式更改为 ASMM,还是从自动内存管理模式更改为ASMM。要从手动共享内存管理模式更改为 ASMM,请执行以下操作:
1. 运行以下查询获取SGA_TARGET的值:
SELECT ((SELECT SUM(value) FROM V$SGA) -(SELECT CURRENT_SIZE FROM
V$SGA_DYNAMIC_FREE_MEMORY)) “SGA_TARGET”FROM DUAL;
2. 设置SGA_TARGET的值:
ALTER SYSTEM SET SGA_TARGET= value[SCOPE={SPFILE|MEMORY|BOTH}]
其中value是在步骤1 中计算的值,或者是介于所有SGA 组件的总大小与
SGA_MAX_SIZE之间的某个值。
3. 将自动设置大小的SGA 组件的值设置为0。为此,需要编辑文本初始化参数文件,或者发出ALTER SYSTEM语句。如果需要,重新启动实例。
sys@TEST0924> desc v$sgainfo;
Name Null? Type
------------------------------------------------------------- ------------------------------------
NAME VARCHAR2(32)
BYTES NUMBER
RESIZEABLE VARCHAR2(3)
sys@TEST0924> select * from v$sgainfo;
NAME BYTES RES
------------------------------------------ ---
Fixed SGA Size 2232960 No
RedoBuffers 16326656 No
Buffer CacheSize 1795162112 Yes
Shared PoolSize 637534208 Yes
Large PoolSize 16777216 Yes
Java PoolSize 16777216 Yes
Streams PoolSize 16777216 Yes
Shared IO PoolSize 0 Yes
GranuleSize 16777216 No
Maximum SGASize 3340451840 No
Startup overhead in SharedPool 117967168 No
Free SGA MemoryAvailable 838860800
12 rows selected.
要从自动内存管理模式更改为ASMM,请执行以下操作:
1. 将初始化参数MEMORY_TARGET 设置为0。
ALTER SYSTEM SET MEMORY_TARGET = 0;
数据库将根据当前的SGA 内存分配设置SGA_TARGET。
2. 将自动设置大小的SGA 组件的值设置为0。完成后,重新启动实例。
禁用ASMM
• 将SGA_TARGET设置为0 可禁用自动优化功能。
• 自动优化的参数设置为其当前大小。
• SGA 大小总体上不受影响。
通过将SGA_TARGET设置为0,可以动态选择禁用自动共享内存管理。在此情况下,所有自动优化的参数的值都将设置为其对应组件的当前大小;即使用户早先为自动优化的参数指定了其它非零值,也是如此。
例如,SGA_TARGET的值为8 GB,SHARED_POOL_SIZE 的值为1 GB。
如果系统将共享池组件的大小内部调整为2 GB,则将SGA_TARGET设置为0 会导致SHARED_POOL_SIZE 被设置为2 GB,从而覆盖用户定义的原有值。
程序全局区(PGA)
默认情况下,启用自动PGA 内存管理。
程序全局区(PGA) 是包含某服务器进程的数据及控制信息的内存区。这是 Oracle Server 在服务器进程启动时创建的非共享内存,只有该服务器进程才能访问。由关联到某个Oracle 实例的所有服务器进程分配的PGA 总内存,也称为该实例分配的聚集 PGA 内存。使用共享服务器时,部分PGA 可位于 SGA 中。
PGA 内存通常包含以下各项:
专用SQL 区
专用SQL 区包含绑定信息和运行时内存结构等数据。这些信息是每个会话的SQL 语句调用所特有的;在其它方面,绑定变量有不同的值,游标的状态也不同。发出SQL 语句的每个会话都有一个专用SQL 区。提交同一SQL 语句的每个用户也都有其自己的专用SQL 区,该专用SQL 区使用一个共享SQL 区。这样,许多专用SQL 区可与同一个共享SQL 区关联。专用SQL 区的位置取决于为会话建立的连接类型。如果会话是通过专用服务器连接的,则专用SQL 区位于该服务器进程的PGA 中。不过,如果会话是通过共享服务器连接的,则部分专用SQL 区将保留在SGA 中。
游标和SQL 区
Oracle Pro*C 程序或Oracle 调用接口(OCI) 程序的应用程序开发人员可以显式打开特定专用SQL 区的游标或句柄,并在该程序的整个执行过程中将它们用作命名资源。数据库为某些SQL 语句隐式发出的递归游标也使用共享SQL 区。
工作区
对于复杂查询(例如,决策支持查询),会将大部分PGA 供内存密集型运算符分配的工作区专用,例如:
• 基于排序的运算符(如ORDER BY 、GROUP BY 和ROLLUP )和窗口函数
• 散列联接
• 位图合并
• 位图创建
• 批量加载操作使用的写缓冲区
排序运算符使用工作区(排序区),对一组行执行内存中排序。与此类似,散列联接运算符使用工作区(散列区),根据其左侧输入内容生成散列表。
工作区的大小是可以控制和优化的。通常,较大的工作区可以显著改进特定运算符的性能不过代价是消耗较多的内存。
会话内存
会话内存是用于存放会话的变量(登录信息)以及与会话相关的其它信息的内存。对于共享服务器,会话内存是共享的,而不是专用的。
自动PGA 内存管理
默认情况下,Oracle DB 会自动对供实例PGA 专用的内存总量进行全局管理。可以通过设
置初始化参数PGA_AGGREGATE_TARGET来控制此内存量。随后,Oracle DB 会努力确保
分配给所有数据库服务器进程和后台进程的PGA 内存总量始终不超过此目标值。
使用V$PARAMETER 视图
SGA_TARGET = 8G
DB_CACHE_SIZE = 0
JAVA_POOL_SIZE = 0
LARGE_POOL_SIZE = 0
SHARED_POOL_SIZE = 0
STREAMS_POOL_SIZE = 0
SELECT name, value, isdefaultFROM v$parameter WHERE name LIKE'%size';
如果为SGA_TARGET指定非零值,且未指定自动优化的SGA 参数的值,则V$PARAMETER 视图中自动优化的SGA 参数的值为 0,ISDEFAULT 列的值为TRUE。
如果已为任何自动优化的SGA 参数指定了值,则查询 V$PARAMETER 时显示的值是你为该参数指定的值。
sys@TEST0924> SELECT name, value,isdefault FROM v$parameter WHERE nameLIKE '%size';
NAME VALUE ISDEFAULT
-------------------------------------------------------------------------------- ---------
sga_max_size 3355443200 TRUE
shared_pool_size 0 FALSE
large_pool_size 0 TRUE
java_pool_size 0 TRUE
streams_pool_size 0 TRUE
shared_pool_reserved_size 31876710 TRUE
db_keep_cache_size 50331648 FALSE
db_recycle_cache_size 0 TRUE
db_flash_cache_size 0 TRUE
db_recovery_file_dest_size 9565110272 FALSE
扫描二维码关注我的微学堂
搜索刘老师微信号:Rman-2014,备注“Oracle学习与咨询”,即可添加好友;或者扫描下面二维码,关注我的“微学堂”公众号,了解最新OCP认证动态、题库及答案解析、培训机构及讲师介绍、课堂授课内容等。每天还有一篇技术文章发布哦!