今天接到用戶反映,執行一個查詢select * from xxx,就會掛起,後端報警文件在報大池無法分配的問題,具體如下:
Tue Oct 11 15:26:06 2016
Errors in file c:\app\administrator\diag\rdbms\cdal\cdal\trace\cdal_p040_4128.trc (incident=113581):
ORA-04031: 無法分配 268512 字節的共享內存 ("large pool","unknown object","large pool","PX msg pool")
可以看出以上是因爲並行查詢導致了大池不足造成。
可先了解下 large pool:
大池是SGA中的一塊可選內存池,大池主要提供了大內存段,大池最大大小爲4G。根據需要時配置,主要用到大池的情況:
1. 用於共享服務(Shared Server MTS方式中)的會話內存和Oracle分佈式事務處理的Oracle XA接口
2. 使用並行查詢(Parallel Query Option PQO)時
3. I/O服務器進程用的內存(緩衝)
4. Oracle備份和恢復操作(啓用了RMAN時)
大池沒有LRU列表。這和共享池中的保留空間不同,保留空間和共享池中其他分配的內存使用同樣的LRU列表。
大塊內存從不會換出大池中,內存必須是顯式的被每個會話分配並釋放。
解決過程:1.檢查是否開啓了並行.
select * from dba_tables where degree<>1;
select * from dba_indexes where degree<>1;
2.發現是表開啓了並行,因此可關閉並行:
ALTER TABLE XX.XXX NOPARALLEL;
3.如果large pool大小不足,可根據實際需求調整大小:
ALTER SYSTEM SET LARGE_POOL_SIZE=xxM scope=spfile;
後通過檢查,該語句執行,執行計劃一直走並行:
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2873591275
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 2 (0)| 00:00:01
| 1 | PX COORDINATOR | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 1 | 12 | 2 (0)| 00:00:01
| 3 | PX BLOCK ITERATOR | | 1 | 12 | 2 (0)| 00:00:01
| 4 | TABLE ACCESS FULL| xxx | 1 | 12 | 2 (0)| 00:00:01
--------------------------------------------------------------------------------
Note
-----
- Degree of Parallelism is 2 because of table property
15 rows selected
SQL> select table_name,degree from user_tables where table_name='xxx';
TABLE_NAME DEGREE
--------------- --------------------
xxx 2
去掉該表的並行度,後,再去執行,之後就不走並行了.
alter table xxx noparallel;
後話:
總覺得很蹊蹺,內存怎麼會不夠呢,物理機器有128g內存,檢查數據庫發現,只分配了800m給memory_target,再一檢查,操作系統是32位,
問題已經很清楚了.根本解決辦法,就是升級到64位.