【发布时间】:2020-11-14 12:08:41
【问题描述】:
有一段时间我一直在努力抽出时间来写这个问题并尽可能地解释这个问题,所以请提前原谅我的长文。
我的环境:
- Oracle Database 12.2 在 Red Hat 7(R.A.C 2 个节点)上运行 - 每个节点 16CPU 和 64GB RAM。
- Parallel Force Local 设置为 TRUE 以强制并行服务器进程只能在启动 SQL 语句的同一节点上执行。
我们有一个非常大的数据库,其中包含许多服务于多个应用程序的模式。大多数应用程序实际上是 PL/SQL 中的批处理引擎,处理亿万条记录,因此出于性能原因,大多数大表都配置了 PARALLEL DEGREE DEFAULT。表已分区并具有高级压缩功能。
除了一些用于开发目的的报告 BI 工具外,许多最终用户可以通过 SQL Developer 访问系统(仅在读取模式下)以进行 QA 检查。我从不喜欢,但有时你必须接受现状。
为了控制一些事情,我设计了一个特定的登录触发器,它不仅涵盖审核功能,还涵盖传入会话的某些方面:
- 使用 SQL Developer 访问的最终用户可能只打开 2 个会话。
- 使用 SQL Developer 访问的最终用户运行立即执行 ALTER SESSION DISABLE PARALLEL QUERY。不幸的是,我知道有些用户正在自己激活它。 ALTER SESSION ENABLE/DISABLE PARALLEL QUERY 由 CREATE SESSION 权限或 CONNECT 角色继承,因此我对此无能为力。
- 使用 SQL Developer 访问的最终用户被分配到特定配置文件,但在 CPU、磁盘读取等方面受到限制。
登录触发器根据一组附加规则允许或不允许访问,但对于问题而言它们无关紧要。
让我们看看在 SQL Developer 上运行的查询如何处理启用了 PARALLEL 的表:
场景
我有一个表,其中包含按不同分区划分的 80 亿条记录。用户使用 sql developer 登录并运行此查询
SELECT COUNT(*) FROM MY_SCHEMA.MY_TABLE PARTITION ( MY_PARTITION ) ;
183.940.801 rows
由于表没有索引,CBO 在 PARALLEL 中运行 TABLE FULL SCAN,使用尽可能多的从属服务器。完成需要 6 秒。到目前为止,没有任何问题。
同时我正在监视会话(当查询运行时,您可以看到所有活动的会话)
INSTANCE SID USERNAME PROGRAM SQL_ID STATUS
---------- ------- -------------------- -------------------------------------------------- -------------------- --------
2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) dtf8d89xg7muq ACTIVE
2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) dtf8d89xg7muq ACTIVE
2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) dtf8d89xg7muq ACTIVE
2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) dtf8d89xg7muq ACTIVE
2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) dtf8d89xg7muq ACTIVE
2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) dtf8d89xg7muq ACTIVE
2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) dtf8d89xg7muq ACTIVE
2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) dtf8d89xg7muq ACTIVE
2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) dtf8d89xg7muq ACTIVE
2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) dtf8d89xg7muq ACTIVE
2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) dtf8d89xg7muq ACTIVE
2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) dtf8d89xg7muq ACTIVE
2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) dtf8d89xg7muq ACTIVE
2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) dtf8d89xg7muq ACTIVE
2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) dtf8d89xg7muq ACTIVE
2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) dtf8d89xg7muq ACTIVE
2 1015 FDM_ADM_GRID SQL Developer dtf8d89xg7muq ACTIVE
2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) dtf8d89xg7muq ACTIVE
2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) dtf8d89xg7muq ACTIVE
2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) dtf8d89xg7muq ACTIVE
2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) dtf8d89xg7muq ACTIVE
2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) dtf8d89xg7muq ACTIVE
2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) dtf8d89xg7muq ACTIVE
2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) dtf8d89xg7muq ACTIVE
2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) dtf8d89xg7muq ACTIVE
2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) dtf8d89xg7muq ACTIVE
2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) dtf8d89xg7muq ACTIVE
2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) dtf8d89xg7muq ACTIVE
2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) dtf8d89xg7muq ACTIVE
2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) dtf8d89xg7muq ACTIVE
2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) dtf8d89xg7muq ACTIVE
2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) dtf8d89xg7muq ACTIVE
2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) dtf8d89xg7muq ACTIVE
查询完成后
SQL> r
1* select inst_id as instance , sid, username, program, sql_id, status from gv$session where username = 'FDM_ADM_GRID'
INSTANCE SID USERNAME PROGRAM SQL_ID STATUS
---------- ------- -------------------- -------------------------------------------------- -------------------- --------
2 1015 FDM_ADM_GRID SQL Developer INACTIVE
到目前为止一切顺利。现在让我们在 SQL Developer 中运行另一个查询
SELECT * FROM MY_SCHEMA.MY_TABLE partition ( MY_PARTITION ) fetch first 1000 rows only;
查询几乎立即检索前 1000 行。但是让我们看看数据库的区别
什么时候运行
SQL> r
1* select inst_id as instance , sid, username, program, sql_id, status from gv$session where username = 'FDM_ADM_GRID'
INSTANCE SID USERNAME PROGRAM SQL_ID STATUS
---------- ------- -------------------- -------------------------------------------------- -------------------- --------
2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) 9jyvj64ag15mv ACTIVE
2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) 9jyvj64ag15mv ACTIVE
2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) 9jyvj64ag15mv ACTIVE
2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) 9jyvj64ag15mv ACTIVE
2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) 9jyvj64ag15mv ACTIVE
2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) 9jyvj64ag15mv ACTIVE
2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) 9jyvj64ag15mv ACTIVE
2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) 9jyvj64ag15mv ACTIVE
2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) 9jyvj64ag15mv ACTIVE
2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) 9jyvj64ag15mv ACTIVE
2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) 9jyvj64ag15mv ACTIVE
2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) 9jyvj64ag15mv ACTIVE
2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) 9jyvj64ag15mv ACTIVE
2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) 9jyvj64ag15mv ACTIVE
2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) 9jyvj64ag15mv ACTIVE
2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) 9jyvj64ag15mv ACTIVE
2 1015 FDM_ADM_GRID SQL Developer ACTIVE
2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) 9jyvj64ag15mv ACTIVE
2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) 9jyvj64ag15mv ACTIVE
2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) 9jyvj64ag15mv ACTIVE
2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) 9jyvj64ag15mv ACTIVE
2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) 9jyvj64ag15mv ACTIVE
2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) 9jyvj64ag15mv ACTIVE
2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) 9jyvj64ag15mv ACTIVE
2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) 9jyvj64ag15mv ACTIVE
2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) 9jyvj64ag15mv ACTIVE
2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) 9jyvj64ag15mv ACTIVE
2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) 9jyvj64ag15mv ACTIVE
2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) 9jyvj64ag15mv ACTIVE
2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) 9jyvj64ag15mv ACTIVE
2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) 9jyvj64ag15mv ACTIVE
2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) 9jyvj64ag15mv ACTIVE
2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) 9jyvj64ag15mv ACTIVE
查询完成后,我再次检查,但是现在所有从属设备仍然存在并且处于活动状态。我会认为,一旦 QC 完成并标记为非活动状态,Oracle 就会关闭所有从属进程。但它没有
`INSTANCE SID USERNAME PROGRAM` SQL_ID STATUS
---------- ------- -------------------- -------------------------------------------------- -------------------- --------
2 6 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00N) 9jyvj64ag15mv ACTIVE
2 128 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P007) 9jyvj64ag15mv ACTIVE
2 140 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P004) 9jyvj64ag15mv ACTIVE
2 256 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00D) 9jyvj64ag15mv ACTIVE
2 284 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00O) 9jyvj64ag15mv ACTIVE
2 388 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00P) 9jyvj64ag15mv ACTIVE
2 400 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00C) 9jyvj64ag15mv ACTIVE
2 510 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00E) 9jyvj64ag15mv ACTIVE
2 621 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00F) 9jyvj64ag15mv ACTIVE
2 641 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00Q) 9jyvj64ag15mv ACTIVE
2 739 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P008) 9jyvj64ag15mv ACTIVE
2 771 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P005) 9jyvj64ag15mv ACTIVE
2 888 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00G) 9jyvj64ag15mv ACTIVE
2 893 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00R) 9jyvj64ag15mv ACTIVE
2 996 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00H) 9jyvj64ag15mv ACTIVE
2 1010 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00S) 9jyvj64ag15mv ACTIVE
2 1015 FDM_ADM_GRID SQL Developer INACTIVE
2 1109 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00I) 9jyvj64ag15mv ACTIVE
2 1116 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00T) 9jyvj64ag15mv ACTIVE
2 1230 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00J) 9jyvj64ag15mv ACTIVE
2 1254 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00U) 9jyvj64ag15mv ACTIVE
2 1352 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P006) 9jyvj64ag15mv ACTIVE
2 1376 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P009) 9jyvj64ag15mv ACTIVE
2 1383 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P001) 9jyvj64ag15mv ACTIVE
2 1477 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P000) 9jyvj64ag15mv ACTIVE
2 1488 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00V) 9jyvj64ag15mv ACTIVE
2 1506 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00K) 9jyvj64ag15mv ACTIVE
2 1604 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P002) 9jyvj64ag15mv ACTIVE
2 1617 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00A) 9jyvj64ag15mv ACTIVE
2 1620 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00L) 9jyvj64ag15mv ACTIVE
2 1740 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P003) 9jyvj64ag15mv ACTIVE
2 1743 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00M) 9jyvj64ag15mv ACTIVE
2 1851 FDM_ADM_GRID oracle@scglvdoraci0010.scger.pre.corp (P00B) 9jyvj64ag15mv ACTIVE
只要会话保持打开状态,QC 将保持非活动状态,而从属服务器处于活动状态,因此尽管它们不做任何事情,但它们仍算作并行服务器。会话关闭或用户运行另一个查询让我注意到并行使用的变化。但是如果用户去喝咖啡,或者去发射或者正在做其他事情,就不会有任何东西。 有 100 多个用户同时工作,您可能会想象到头痛。我不得不设计一些解决方法:
- 我必须在触发器内创建一个新控件来识别 QC 与处于 ACTIVE 状态的从属设备的非活动时间,以确定用户已经打开了多少会话。
- 在 1 小时的窗口时间后,我必须创建一个清理进程来断开处于此状态的会话
- 我不能在配置文件中使用限制会话,因为它们在 QC 或 SLAVES 之间没有区别。
- 无论我配置了多少东西,有时我会用完并行进程,并且如果在工作时间执行批处理(这种情况经常发生),我有时会因为从站的数量而面临这些重要进程缺乏并行可用性的问题被非活动会话占用。
我的问题如下:
- 当 QC 已经完成时,为什么从站仍然处于 ACTIVE 状态?不是应该在 QC 交付结果后立即终止从站吗?
- 为什么在 SQLPLUS 和 Java 池解决方案(作为 SAP 业务对象)中运行非常相似的查询时,不会发生这种行为?
- 有没有办法从最终用户禁用并行功能,无论他们尝试通过 ENABLE PARALLEL QUERY 还是通过 HINTS 来激活它们?
我为这个冗长的问题道歉,但我不想留下任何东西。 我非常感谢您对此的任何见解。
谢谢大家。
【问题讨论】:
-
你看过资源管理器吗?它有一些并行执行限制,您可以通过将某些用户放在不同的消费者组中来为它们设置这些限制。我在使用 DEFAULT 度数的表时遇到了问题。像 8 这样的固定数字似乎对我来说效果更好。你有 2 个节点和 16 个核心,所以我认为 DEFAULT=32 这似乎过多,但你的帖子显示 16 级查询,所以我不知道为什么会这样。我以为 DEFAULT=nodes*cores。
-
我试图为资源管理器构建一个测试用例,但是我遇到了很多问题,以至于我花费的时间不值得。我虽然想修复学位,但它产生的问题比解决默认产生的问题要多。此外,我在批处理中有很多次,以至于整个服务器都被一个查询占用了
-
可能您的默认度数为 16,因为您将 PFL 设置为 True,因此它仅将其视为 1 个节点。 16级是合理的。 SQL Developer 会话一直保留在 PQ 从站上,这真是令人遗憾。糟糕!
标签: oracle oracle-rac parallel-query