我如何解决 Amazon RDS for Oracle 数据库实例的 ORA-00018 或 ORA-00020 错误?

2 分钟阅读
0

我正在尝试以主用户或 DBA 用户的身份连接适用于 Oracle 数据库实例的 Amazon Relational Database Service (Amazon RDS)。但我收到以下错误之一:

ORA-00018 超出最大会话 ORA-00020 超出最大流程

如何解决这些错误?

简短描述

这些错误可以由计划的扩展练习或导致大量数据库连接的计划外事件引起。在这些情况下,很多客户端会话针对数据库实例而启动,并且达到了以下数据库限制之一:

  • PROCESSES – 允许的用户进程最大数量。
  • SESSIONS – 允许的用户会话最大数量。

如果由于计划的扩展练习而达到最大连接数,则增加 SESSIONS 或 PROCESSES,或同时增加两者。这可以适应您的应用程序的新规模。由于这两个参数不是动态的,因此,请修改参数重启实例

如果由于意外事件而达到最大连接数,请确定事件的原因并执行适当的操作。

例如,当响应时间由于锁定或块争用而增加时,应用程序可能会使数据库不堪重负。在这种情况下,增加 SESSIONS 或 PROCESSES 只会在再次达到极限之前增加连接数量。这可能会加剧争用造成的问题。这反过来可能会阻止 Amazon RDS 监控系统登录,执行运行状况检查,或采取重启之类的纠正错误。

解决方法

Oracle 用户 PROFILE

导致 ORA-18 和 ORA-20 的最常见原因之一是大量空闲连接。空闲连接会保留在数据库中,而不会被应用程序或数据库管理员正确关闭。IDLE 的增加可能导致数据库达到 SESSIONS/PROCESS 参数的最大限制。因此,不允许建立新的连接。最佳做法是使用有限的 IDLE_TIME 值为应用程序连接设置配置文件。

在 Oracle 数据库中,每个用户都分配给一个 PROFILE。Oracle PROFILE 分配给附加到此 PROFILE 的每个用户的一组资源。其中一项资源是 IDLE_TIME。IDLE_TIME 以分钟为单位指定数据库终止查询之前会话期间允许的连续不活动量。长时间运行的查询和其他操作不受此限制的约束。

此示例说明如何创建最大 IDLE_TIME 为 30 分钟的配置文件并将其分配给应用程序用户。任何超过 30 分钟的 IDLE 连接都会被数据库自动终止:

使用有限的 IDLE_TIME 参数创建 PROFILE:

SQL> select count(*) from v$session where type= 'BACKGROUND';

将此 PROFILE 分配给特定用户:

  SQL> ALTER USER <username> PROFILE <profile_name>;

扩展 RDS 实例大小

由于来自应用程序用户的传入工作负载增加,可能会达到最大会话/进程数。默认情况下,在 RDS for Oracle 中,两个参数限制均基于预定义的公式计算,该公式取决于数据库实例类内存。在这种情况下,手动修改 SESSIONS/PROCESS 参数不是最佳做法。相反,应根据工作负载纵向扩展实例。

PROCESSES/SESSIONS 参数的 RDS 默认设置是使用以下公式计算的:

  • PROCESSES= LEAST({DBInstanceClassMemory/9868951}, 20000)
  • SESSIONS = Oracle Default = (1.5 * PROCESSES) + 22

手动设置超出默认限制的 PROCESSES 或 SESSIONS 参数可能会导致内存消耗增加。因此,数据库可能会由于内存不足问题而崩溃。此外,手动设置 PROCESSES 或 SESSIONS 可能会在扩大/缩小实例时导致配置不匹配。发生这种情况是因为 PROCESSIONS 和 SESSIONS 参数不再依赖于分配的实例内存。

LICENSE_MAX_SESSIONS

LICENSE_MAX_SESSIONS 参数用于指定允许的并发用户会话最大数。这不适用于 Oracle 后台进程或具有 RESTRICTED SESSION 权限的用户,包括具有 DBA 角色的用户。将 LICENSE_MAX_SESSIONS 设置为低于 SESSIONS 和 PROCESSES 的值。这会导致客户端连接出现 ORA-00019 错误,而不是 ORA-18 或 ORA-20 错误。ORA-00019 错误不适用于具有 RESTRICTED SESSION 权限的用户。因此,主用户和 RDSADMIN 用户能够登录到数据库实例并执行管理故障排除和纠正措施。此外,Amazon RDS 监控可以通过使用 RDSADMIN 执行运行状况检查来继续连接到数据库。

