共享池共享池缓存各种类型的程序数据。例如,共享池存储解析sql、PL/SQL代码、系统参数和数据字典信息。共享池涉及到数据库中发生的几乎所有的操作。例如,如果用户执行SQL语句,则oracle数据库访问共享
共享池
共享池缓存各种类型的程序数据。
例如,共享池存储解析sql、PL/SQL代码、系统参数和数据字典信息。共享池涉及到数据库中发生的几乎所有的操作。例如,如果用户执行SQL语句,则oracle数据库访问共享池。
共享池分为几个组件,其中最重要的部分如下图所示:
这些结构包括:
·库缓存
·数据字典缓存
·服务器结果缓存
·保留池
库缓存详解
库缓存是存储可执行SQL和PL/SQL代码的共享池内存结构。
该缓存包含共享的SQL和PL/SQL区和控制结构,如锁和库缓存句柄。在共享服务器架构中,库缓存还包含私有的SQL区域。
当执行SQL语句时,数据库尝试重用以前执行的代码。如果一个SQL语句的解析存在于库缓存并且可以被共享,那么数据库就会重用该代码,称为软解析或库缓存命中(cache hit)。否则,数据库必须构建应用程序的新的可执行版本,称为硬解析或缓存遗漏(cache miss)。
共享SQL区
数据库会处理每个运行在共享SQL区和私有SQL区的SQL语句。
数据库在共享SQL区处理第一次出现的SQL语句,该区域可被所有用户访问,并且包含语句解析树和执行计划。对于每一个唯一的SQL语句,只存在一个共享的SQL区。每个会话发出一个SQL语句都会在PGA中产生一个私有SQL区与之对应,即便是不同会话提交相同的SQL语句,但是每个会话都会有属于自己的SQL区。PGA中每个私有的SQL区都会与共享SQL区相关联。
当应用程序提交类似的SQL语句时,数据库将自动确定。数据库同时考虑由用户和应用程序直接发出的SQL语句,以及语句在内部发出的递归SQL语句。
数据库执行以下步骤:
1、检查共享池,查看在共享SQL区域是否存在语法语义相似的语句
·如果存在相同的语句,那么数据库将会直接使用它们,从而减少内存消耗。
·如果不存在相同的语句,那么数据库将会在共享池中分配一个新的共享SQL区。具有相同语法 但不同语意的语句使用子游标。
在这两种情况中,用户的私有SQL区域指向包含语句和执行计划的共享SQL区域。
2、为会话分配一个私有的SQL区域
私有SQL区域的位置取决于会话建立的连接方式。如果会话是通过共享服务器连接,那么私有SQL区域的一部分将会保留在SGA中。
下图显示了一个专用的服务器架构,其中两个会话在它们自己的PGA中保留同一SQL语句的副本。在共享服务器中,此副本位于UGA,它位于大池中,当大池不存在时副本则会存在于共享池中。
程序单元和库缓存
库缓存包含PL/SQL程序和Java类的可执行形式。这些项目统称为程序单元。
数据库处理程序单元与处理SQL语句类似。例如,数据库分配一个共享区域来保存解析的、已编译的PL/SQL程序的形式。数据库分配一个私有区域来保存特定于运行该程序的会话值,包括本地、全局和包变量,以及执行SQL的缓冲区。如果多个用户运行相同的程序,那么每个用户都维护自己的私有SQL区域的一个单独的副本,该副本包含特定于会话的值,并访问单个共享的SQL区域。
数据库在PL/SQL程序单元内处理单个SQL语句,如前所述。尽管这些SQL语句起源于PL/SQL程序单元,但它们使用共享区域来保存它们的解析语句并且使用每个会话的私有区域来执行语句。
分配和重新利用共享池中的内存区
在解析新的SQL语句时,数据库会分配共享池内存。内存的大小取决于语句的复杂程度。
一般情况下,共享池中的一个项目会被一直保持,直到它根据LRU算法被删除。该数据库允许多个会话使用的共享池项在内存中停留,只要它们是有用的,即使创建该项目的进程终止了。这种机制可以最小化SQL语句的开销和处理。
如果新的项目需要空间,那么数据库就可以将不常用的项目所占用的空间释放掉。共享的SQL区域可以从共享池中删除,即使共享的SQL区域对应于不长使用的开放游标。如果随后使用open cursor运行它的语句,oracle数据库就会对语句进行修复,并分配一个新的共享SQL区域。
数据库在以下情况下从共享池中删除共享的SQL区域:
·如果数据库收集表、表集群或索引的统计信息,那么在默认情况下,数据库将逐渐删除包含在一段时间之后引用分析对象的语句的所有共享SQL区域。下一次运行删除语句时,数据库在一个新的共享SQL区域中解析它,以反映模式对象的新统计数据。
·如果一个模式对象在SQL语句中被引用,如果这个对象后来被一个DDL语句修改,那么该数据库就会使共享的SQL区域失效。在下一次运行时,优化器必须重新解析该语句。
·如果更改全局数据库名称(全局数据库名称=数据库名+数据库域名,如:oradb.fj.jtyz),则数据库将会从共享池中删除所有信息。
为了评估数据库实例重启后可能出现的性能问题,请使用ALTER SYSTEM FLUSH SHARED_POOL语句手动删除共享池中的所有信息。
数据字典缓存
数据字典是数据库表和视图的集合,包含关于数据库、其结构和用户的参考信息。
oracle数据库经常在SQL语句解析期间访问数据字典。在oracle数据库中经常访问数据字典,指定以下特殊内存位置来存放字典数据:
·数据字典缓存
这个缓存包含关于数据库对象的信息。缓存也被称为行缓存,因为它将数据保存为行而不是缓冲区。
·库缓存
所有服务器进程共享这些缓存,以便访问数据字典信息。
服务结果缓存
服务器结果缓存是共享池中的一个内存池。与缓冲池不同,服务器结果缓存包含结果集,而不是数据块。
服务器结果缓存包含SQL查询结果缓存和PL/SQL函数结果缓存,它们共享相同的基础结构。
客户端结果缓存与服务器结果缓存不同。客户端缓存是应用程序级别配置的,它位于客户机内存中,而不是在数据库内存中。
SQL查询结果缓存
SQL查询结果缓存是服务器结果缓存的一个子集,它存储查询和查询片段的结果。
大多数应用程序都得益于这种性能改进。考虑到一个重复的运行相同的select语句的应用程序。如果结果被缓存,那么数据库将立即返回它们。这样,数据库避免了重新运行块和重新计算结果的昂贵操作。
当查询执行时,数据库搜索内存,以确定结果缓存中是否存在结果。如果结果存在,那么数据库将从内存中检索结果而不是执行查询。如果没有缓存结果,则数据库执行查询并将结果返回,然后将结果存储在结果缓存中。每当事务修改用于构造缓存结果的数据库对象的数据或元数据时,数据库就会自动地使缓存的结果失效。
用户可以使用RESULT_CACHE提示对查询或查询片段进行注释,以指示数据库应该存储在SQL查询结果缓存中的结果。RESULT_CACHE_MODE初始化参数确定SQL查询结果缓存是否用于所有查询,还是仅仅用于带注释的查询。
PL/SQL函数结果缓存
PL/SQL函数结果缓存是存储函数结果集的服务器结果缓存的子集。
如果没有缓存,那么1000个函数调用(1s/个)将花费1000秒的时间。有了缓存,使用相同输入的1000个函数调用的只会花费1秒的时间。结果缓存的优秀候选函数经常被调用,这些函数依赖于相对静态的数据。
PL/SQL函数代码可以包含一个请求来缓存它的结果。在调用这个函数时,系统检查缓存。如果缓存包含先前使用相同参数值的函数调用的结果,那么系统将直接会把缓存值返回给请求者,并且数据库不会再执行该函数体。如果缓存不包含结果,那么系统将执行该函数体,并将对于这些参数值的结果添加到缓存中,然后将控制权返回给调用者。
你可以指定oracle数据库使用的数据库对象来计算缓存的结果,因此如果它们中的任何一个被更新,那么缓存的结果就会变得无效,并且必须重新计算。
缓存可以积累很多结果——一个结果是每一个被调用的参数值的唯一组合。如果数据库需要更多的内存,那么它就需要计算出一个或多个缓存的结果。
保留池
保留池是oracle数据库可以用来分配大量连续内存块的共享池中的内存区域。
数据库从共享池中分配内存。块允许大型对象(超过5Kb)加载到缓存中,而不需要请求单个相邻区域。这样,数据库就减少了因为碎片而耗尽连续内存的可能性。
不同寻常的是,Java、PL/SQL或SQL游标可能会从大于5kb的共享池中进行分配的。为了让这些分配最有效的进行,数据库将一小部分共享池隔离在预留的池中。
大池
大池是一个可选的内存区域,用于内存分配,大于共享池的内存分配。
大池可以为下面的内容提供大内存分配:
·为共享服务器和oracle XA接口(在事务与多个数据库交互的地方使用UGA)
·用于并行执行语句的消息缓冲区
·用于恢复管理器(RMAN)I/O slaves 缓冲区
通过大池中分配会话内存,数据库可以避免在从共享池分配内存时发生的内存碎片。当数据库将大池内存分配到会话时,除非会话主动释放该内存,否则内存不能被释放。相反,数据库在共享池中以LRU方式管理内存,这意味着内存部分可以老化。
下图是大池的结构图:
大池与共享池中的预留空间不同,共享池使用与共享池中分配的其它内存相同的LRU列表。大池没有LRU列表。内存块分配并不能释放,直到它们被使用完。一旦内存块被释放,其它进程就可以使用它。
Java 池
Java池是用来存储在Java虚拟机(JVM)内所有特定于会话的Java代码和数据的内存区域。该内存包括在调用结束时迁移到Java会话空间的Java对象。
对于专用的服务器连接,Java池包含每个Java类的共享部分,包括方法和只读内存,如代码向量,而不是每个会话的Java状态。对于共享服务器,池包含每个类的共享部分和每个会话状态的一些UGA。每个UGA都在必要时增长和收缩,但是UGA的总大小必须适合于Java池空间。
Java Pool Advisor统计信息提供了有关用于Java的库缓存内存信息,并预测Java池大小的变化如何影响解析速率。当statistics_level设置为典型或更高时,Java Pool Advisor在内部打开,当advisor关闭时这些信息将被重置。
流池
流池存储缓存队列信息,并为oracle流捕获过程和应用程序提供内存。流池仅由oracle流使用。
除非特别地配置它,否则流池的大小从0开始。池大小按oracle流的要求动态增长。
混合SGA区域
固定的SGA是一个内部管理区域。
比如,固定SGA区包括:
·那些后台进程需要访问的关于数据库和实例的一般信息
·进程之间传递的信息,比如关于锁的信息
固定SGA大小是由oracle数据库设置的,不能手动更改。固定SGA大小可以通过释放空间而得到改变。
软件代码区概述
软件代码区域是存储正在运行或可以运行的代码的一部分内存。oracle数据库代码存储在一个通常比用户程序的位置更具有排他性和受保护的软件区域。
软件代码区通常都是静态的大小,只会在软件更新或重装的情况下改变大小。这些领域所需的大小因操作系统而异。
软件代码区是只读的,可以安装共享或非共享。一些数据库工具和实用工具,如oracle fORMs和SQL*PLUS,可以安装共享。在可能的情况下,共享数据库代码,这样所有用户都可以访问它,而不会在内存中有多个副本,从而让主要内存和性能的整体提高。如果在同一台计算机上运行数据库,数据库的多个实例可以使用相同的数据库代码区域。
安装软件共享的选项对于所有操作系统都是不可用的,例如,在运行windows操作系统的个人电脑上。
--结束END--
本文标题: oracle内存架构(三)
本文链接: https://lsjlt.com/news/36829.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0