热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle数据库实例之内存架构(一)

Oracle数据库实例之内存架构(一)Oracle数据库内存结构基本内存结构Oracle内存管理用户全局区:UGA程序全局区:

Oracle数据库实例之内存架构(一)

  • Oracle数据库内存结构
    • 基本内存结构
    • Oracle内存管理
  • 用户全局区:UGA
  • 程序全局区:PGA
    • PGA的内容
    • 专用和共享服务器模式下的PGA
  • 系统全局区:SGA

本文讨论的内容涉及的数据库版本为 12.2。

Oracle数据库内存结构

数据库实例启动后,Oracle数据库会为其分配一块内存区域并启动相关后台进程。该内存区域存储了以下信息:

  • 程序代码;
  • 已连接会话(session)的信息,即使该session当前并未处于活跃状态;
  • 程序执行过程中所需的信息,比如查询(query)的当前状态;
  • 进程之间共享和通信的(lock data)相关的信息;
  • 缓存数据(cached data),比如数据块、重做记录等从磁盘中读取的信息。

基本内存结构

Oracle数据库中的基本内存结构包括:

  • 系统全局区(System global area, SGA)
    SGA是一组共享内存,其中包含了数据库实例的数据和控制信息。所有的服务器和后台进程都会共享SGA。SGA中的数据包括缓存数据块、共享SQL区等。

  • 程序全局区(Program global area, PGA)
    PGA是非共享的内存区域,其中包含了一个Oracle进程独占使用的数据和控制信息。当有一个Oracle进程启动时,Oracle数据库就会创建一个PGA。对于每个服务器进程(server process)和后台进程,都会存在一个对应的PGA。所有单独的PGA的集合构成了总的实例PGA(instance PGA)。数据库的初始化参数(在参数文件 spfile 中)决定了PGA实例的大小,而不是每个单独的PGA。

  • 用户全局区(User global area, UGA)
    UGA是与一个用户会话(user session)相关的内存。

  • 软件代码区(Software code areas)
    软件代码区是用于存储正在运行或者可以运行的代码。Oracle数据库代码存储在与用户程序不同的地方。

下图展示了以上内存结构之间的关系。

图1 Oracle数据库内存结构
在这里插入图片描述


Oracle内存管理

内存管理(memory management)涉及到在对数据库的需求发生变化时,维护Oracle实例内存结构的最佳大小。Oracle数据库基于与内存相关的初始化参数配置来管理内存。内存管理的基本可选项包括以下内容:

  • 自动内存管理(automatic memory management)
    需要明确设置数据库实例内存的目标大小。数据库实例会自动调整到目标内存大小,并按需在SGA和实例PGA之间分配内存。

  • 自动共享内存管理(automatic shared memory management)
    该模式为部分自动内存管理。你需要为SGA设定目标大小,然后为实例PGA设定总的目标大小,但是你也可以单独管理PGA。

  • 手动内存管理(manual memory management)
    该模式下,你需要设定许多初始化参数来单独管理SGA和实例PGA。

如果你用数据库配置助手(Database Configuration Assistant, DBCA)来创建数据库,并选择了基本的安装选项,那么默认的内存管理方式为自动内存管理。

用户全局区:UGA

UGA是一块为会话变量(session variables)分配的内存,比如登录信息等其他数据库会话需要的信息。本质上,UGA存储了session的状态。

图2 UGA结构
在这里插入图片描述

如果一个会话向内存中载入了PL/SQL包(PL/SQL package),那么UGA中就包含了包的状态,即某个时刻该包里所有变量存储的的一组值。当该包的一个子程序修改了变量的值,包的状态也会改变。包的变量默认是唯一的,且在会话的生存时间内存在。

UGA中还存储了OLAP页池(OLAP page pool)。这个页池会管理OLAP数据页(数据块)。该页池在OLAP会话启动时被分配,在会话结束时被释放。OLAP会话会在用户查询维度对象(比如数据立方体 cube)时自动打开。

UGA必须在会话生存时间内可用。因此,使用共享服务器(shared server)连接时,UGA不能存储在PGA中。因为PGA只与单个进程相关。此时,UGA存储在SGA中,使得任意一个共享服务器进程都能访问它。相反地,当使用专用服务器(dedicated server)连接时,UGA就存储在PGA中。

程序全局区:PGA

PGA是针对系统中一个非共享的进程(process)或线程(thread)的内存,不会在SGA中分配。PGA是存储了一个专用或共享服务器进程所需的会话变量的堆内存(memory heap)。服务器进程分配它在PGA中所需的内存结构。

下图展示了一个实例PGA。你可以通过初始化参数来设置实例PGA的最大目标大小。组成实例PGA的所有单个的PGA会按需自动增长到该目标值。

图3 PGA实例结构
在这里插入图片描述


PGA的内容

PGA被划分为几个不同的区域。下图展示了一个专用服务器会话对应的PGA内容。

图4 PGA结构
在这里插入图片描述

第一部分:私有SQL区
私有SQL区(private SQL area)存有经过语法分析的SQL语句(parsed SQL statement)的信息、以及其他针对会话的信息。当服务器进程执行SQL或PL/SQL代码时,该进程会使用私有SQL区来存储绑定变量(bind variable)的值、查询执行状态、以及查询执行工作区的信息。