注意:LICENSE_MAX_SESSIONS 最初旨在根据并发会话的数量限制使用量。Oracle 不再基于并发会话的数量提供许可,LICENSE_MAX_SESSIONS 初始化参数被弃用。然而,如果您使用最高为 19c 的 Oracle 版本,您仍可以使用该参数。此外,不应向应用程序用户授予 DBA 角色或 RESTRICTED SESSION 权限。有关更多信息,请参阅适用于 LICENSE_MAX_SESSIONS 的 Oracle 文档。

LICENSE_MAX_SESSIONS 是一个动态参数,因此,无需重新启动数据库实例即可设置该参数。有关更多信息,请参阅使用参数组

LICENSE_MAX_SESSIONS 参数可以设置为公式,类似于 PROCESS 参数。最佳做法是将 LICENSE_MAX_SESSIONS 参数设置为基于公式而不是静态值。这有助于避免在扩大/缩小实例大小时出现配置错误。例如:

  • 要将其设置为与 PROCESSES 参数相同: LICENSE_MAX_SESSIONS= LEAST({DBInstanceClassMemory/9868951}, 20000)
  • 要将其设置为 PROCESSES 参数的 4/5: LICENSE_MAX_SESSIONS= LEAST({DBInstanceClassMemory/12336188}, 20000)

使用 DEDICATED 会话

如果您使用 DEDICATED 会话,您的客户端连接可能会超出 PROCESSES 参数的限制 (ORA-20)。如果您的客户端连接数超出限制,请将 LICENSE_MAX_SESSIONS 的值设置为小于 PROCESSES 的值:

  • LICENSE_MAX_SESSIONS = 仅最大客户端连接数。
  • PROCESSES = LICENSE_MAX_SESSIONS + 后台进程总数,包括并行查询、数据库管理员用户(包括主用户)和缓冲区。缓冲区允许稍后可能发生的意外后台进程。要查看您现在拥有的后台进程数,请运行一个类似于以下内容的查询:
SQL> select count(*) from v$session where type= 'BACKGROUND';

**注意:**SESSIONS(默认值为 (1.5 * PROCESSES) + 22)应已足够。有关更多信息,请参阅适用于会话的 Oracle 文档。

要手动连接到您的实例以验证 SESSIONS,请运行与以下内容类似的命令:

SQL> select name, value from v$parameter where upper(name) in ('SESSIONS','PROCESSES','LICENSE_MAX_SESSIONS');
NAME   VALUE
------------------------------ ------------------------------
processes   84
sessions   148
license_max_sessions   0

使用 SHARED 会话

如果您使用 SHARED 会话,您的客户端连接可能会超出 SESSIONS 参数的限制 (ORA-0018)。如果您的客户端连接数超出限制,请将 PROCESSES 参数设置为更大的值。

  • LICENSE_MAX_SESSIONS = 仅最大客户端连接数。
  • PROCESSES = 后台进程总数,包括并行查询、数据库管理员用户(包括主用户)和缓冲区。请确保包含 SHARED_SERVERS 和 DISPATCHERS 的设置与后台进程数。
  • SESSIONS = (1.5 * PROCESSES) + 22

如果您使用 SHARED 服务器并收到最大进程数 (ORA-20) 错误而非最大会话数 (ORA-18) 错误,则您的调度程序可能已不堪重负。在调度程序不堪重负时,连接将被迫作为 DEDICATED 进入。增加 DISPATCHERS 的数量以允许更多会话连接共享。也可能需要增大 SHARED_SERVERS 参数。

要检查您使用的是共享服务器还是专用服务器,请运行如下命令:

SQL> select decode(server, 'NONE', 'SHARED', server) as SERVER, count(*)
from v$session group by decode(server, 'NONE', 'SHARED',server)

相关信息

使用 Oracle 的最佳实践

AWS 官方
AWS 官方已更新 1 年前