Oracle 和 DB2,比较与兼容性/架构/DB2
用于存储有关 DB2 通用数据库 (DB2) 和数据库数据的信息的物理文件是在文件系统上使用 CREATE DATABASE 命令在目录中创建的。以下描述的是实际存储在磁盘上的结构。它们用于存储用户信息和管理数据库实例的操作。它们是日志文件、控制文件、锁定文件和配置文件等。DB2 如何将这些物理结构映射到 DBMS 使用的逻辑结构(如容器、页面和表空间)将在后面介绍。
这些文件可以存储在原始设备上,也可以存储在文件系统文件和目录中。在这个层次结构中,为每个实例创建一个子目录,以便在同一个目录中创建的不同实例中的数据库不会使用相同的路径。在这个目录中创建的第一个数据库名为 SQL00001,它包含与第一个数据库关联的所有数据库对象。
在每个实例子目录下面,创建另一个名为 NODE0000 的目录,用于标识逻辑分区数据库中的分区。在这个目录中创建的第一个数据库名为 SQL00001,它包含与第一个数据库关联的所有数据库对象。随后创建的数据库按顺序命名,如 SQL00002、SQL00003 等。
物理结构是
Directory identified in CREATE DATABASE | +→ Instance | +→ NODE0000 | +→ SQL00001 | +→ SQL00002
数据库目录包含以下文件和目录
- SQLDBCON – database configuration information - The SQLOGDIR directory – contains database log files | + --> SQLLOGCTL.LFH and SQLOGMIR.LFH – log control information files. These files contain information about the active logs and are used in database recovery - SQLINSLK – a lock files that ensures that each database is used by only one databasze instance - DB2RHIST.ASC – a housekeeping file that contains the following data backup
restore
Table loads
Table reorganizations
Tablespace alterations
- DB2RHIST.BAK – a backup of the DB2RHIST.ASC file - SQLSPCS.1 and SQLSPCS.2 – table space information, each file is duplicated as a backup - SQLBP.1 and SQLBP.2 – buffer pool information, each file is duplicated as a backup
DB2 在四个不同的块中管理内存。可以认为内存从上到下组织。为数据库实例分配了内存 - 数据库管理系统 (DBMS),它处理 DBMS 中的所有单个数据库以及所有实例级任务和活动。在其下方,为每个包含数据库缓冲池和恢复信息的单个数据库分配了内存。对于与数据库关联的每个应用程序集,都会有内存分配,并且在应用程序中,DB2 称为代理的东西就像做应用程序工作的小子例程或实用程序。因此,从上到下,我们有
• 数据库实例内存(每个 DBMS 实例一个)
• 数据库全局内存(每个数据库一个)
• 应用程序全局内存
• 代理私有内存(每个应用程序一个)
为每个 DBMS 实例分配的内存是数据库实例内存,它每个 DB2 实例分配一个,用于实例级任务,如监控、审计和节点间通信。它在 DBMS 启动时分配(db2start),并在停止时释放(db2stop)。
数据库实例内存中的内存池是
• 监控堆
• 审计缓冲区和
• FCM 缓冲区
运行状况监控器捕获有关数据库管理器、数据库、表空间和表空间容器的信息。它根据来自数据库系统监控器、操作系统和 DB2 本身的數據来评估实例的运行状况。监控堆将为每个指标最多保留十个历史记录,并且只能在数据库处于活动状态时评估数据库上的运行状况指标。
历史记录存储在
Directory specified in CREATE DATABASE | +→ Instance | +→ hmonCache directory.
历史记录在运行状况监控器停止时被清除。运行状况监控器在达到十条记录时也会修剪旧的历史记录。
DB2 中的审计功能监控对超出既定身份验证凭据、权限和特权的數據的访问。此功能会生成记录,这些记录保存在审计缓冲区中,然后保存在磁盘上的审计日志文件中。
审计日志 (db2audit.log) 和审计配置文件 (db2audit.cfg) 位于
Directory specified in CREATE DATABASE | +→ Instance | +→ security directory.
DB2 使用快速通信管理器 (FCM) 来控制数据库分区和代理之间信息流。FCM 所需的内存被分配为数据库实例的 FCM 缓冲区。
为数据库实例内存预留的内存大小在 instance_memory 参数中指定。默认值为 AUTOMATIC,DB2 将根据监控堆、审计缓冲区和 FCM 缓冲区的大小计算内存量。还会为溢出缓冲区分配额外的内存,以满足堆超出配置限制时的内存请求。
这样,可以看出 DB2 通过动态管理其组成部分来有效地处理数据库实例内存。
为每个数据库分配的内存是数据库全局内存,它每个数据库分配一个,用于备份和恢复、锁定和 SQL 执行。它在您启动或首次连接到数据库时分配,并在您停止或断开连接时释放。数据库启动时,DB2 会根据需要完全或部分分配内存池。
在数据库全局内存中,有多个内存池。这些内存池中大多数的大小由它们的配置设置预先确定,但是包缓存和目录缓存是动态的,因为您可以有任意数量的应用程序连接到数据库。包缓存用于缓存 SQL 查询的访问计划。目录缓存是 DB2 数据字典。此外,实用程序堆是动态分配的。它用于备份等实用程序,并且最初仅为此分配了 16 KB 内存。实用程序启动后,将分配实用程序堆的全部内存。锁定列表是保存有关数据库上持有的锁定的信息的缓冲区。它是在多用户并发访问中维护数据库一致性的重要组成部分。
您可以配置 DB2 根据其包含的内存池的大小计算数据库全局内存的大小。它还会为溢出缓冲区分配额外的内存,以处理内存需求峰值(例如,如果备份由于某种原因需要超过配置的内存)。
这样,可以看出 DB2 通过动态管理其组成部分来有效地处理数据库全局内存。
通常,数据库全局内存的最大组成部分是缓冲池。数据库必须至少有一个缓冲池,所有数据和索引都在其中处理。数据库可能有多个缓冲池,具体取决于工作负载和数据库页面大小。缓冲池的大小受可寻址内存架构的限制。如果数据库配置文件 SQLBP.1 和 SQLBP.2 中的缓冲池分配太大而无法放入可寻址内存空间,则数据库将无法启动。为了解决这个问题,在数据库启动时会分配四个小的附加缓冲池。它们分别为页面大小 4K、8K、16K 和 32K,这些缓冲池将用于启动 DB2(带错误),以便您可以更改主缓冲池的大小。此外,可以扩展主缓冲池以解决此问题。此扩展存储充当从主缓冲池中弹出页面的缓存。它们不会被写入磁盘,而是存储在扩展存储中,这将它们保留在主内存中并减少磁盘 I/O。存在权衡,因为主内存是有限的,扩展存储以牺牲其他内存池为代价分配。
排序堆阈值内存池用于排序,DB2 执行两种类型的排序 - 私有排序和共享排序。共享排序使用数据库共享内存池中的内存,私有排序在代理的私有内存中进行(稍后介绍)。
如果检索的行没有索引,或者优化器决定排序比索引扫描更有效,则执行排序。配置参数 SHEAPTRES 指定实例可以用于私有排序(代理私有内存)的内存量的软上限。DB2 通过在达到此限制时限制可用于其他排序的内存量来管理这些排序的内存。
如果使用并行处理或集中器,DB2 可能会选择共享排序而不是私有排序。在这种情况下,排序堆将在数据库全局内存中分配。用于共享排序的最大内存量由 SHEAPTHRES_SHR 数据库参数控制。这是一个针对整个数据库的硬性限制,用于共享排序的可用内存总量。当达到此限制时,请求的应用程序将收到错误,并且在内存使用量降至 SHEAPTHRES_SHR 限制以下之前,将不再允许任何共享排序内存请求。
DB2 应用程序全局内存
[edit | edit source]
在以下情况下会分配应用程序全局内存:
• 分区数据库
• 使用内部并行处理的非分区数据库
• 启用了连接集中器
在上述情况不成立的环境中(即非分区数据库),应用程序全局内存的使用最少。
分区。
到目前为止,我们一直在描述单片式架构,其中数据库中的所有用户数据都表示为一个单元 - 数据、索引、配置文件和事务日志都用于完整的数据集。分区是一种将整个数据集分解为离散单元的技术,所有单元都在单个数据库实例下运行,但每个单元都拥有自己的独立数据、索引、配置文件和事务日志集合。
这允许组织将大型数据集分散到多个不同的服务器上(或在一个大型服务器上创建多个独立运行的逻辑分区)。这样做有很多好处 - 可以对单个分区进行管理,而不会影响完整的数据集(例如,可以逐分区进行备份和恢复)。数据的分离意味着整个数据集不易受到停机的影响(不是所有数据都不可用,而只有一个分区不可用)。分区可以任意进行 - 按地理区域、日期范围、组织部门,应有尽有。这允许处理和 I/O 负载分散。总体优势包括灵活性、安全性、可扩展性和速度。DB2 数据库分区功能 (DPF) 的一个很好的特性是,无论您是否使用它,它都是相对透明的 - 按照 DB2 SQL 参考
"分区关系数据库是一个关系数据库,其数据跨多个分区管理 [..]. 数据跨分区的分离对大多数 SQL 语句的用户来说是透明的。"
这意味着将数据库进行分区以实现可扩展性或性能目的的决定不需要考虑重新设计现有设计。当然,这个选项不是免费的,但当决定变得更大或更快时,它就很好,因为这仅仅归结为硬件和许可证成本效益分析。
分区将在第 4 章中详细介绍。它在这里介绍是因为它与应用程序全局内存有关。提高分区效率的一种方法是,应用程序逻辑可以在应用程序级别(在代理私有内存中)本地化,或者在应用程序全局内存中的分区级别本地化 - 这样,针对特定分区的处理可以在应用程序级别在该分区内完成,但针对整个数据集的处理可以抽象到分区级别。这对应用程序全局内存有影响,其中一个影响是,需要为每个应用程序分配内存 - 应用程序控制堆,以及为所有应用程序分配内存 - 应用程序组共享堆。
应用程序组共享堆由代理用于在分区之间共享信息。它还用于存储有关临时表的信息,以及执行代理的 SQL 语句。从本质上讲,它是一个用于分区的内存池。
非分区数据库上的内部并行处理是指多个代理和子代理可以在同一时间为一个应用程序活动。这些代理在该实例中使用应用程序组共享堆进行应用程序级别的通信(而不是分区级别)。
连接集中器是一种连接池方式。每个到数据库的连接(来自应用程序和代理)都使用一部分内存(以维护连接状态等)。在拥有数千个连接的大型多用户数据库中,这会占用大量内存。问题是,这些连接中可能没有一个在执行有用的工作,它们可能处于等待状态 - 这是浪费的。集中器充当多路复用器,所有连接都进入集中器,它保留这些逻辑连接,然后将每个代理的资源请求多路复用到较少数量的实际数据库连接上。为了做到这一点,集中器需要存储有关连接的信息,它使用应用程序组共享堆来完成此操作。
DB2 代理私有内存
[edit | edit source]
代理为应用程序执行工作,它们用于以下内容:
• 生成查询计划
• 执行查询计划
• 处理游标
• 排序
• 收集统计信息
每个代理进程都需要内存来执行其功能,并且在将代理分配为连接请求或新 SQL 请求的结果时分配此内存。从图中可以看出,代理私有内存池是:
• 应用程序堆 - 用于在代表相同请求工作的代理之间共享信息(对于未使用内部并行处理的非分区数据库来说,这最少)。它还用于存储临时表的描述符信息。
• 排序堆 - 用于处理排序操作,包括排序、哈希连接和动态位图。
• 语句堆 - 用作 SQL 或 XQuery 编译器的工作空间,它为每个 SQL 或 XQuery 语句分配和释放。
• 统计信息堆 - 用于存储有关表、关联索引或统计视图的特征的统计信息,例如:
o number of records
o number of pages
o average record length
优化器使用这些统计信息来确定访问路径。
• 查询堆 - 用于将查询存储在代理的私有内存中。每个查询的信息是:
o the input and output SQL descriptor area
o the statement text
o the SQL communication area
o the package name, creator, section number, and consistency token.
• Java 解释器堆 - 由 Java 解释器用于服务 Java 存储过程和用户定义函数。
• 代理堆栈大小 - 代理堆栈是每个代理的虚拟内存,在 Windows 中,初始堆栈大小设置为防止堆栈溢出错误。
为了平衡内存限制与速度,您可以让代理在空闲时保留内存。这些空闲代理的内存分配会占用内存,因此您可以设置对任何时间点允许的空闲代理数量的限制。拥有空闲代理保留其内存的优势在于,当新的请求进来时,您不需要创建和销毁它们,而是调用空闲代理来处理该请求。
DB2 进程模型
[edit | edit source]
之前,我们描述了数据库数据是如何布局在物理磁盘上的,包括用户数据和 DBMS 运行所需的信息。接下来,我们描述了 DB2 在 RAM 中使用这些数据时使用的内存结构。内存中的结构不仅用于数据库数据,还用于数据库程序 - 以进程和线程形式实现的用户程序和 DB2 程序。上面的图是所有 DB2 数据库共有的进程和线程的代表性子集,并提供了对数据库如何运行的洞察。
DB2 系统控制器 - db2sysc - 是主要的 DB2 线程,它是您启动数据库时启动的。每个活动分区只有一个多线程 db2sysc,它会生成我们接下来要描述的所有其他线程 - 其中一些是明确命名的,例如 db2lock,而另一些则简单地标识为 EDU(引擎可调度单元)。所有进程和线程都由 db2sysc 生成(或调度),EDU 是一个统称,尽管语法上不正确。
数据库是这些服务器进程的集合。当它启动时,它正在执行诸如监视数据库运行状况之类的操作,但它基本上只是在运行,它不会执行任何有用的工作,直到客户端进程连接到它。在本例中,客户端进程是您的程序 - 您用于创建、管理和访问数据库中的数据的 SQL。
客户端程序可以在远程或与数据库服务器相同的机器上运行。它们通过侦听器连接到数据库,并为它们分配协调代理(由 db2sysc 启动的 db2agent)。如果客户端在与数据库实例相同的机器上本地运行,它将通过 db2ipccm 连接,否则它将通过特定于客户端通信方法的侦听器连接,例如,使用 TCP/IP 的客户端将连接到 db2tcpm 侦听器,使用 SNA / APPC 的客户端将使用 db2snacm。
与内存架构被分解为实例、数据库、应用程序和代理内存池一样,进程架构也将被分解为与实例、数据库、连接和请求进程相关的进程。
防火墙之外有一些进程,这些进程本身不属于数据服务器。这些是前面已经描述的用户进程(本地和远程),以及诸如以下进程:
• db2fmp - 栅栏模式进程,负责在防火墙之外执行栅栏存储过程和用户定义函数。db2fmp 始终是单独的进程,但根据它执行的例程类型,它可能是多线程的。
• db2vend - 为其他进程和线程执行供应商代码 (*nix 仅限)
实例级线程。
前面提到的系统控制器 db2sysc 必须存在,否则您的数据库无法正常工作。进程模型图中的其他实例级线程是:
• 侦听器线程 db2ippcm 和 db2tpcm 既是实例线程,也是连接线程,所有子代理线程(db2agent、db2agnta、db2agntp 和 db2agnsc)也是如此
• db2wdog - DB2 看门狗仅适用于 *nix 系统,因为 *nix 只能识别其父进程。每当启动一个新进程时,另一个仅限 *nix 的进程 - 全局守护进程服务 - db2gds - 会通知 db2wdog。如果任何进程收到异常信号,此信号将传递给 db2wdog,db2wdog 会通知所有其他实例进程。• db2acd - 自主计算守护进程运行运行状况监视器、维护实用程序和管理任务计划程序。
连接线程。
所有客户端连接都获得一个与之关联的协调代理 -db2agent-,无论它们是直接与代理通信,还是通过实例级侦听器线程(例如 db2ipccm 或 db2tcpm)通信。代理处理应用程序的所有数据库操作。如果您使用的是内部并行处理,db2agent 会将数据库请求分发到子代理 - db2agntp。代理可以连接到数据库、实例或客户端。代理池保存空闲代理(在之前的 DB2 内存模型中进行了描述)。
数据库线程。
以下是图 10 中标识的数据库级别线程的列表。这不是一个完整的列表,它用于识别与数据库操作(如日志记录和死锁检测)相关的具有 Oracle 和 DB2 公共性的主要线程。
• db2pfchr:缓冲池预取器从磁盘获取数据到内存。
• db2pclnr:缓冲池页面清理器从缓冲池中弹出页面。
• db2loggr:日志记录器处理事务处理和恢复的日志文件。
• db2loggw:日志写入器将日志记录写入日志文件。
• db2logts:表空间日志记录器收集有关修改表空间时哪些日志处于活动状态的信息。
• db2dlock:死锁检测器识别锁冲突。在分区数据库中,全局死锁进程 - db2glock - 协调每个分区上每个 db2dlock 进程的信息。