切忌不要混淆私有SQL区(在PGA中)和共享SQL区(在SGA中,用于存储执行计划)。同一个或者不同的会话中的多个私有SQL区可以指向SGA中的一个执行计划。但是这些私有SQL区彼此之间并不共享,其中包含的值和数据也可能不一样。

游标(cursor)是一个具体的私有SQL区的名称或者句柄(handle)。可以把游标认为是客户端的一个指针和服务器端的一个状态。考虑到二者联系紧密,有时候游标和私有SQL区这两个名词会互换着使用。

图5 游标
在这里插入图片描述

私有SQL区可以分为以下两个部分:

  • 运行时区(run-time area)
    运行时区包含了查询的执行状态信息。比如,运行时区会追踪在全表扫描(full table scan)中截至到当前已获取的行的数目。Oracle数据库在执行请求的第一步就会创建运行时区。对于DML操作而言,运行时区会在SQL语句关闭时释放。

  • 持久区(persistent area)
    持久区包含绑定变量的值。绑定变量的值会在执行SQL语句时传递给处于运行时的SQL语句。只有在游标关闭时,持久区才会被释放。

客户端进程负责管理私有SQL区。私有SQL区的分配和回收很大程度上取决于应用,尽管一个客户端进程能够分配的私有SQL区的数量会受到初始化参数 OPEN_CURSORS 的限制。通常来说,应用应该关闭所有不再使用的游标,以释放持久区来最小化应用用户所需的内存。

第二部分:SQL工作区
工作区(work area)是用于内存密集型操作而分配的一块私有PGA内存。例如,一个排序运算子使用排序区(sort area)来给行排序。一个哈希连接运算子(hash join operator)使用一块哈希区来创建哈希表。位图合并(bitmap merge)则使用位图合并区来合并多次位图索引扫描获取的数据。

下面展示了两个表 employeesdepartments 的连接操作及其对应的查询计划。运行时区负责跟踪全表扫描的过程。当前会话执行一个哈希连接操作来匹配两个表的行。ORDER BY 排序则发生在排序区。

SQL> SELECT * 2 FROM employees e JOIN departments d 3 ON e.department_id=d.department_id 4 ORDER BY last_name;
.
.
.
--------------------------------------------------------------------------------
| Id| Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 106 | 9328 | 7 (29)| 00:00:01 |
| 1 | SORT ORDER BY | | 106 | 9328 | 7 (29)| 00:00:01 |
|*2 | HASH JOIN | | 106 | 9328 | 6 (17)| 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPARTMENTS | 27 | 540 | 2 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| EMPLOYEES | 107 | 7276 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------

如果运算子处理的数据的量超过了工作区的容量,Oracle数据库就会把输入数据分割成更小的部分。这样数据库就能在内存中先处理一部分数据,而把剩余的部分放在临时的磁盘空间中留待之后处理。

当自动PGA内存管理模式开启时,数据库会自动地调整工作区的大小。当然你也可以手动控制调整工作区的大小。通常来说,更大的工作区能够显著提升运算子的性能,同时也会消耗更多的内存。

专用和共享服务器模式下的PGA

PGA的内存分配取决于数据库使用的是专用的还是共享的服务器连接。

内存区专用服务器共享服务器
会话内存是否共享私有共享
持久区的位置PGASGA
DML和DDL语句的运行时区的位置PGAPGA

系统全局区:SGA

SGA是一块可读写内存区域,与Oracle后台进程(background processes)一起构成了数据库实例。所有代表用户执行的服务器进程都能读取实例SGA里的信息。有一些进程能在数据库运行时写入SGA。需要注意的是,服务器和后台进程本身并不在SGA中,而是存在于独立的内存空间中。

每个数据库实例都有自己的SGA。Oracle数据库会在实例启动时自动为SGA分配内存,并在实例关闭时回收内存。正如图1,SGA由多个为了满足特定内存分配需求的内存池组成。除了重做日志缓存(redo log buffer)以外,所有其他的内存池都按连续内存单位分配和回收内存空间。这个连续内存单位称之为粒(granule),其大小与平台有关且取决于总的SGA大小。

查询 V$SGASTAT 视图可以看到SGA各部分的信息。其中包括数据库缓存、IM区、重做日志缓存、共享池、Large池、Java池、Streams池、固定SGA等。

SGA更详细的内容请参考:Oracle数据库实例之内存架构(二)。

References
[1] https://docs.oracle.com/en/database/oracle/oracle-database/12.2/cncpt/memory-architecture.html#GUID-0788EAEE-0E93-497B-9ACA-401EC0F7BCA1


推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • 本文介绍了将mysql从5.6.15升级到5.7.15的详细步骤,包括关闭访问、备份旧库、备份权限、配置文件备份、关闭旧数据库、安装二进制、替换配置文件以及启动新数据库等操作。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了如何使用Power Design(PD)和SQL Server进行数据库反向工程的方法。通过创建数据源、选择要反向工程的数据表,PD可以生成物理模型,进而生成所需的概念模型。该方法适用于SQL Server数据库,对于其他数据库是否适用尚不确定。详细步骤和操作说明可参考本文内容。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文讨论了在使用sp_msforeachdb执行动态SQL命令时,当发生错误时如何捕获数据库名称。提供了两种解决方案,并介绍了如何正确使用'?'来显示数据库名称。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
author-avatar
手机用户2502859707
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有