標籤

4GL (1) 人才發展 (10) 人物 (3) 太陽能 (4) 心理 (3) 心靈 (10) 文學 (31) 生活常識 (14) 光學 (1) 名句 (10) 即時通訊軟體 (2) 奇狐 (2) 音樂 (2) 產業 (5) 郭語錄 (3) 無聊 (3) 統計 (4) 新聞 (1) 經濟學 (1) 經營管理 (42) 解析度 (1) 遊戲 (5) 電學 (1) 網管 (10) 廣告 (1) 數學 (1) 機率 (1) 雜趣 (1) 證券 (4) 證券期貨 (1) ABAP (15) AD (1) agentflow (4) AJAX (1) Android (1) AnyChart (1) Apache (14) BASIS (4) BDL (1) C# (1) Church (1) CIE (1) CO (38) Converter (1) cron (1) CSS (23) DMS (1) DVD (1) Eclipse (1) English (1) excel (5) Exchange (4) Failover (1) FI (57) File Transfer (1) Firefox (2) FM (2) fourjs (1) gladiatus (1) google (1) Google Maps API (2) grep (1) Grub (1) HR (2) html (23) HTS (8) IE (1) IE 8 (1) IIS (1) IMAP (3) Internet Explorer (1) java (3) JavaScript (22) jQuery (6) JSON (1) K3b (1) LED (3) Linux (112) Linux Mint (4) Load Balance (1) Microsoft (2) MIS (2) MM (51) MSSQL (1) MySQL (27) Network (1) NFS (1) Office (1) Oracle (125) Outlook (3) PDF (6) Perl (59) PHP (33) PL/SQL (1) PL/SQL Developer (1) PM (3) Postfix (2) postfwd (1) PostgreSQL (1) PP (50) python (1) QM (1) Red Hat (4) Reporting Service (28) ruby (11) SAP (234) scp (1) SD (16) sed (1) Selenium-WebDriver (5) shell (5) SQL (4) SQL server (8) SQuirreL SQL Client (1) SSH (2) SWOT (3) Symantec (2) T-SQL (7) Tera Term (2) tip (1) tiptop (22) Tomcat (6) Trouble Shooting (1) Tuning (5) Ubuntu (33) ufw (1) utf-8 (1) VIM (11) Virtual Machine (2) vnc (3) Web Service (2) wget (1) Windows (19) Windows (1) WM (6) youtube (1) yum (2)

2012年12月26日 星期三

Oracle : ORA-04031

http://www.laoxiong.net/an-ora-04031-case.html

ORA-04031案例一则

ORA-04031这个错误,几乎每一个专业的DBA都遇到过。这是一个相当严重的错误,Oracle进程在向SGA申请内存时,如果申请失败,则 会报这个错误。大部分情况下是在向SGA中的shared pool申请内存时失败,而少有向large pool等池中申请内存失败。比如下面的报错:
Wed Apr 27 16:00:25 2011
Errors in file /oracle/app/oracle/admin/zxin/bdump/zxin1_ora_2052294.trc:
ORA-04031: unable to allocate 4128 bytes of shared memory
("shared pool","unknown object","sga heap(3,0)","kgllk hash table")
这里很清楚地表示出来,是在向shared pool申请内存时失败。
shared pool内存申请(分配)失败,通常有如下的几种可能:
  • shared pool过小,比如在SGA Manual Management方式下,shared pool设置过小。比如一套数千连接的大系统,shared pool只设置了几百M。这种情况下,要解决问题很解单,增加shared pool的大小即可。
  • 应用没有使用绑定变量,硬解析非常多,导致shared pool内存碎片严重,分配大块内存时不能获得连续的内存空间。硬解析多的一个变种是虽然使用了绑定变量,但是由于某种原因,Cursor不能共享,导致 Child Cursor非常多。实际上,如果shared pool较大(比如数GB大小),这种问题还是很少出现的,并且出现也通常出现在申请大块内存时。这种情况如果使用alter system flush shared_pool可以暂时缓解问题。但是这条命令又通常不适用于shared pool较大而且比较繁忙的系统。使用绑定变量
  • Cache的cursor很多,同时cursor_space_for_time这一参数设置为TRUE,可能会使shared pool碎片化严重,导致不能分配到大块的连续内存。
  • Oracle的BUG导致内存泄露,比如在一些版本中查询v$segment_statistics这样的视图导致内存泄露,使shared pool内存耗光。同样的情形还有类似于“obj stat memory”,”gcs resources”,”ges resources”等。通常这类内存为perm类型(permanet),这类内存通常是在分配时就确定了固定的用途,不能用于其他用途,因此极容易产 生碎片。
  • Oracle从9i开始,根据shared pool的大小将shared pool分为多个子池(subpool),每个子池有独立的free list,同时在分配时单独管理(有其独立 的shared pool latch)。Oracle的BUG或者说是内存分配策略缺陷导致某一类shared pool的内存分配只在一个子池(subpool)中,即多个子池的使用极不均衡,导致向那个使用得最多的子池申请内存时失败。报错信息中的”sga heap(3,0)”即指明是在第3个子池申请内存时失败。本文案例中的ORA-04031错误其产生的原因可以归结为Oracle对shared pool的分配/使用策略问题。
  • 操作系统内存不足,这只会出现在shared pool的使用还没有达到最大值时才会出现,并且在操作系统都有swap的情况下,只有部分操作系统才可能有这种情况,比如在HP-UX下,reserved 内存过多导致swap满。
  • 其他原因,多数是因为BUG。请参考下面提及的MOS参考文档。
本文中的案例,其数据库是运行在AIX 5.3系统中的10.2.0.4 RAC,RAC节点数为2。数据库是从9i升级到10g,而目前处于正式升级前的测试阶段。数据库报的ORA-04031错误信息如本文前面所示(其中的数据库名称已经做了处理)。
在继续讲解案例之前,不得不提到MOS上的几篇关于ORA-04031错误的文档:
  • Master Note for Diagnosing ORA-4031 [ID 1088239.1]
  • Diagnosing and Resolving Error ORA-04031 on the Shared Pool or Other Memory Pools [Video] [ID 146599.1]
  • Interpreting the automatically generated ORA-4031 diagnostic trace. [ID 809560.1]
  • Troubleshooting and Diagnosing ORA-4031 Error [Video] [ID 396940.1]
  • ORA-4031 Common Analysis/Diagnostic Scripts [Video] [ID 430473.1]
其实分析ORA-04031错误,通常有以下几个要点:
  • 判断错误发生所有的内存区域,是shared pool,large pool还是streams pool等。这个很容易从错误信息中判断出来,本文主要描述shared pool的ORA-04031错误,这也是最常见的。
  • 检查Shared Pool的总大小以及free memory的大小。如果free memory看上去挺多,以subpool为单位检查是否存在是由于碎片导致没有足够的连续内存以供分配,特别是关注报错信息中提及的子池。
  • 如果Shared Pool相较于系统规模来说足够大(通常数GB都已经是很大的了),检查Shared Pool中有没有占用非常多的内存类型或内存组件,如果有,是什么样的类型的内存,在各个子池之间是否分布均匀。如果有异常占用较多的内存类型,根据此类 型在MOS上搜寻是否是会有相应的BUG引起,或者分析这种类型的内存消耗较多的原因。比如如果是sql area很大,检查是不是硬解析特别多,或者是不是child cursor特别多引起。
  • 基于以上分析的数据,来判断shared pool内存分配失败的原因。
上面的步骤写得比较粗略,关于分析和解决ORA-04031问题,这里也有一篇不错的文章:Simplified Approach to Resolve ORA-4031
这里关键的是分析Shared Pool的内存数据。ORA-04031错误发生后如果有条件可以马上连接到数据库中查询相应的x$表和v$视图得到相应的数据,否则只能通过ORA- 4031错误发生时产生的trace文件。_4031_dump_bitvec这个隐含参数用于控制发生ORA-04031错误时对SGA的dump行 为,而trace文件的分析就不像使用SQL那样简单了。
下面再来详细地分析案例:
从错误信息来看,很显然,是向shared pool的第3个subpool申请内存时出错。
以下的数据是shared pool的数据:
SQL> select sum(bytes)/1024/1024 mb from v$sgastat where pool='shared pool';

        MB
----------
4096.53062

SQL> SELECT KSMCHCLS CLASS, COUNT(KSMCHCLS) NUM, SUM(KSMCHSIZ)
  2  SIZ,
  3  To_char( ((SUM(KSMCHSIZ)/COUNT(KSMCHCLS)/1024)),'999,999.00')|
  4  |'k' "AVG SIZE"
  5  FROM X$KSMSP GROUP BY KSMCHCLS; 

CLASS           NUM        SIZ AVG SIZE
-------- ---------- ---------- ------------
R-freea         512      24576         .05k
freeabl      807395 1643969848        1.99k
recr         530728  662065240        1.22k
R-free          256  214910976      819.82k
free          43063  100605496        2.28k
perm            140 1673368632   11,672.49k
虽然free的数量不是太多,但是freeable的数量还是很多的。
下面是各个子池更详细的数据:
SQL> SELECT KSMCHIDX,KSMCHDUR, KSMCHCLS CLASS, COUNT(KSMCHCLS) NUM, SUM(KSMCHSIZ)
  2  SIZ,
  3  To_char( ((SUM(KSMCHSIZ)/COUNT(KSMCHCLS)/1024)),'999,999.00')|
  4  |'k' "AVG SIZE"
  5  FROM X$KSMSP GROUP BY KSMCHIDX,KSMCHDUR, KSMCHCLS
  6  order by 1,2,3; 

  KSMCHIDX   KSMCHDUR CLASS           NUM        SIZ AVG SIZE
---------- ---------- -------- ---------- ---------- ------------
         1          1 R-free           27   22666392      819.82k
                      R-freea          54       2592         .05k
                      free             26      14024         .53k
                      perm             32  430299448   13,131.70k
                    2 R-free           12   10073952      819.82k
                      R-freea          24       1152         .05k
                      free          10531   24519112        2.27k
                      freeabl       44922   32457736         .71k
                      recr         163177  134273584         .80k
                    3 R-free            9    7555464      819.82k
                      R-freea          18        864         .05k
                      free           1678    4555704        2.65k
                      freeabl       79815  102514024        1.25k
                      recr          32689   36368096        1.09k
                    4 R-free           20   16789920      819.82k
                      R-freea          40       1920         .05k
                      free           2182    5810056        2.60k
                      freeabl       66235  254656184        3.75k
                      recr          16245   58284480        3.50k
         2          1 R-free           25   20987400      819.82k
                      R-freea          50       2400         .05k
                      free             23      20016         .85k
                      perm             35  398418384   11,116.58k
                    2 R-free            4    3357984      819.82k
                      R-freea           8        384         .05k
                      free           5137    6604176        1.26k
                      freeabl       40377   12140944         .29k
                      recr          54942   45005024         .80k
                    3 R-free            9    7555464      819.82k
                      R-freea          18        864         .05k
                      free           1477    5524568        3.65k
                      freeabl       79548  101879808        1.25k
                      recr          32380   36033448        1.09k
                    4 R-free           21   17629416      819.82k
                      R-freea          42       2016         .05k
                      free           2540    7092424        2.73k
                      freeabl       70133  270332800        3.76k
                      recr          15924   57263032        3.51k
         3          1 R-free           26   21826896      819.82k
                      R-freea          52       2496         .05k
                      free             26      20520         .77k
                      perm             33  414355416   12,261.94k
                    2 R-free            4    3357984      819.82k
                      R-freea           8        384         .05k
                      free           4693    7053032        1.47k
                      freeabl       49723   14339800         .28k
                      recr          52771   42357312         .78k
                    3 R-free           11    9234456      819.82k
                      R-freea          22       1056         .05k
                      free           3594    9280904        2.52k
                      freeabl       95823  121934488        1.24k
                      recr          39643   44097504        1.09k
                    4 R-free           25   20987400      819.82k
                      R-freea          50       2400         .05k
                      free           2822    7291680        2.52k
                      freeabl       84443  323149712        3.74k
                      recr          19148   67997008        3.47k
         4          1 R-free           27   22666392      819.82k
                      R-freea          54       2592         .05k
                      free             26      18088         .68k
                      perm             40  430295384   10,505.26k
                    2 R-free            6    5036976      819.82k
                      R-freea          12        576         .05k
                      free           4818   11473920        2.33k
                      freeabl       46089   39963224         .85k
                      recr          54061   44188072         .80k
                    3 R-free            9    7555464      819.82k
                      R-freea          18        864         .05k
                      free           1427    4109504        2.81k
                      freeabl       80026  102379080        1.25k
                      recr          33217   36949240        1.09k
                    4 R-free           21   17629416      819.82k
                      R-freea          42       2016         .05k
                      free           1993    6228464        3.05k
                      freeabl       70581  269087136        3.72k
                      recr          16614   59372656        3.49k
KSMCHDUR是什么意思?在9i里面这个列的值通常为1。实际上,Oracle从9i开始,将shared pool划分为多个sub pool。而在10g以上的版本中(具体开始的版本号已经不记得),每个sub pool又分了4个更小的池,我们暂且称之为mini heap。每个mini heap有其自己的free list。KSMCHDUR这一列即表示mini heap的编号。”heap(3,0)”中的0是指第1个mini heap。
在上面的数据中,可以看到这个子池的第1个mini heap的free已经很少,只有10来K。另外,我们可以观察到,perm类型的内存块只存在于每个sub pool的第1个min heap中。这个是一个重点,在后面会有解释。
这里本应该有通过查询v$sgastat得到shared pool的各个组件占用的内存分布,只是写BLOG时找不到了….但是我们可以在trace文件中找到数据,下面只列出sub pool 3的数据:
==============================
Memory Utilization of Subpool 3
================================
     Allocation Name          Size
_________________________  __________
"free memory              "    81466568
"miscellaneous            "           0
"dpslut_kfdsg             "         512
"trace buffer             "      737280
"trace_knlasg             "         504
"gcs res hash bucket      "     1048576
"gcs res latch table      "       12288
"evaluation con           "           0
"sql area                 "   344545752
"UNDO STAT INFO           "       59904
"txncallback              "      141744
"transaction              "     2103264
"ges resource pools       "        3968
"sessions                 "     4526488
"dlo fib struct           "      128032
"KJCTS process batching st"         240
"row cache                "        3272
"KCB where statistics arra"       25888
"KCB buffer wait statistic"       32000
"KCB incremental ckpt entr"         512
"invalid low rba queue    "        1024
"table definiti           "      108704
"temporary tabl           "        4136
"KCL instance cache transf"      131072
"resumable                "        2720
"KESTB existence bitvec se"         128
"type object de           "      392448
"enqueue_hash             "      318960
"KSXR pending consumption "       20192
"KTI SGA freeable small po"           0
"trigger defini           "      885472
"trigger source           "       99264
"trigger inform           "         960
"KTCN: Obj Invalidation Se"        2336
"kmgsb circular statistics"      108800
"kgl lock hash table state"       45360
"kglsim size of pinned mem"        8024
"kelr system metrics table"         280
"kzctxgjsi ksuseclid memor"      117360
"kzctxgjci ksuseclid  memo"           0
"CCursor                  "    95912048
"ksr message pool free que"      188960
"ksb ci process list (each"         144
"ksunfy: nodes of hierarch"         320
"ksuloi: long op free list"         256
"kwqmncal: allocate buffer"        4048
"ksim group query request "           0
"ksuxds ksuseclid  memory "           0
"call                     "       87304
"dictionary cache         "           0
"KSXR pending reply queue "      255488
"hng: All sessions data fo"           0
"ksfv subheap descriptor  "         184
"gcs resources            "   169082312
"gcs affinity             "        8320
"gcs opaque in            "       12312
"PCursor                  "    50743128
"ges resource             "      539376
"fdrec_kffsg              "          24
"work area tab            "       80640
"kglsim main lru count    "       38400
"plwpil:wa                "        4264
"grptab_kfgsg             "        2464
"AW SGA                   "          40
"KEWS sesstat seg tbl     "           8
"kebm slave descriptors   "        1456
"kglsim hash table bkts   "     1048576
"KSXR global channels     "        1288
"ges enqueues             "    17333720
"PLS chunk                "         352
"KSQ event description    "        1440
"KESTB existence bitvec   "        4096
"gcs shadows              "   101246344
"qmtb_init_data           "         224
"Core dump directory      "         264
"sort segment handle      "        7480
"SERVICE NAME ENTRY       "          48
"PQ/BizCard               "        1536
"qtree_kwqbspse           "          40
"latch descriptor table   "        1576
"recovery domain          "       29856
"parameters               "       30056
"SHARED SERVERS INFO      "         240
"qtree_kwqbsgn            "          40
"post agent               "           0
"pspool_kfsg              "          80
"plwsppwp:wa              "           0
"PL/SQL DIANA             "    14050624
"segmented arrays         "        2072
"Checkpoint queue         "     4097024
"sim lru segments         "        2560
"sim segment hits         "        2560
"sim state object         "          40
"partitioning d           "      199616
"ASH buffers              "     8388608
"message pool freequeue   "      276336
"PL/SQL MPCODE            "     4499360
"PL/SQL PPCODE            "     3984944
"procs: ksunfy            "     1512000
"primem_kfmdsg            "        1032
"SYSTEM PARAMETERS        "       76624
"object queue hash buckets"      262656
"object queue hash table d"        7552
"object level stats hash t"         512
"object stat dummy statprv"         144
"sim cache sizes          "         320
"logout storm management  "       24000
"pl/sql source            "       21256
"sys event stats          "      199136
"parameter handle         "       67896
"Parameter Handle         "        1656
"channel handle           "      828672
"API blockers array       "          64
"PARAMETER TABLE          "        2048
"PARAMETER ENTRY          "           8
"LGWR post requested array"          24
"bloom filter             "        3104
"param hash values        "        5984
"sql area:PLSQL           "    11477776
"PX subheap desc          "         256
"repository               "      213544
"sql area:KOKA            "       16192
"archive_lag_target       "        9624
"state objects            "         640
"latch nowait fails or sle"      116832
"sched job slv            "        5952
"pso tbs: ksunfy          "      390000
"dummy                    "      269928
"Sort Segment             "       37440
"Cursor Stats             "     6095760
"Banner Storage           "        2048
"quiescing session        "        3872
"API data buffer          "          16
"buffer handles           "     1020000
"prmtzdini tz region      "      408320
"sga node map             "          16
"savepoints               "           0
"Managed Standby Proc Arra"       24576
"OS proc request holder   "        4664
"db_files                 "      416576
"PX server msg stats      "        2288
"KQR M PO                 "      283376
"kks stats                "          40
"parameter table block    "      483168
"KSFV SGA                 "         824
"plugin datafile array    "       36016
"plwda:PLW_STR_NEW_RVAL   "          24
"plwspv:PLW_STR_NEW_VAL   "          16
"KGKP sga                 "          32
"BRANCH TABLE SEGMENTED AR"       70176
"mvobj part des           "      306544
"parameter value memory   "         216
"multiblock re            "       98496
"parameter text value     "        1080
"parallel_max_servers     "        8192
"KGLS heap                "    13290800
"KGSKI sga                "          80
"resize request state obje"      368000
"MTTR advisory            "     1462832
"monitoring co            "       12480
"rules engine aggregate st"        1416
"krbmror                  "       36400
"joxs heap                "         136
"krbmrsr                  "         152
"ksfqpar                  "        4008
"SGA - SWRF DrvMet Runtime"        2656
"SGA - SWRF Metrics ksuTim"          72
"SGA - SWRF RawMet Runtime"        1408
"SGA - SWRF Metrics WCTime"          32
"SQL Memory Manager Base W"       13400
"change notification regis"        4096
"simulator latch/bucket st"       59392
"Prefetch history buffer  "        2832
"change notification obj m"        4096
"KQR ENQ                  "       16512
"kksss                    "       16464
"API data buffer length   "           0
"kokcd                    "           0
"kohsg                    "           8
"Sequence Background Insta"          88
"ksfqpn                   "         416
"KGLS SP                  "        4704
"knstsg                   "          48
"latch classes            "         352
"system default language h"         568
"name-service entry       "        2592
"API data buffer array    "           0
"kzull                    "        4096
"kzulu                    "         392
"kfgsga                   "         104
"library cache            "    46604712
"kcrrny                   "       25320
"spfile cleanup structure "       16760
"xssinfo                  "        5952
"buffer_pool_desc_array   "        3384
"row cache child latch    "        3360
"rm request queue link    "        5320
"SCHEDULING POLICY TABLE  "         160
"namhsh_kfdsg             "        4104
"Closed Thread SCN Bitvec "        8448
"Client ID trace settings "        3872
"osp allocation           "       21104
"os statistics            "        9192
"plwppwp:PLW_STR_NEW_LEN_V"          16
"plwgc: plwgc_garbage_clea"           0
"plwiiw: kglpql warnings  "           0
"object queue             "      808080
"obj stat memo            "      599184
"obj htab chun            "      122960
"object level             "      111888
"XCT XGA                  "           0
"SGA - SWRF Metric Eidbuf "      900840
"Processor group descripto"          64
"Prefetch client count per"          32
"X$SKGXPIA                "        2680
"simulator hash buckets   "     2101248
"State object subpools    "         896
"API data buffer length ma"           0
"AWR Table Info (KEW layer"         872
"character set memory     "        4856
"sim segment num bufs     "        1280
"character set object     "      129728
"session idle latches     "        2560
"qesmmaInitialize:        "         112
"returns from remote ops  "       49152
"name-service             "        4080
"SGA - SWRF Metric CHBs   "       10912
"listener addresses       "          32
"db_block_hash_buckets    "    67108864
"KSI resource types       "        2704
"kglsim object batch      "     4196304
"trigger condition node   "          72
"ksws service events      "       18560
"Heap0: KGL               "    11642128
"fixed allocation callback"         392
"kqlpWrntoStr:value       "           0
"KEWS statistic name      "         424
"KEWS statistic maps      "        1096
"KCL partition table      "      131072
"kebm slave message       "          88
"kcbl state objects       "       12800
"free rm request queue lin"           0
"xsoqsehift               "        3104
"DBWR event stats array   "         192
"kgllk hash table         "      659456
"event descriptor table   "         192
"kpssnfy: kpsssgct        "          32
"kpscad: kpscscon         "        1952
"dbwriter coalesce buffer "     3158016
"kglsim hash table        "        8208
"gcs resource freelist dyn"         256
"gcs shadow locks dyn seg "         256
"kks stats latch          "         160
"KTC latch cleanup        "         576
"ges enqueue max. usage pe"          64
"ges lmd process descripto"        2760
"KTU latch cleanup        "        2496
"kscdnfyinithead          "          16
"X$KSVIT table            "         512
"kqlpaac:value-1          "          64
"KCL buffer header        "      192064
"kxfpdp pointers          "       28800
"kodosgi kopfdo           "         104
"kglsim latches           "         136
"TXN TABLE SEGMENTED ARRAY"       54784
"KJCT remote i            "        1640
"KKJ SHRD WRQS            "         288
"KJC dest ctx             "        3560
"kwrsnfy: kwrs            "        1624
"kwqmn:tskdata            "           0
"KKKI consumer            "        4136
"dbwr suspend/resume ptr a"          16
"dbwr actual working sets "          64
"KGSKI schedule           "           0
"temp lob duration state o"        3296
"ges regular msg buffers  "     3078008
"jsksncb: 9               "       28672
"Transportable DB Converte"        2552
"KTU lat struct           "         800
"kks stats hds            "         256
"KSFD SGA I/O b           "     4190248
"HTTP fixed headers       "          72
"UNDO INFO SEGMENTED ARRAY"      649856
"ges process hash table   "      132000
"jsksncb-latch            "        1280
"kfkid hrec               "          24
"KTCCC OBJECT             "           0
"KTPR HIST TB             "        2808
"KTF MAPPINGS             "       12288
"kksss-heap               "       35136
"kglsim heap              "     3431232
"event statistics per sess"     7665280
"eventlist to post commits"          16
从上面的数据可以看到,第3个sub pool中,占用较多的内存是gcs resources、gcs shadows以及sql area。但是没有明显的异常。
下面是第3个sub pool中第1个mini-heap中free memory的更详细数据:
SQL> break on ksmchidx on ksmchdur
SQL> select
  2    ksmchidx,ksmchdur,
  3    case
  4          when ksmchsiz < 1672 then trunc((ksmchsiz-32)/8)
  5          when ksmchsiz < 4120 then trunc((ksmchsiz+7928)/48)
  6          when ksmchsiz < 8216 then 250
  7          when ksmchsiz < 16408 then 251
  8          when ksmchsiz < 32792 then 252
  9          when ksmchsiz < 65560 then 253
 10          when ksmchsiz >= 65560 then 253
 11     end bucket,
 12    sum(ksmchsiz)  free_space,
 13    count(*)  free_chunks,
 14    trunc(avg(ksmchsiz))  average_size,
 15    max(ksmchsiz)  biggest
 16  from
 17    sys.x$ksmsp
 18  where
 19    inst_id = userenv('Instance') and
 20    ksmchcls = 'free'
 21  group by
 22    case
 23          when ksmchsiz < 1672 then trunc((ksmchsiz-32)/8)
 24          when ksmchsiz < 4120 then trunc((ksmchsiz+7928)/48)
 25          when ksmchsiz < 8216 then 250
 26          when ksmchsiz < 16408 then 251
 27          when ksmchsiz < 32792 then 252
 28          when ksmchsiz < 65560 then 253
 29          when ksmchsiz >= 65560 then 253
 30     end ,
 31    ksmchidx, ksmchdur
 32  order by ksmchidx , ksmchdur
 33  /

  KSMCHIDX   KSMCHDUR     BUCKET FREE_SPACE FREE_CHUNKS AVERAGE_SIZE    BIGGEST
---------- ---------- ---------- ---------- ----------- ------------ ----------
         3          1          5         72           1           72         72
                              13        136           1          136        136
                              27        248           1          248        248
                              48        416           1          416        416
                              56       1920           4          480        480
                              66       1680           3          560        560
                              68       4608           8          576        576
                             164       1344           1         1344       1344
                             180       1472           1         1472       1472
                             188       1536           1         1536       1536
                             190       1552           1         1552       1552
                             199       1624           1         1624       1624
                             204       1880           1         1880       1880
                             207       2032           1         2032       2032
可以看到,最大的free memory块才2032字节,而报错中提到的申请的内存大小为4128字节。由于在第3个sub pool的第1个mini heap中没有4128字节的连续free memory,所以导致内存申请失败。
那么这里的问题是,为什么这个mini heap中的free memory那么少?正如前面提及,为什么这个mini heap中的已经使用的类型全是perm类型?这个问题的答案就在于”DURATION”。Oracle在启用了SGA自动管理的模式下,为了便于在 shared pool与buffer cache或其他内存之间动态调整大小,规定了在每一个mini heap中分配内存按照duration来进行。这里duration可以理解为内存块的持久时间。perm类型的内存块,就是分配后不能释放,只能用于 相同组件的重用。比如gcs resources这种组件的内存是perm类型,这种内存被分配后,不能释放给sql area使用,也不能给gcs shadows使用,只能给其他的gcs resource使用。按DURATION分配内存时,perm类型的内存就只能从每个sub pool的第1个mini heap中分配。而其他类型的内存通常在sub pool的第2-4个mini heap中分配。由于perm类型的内存不能释放,也不能被其他组件的内存重用,所以里面的内存会越用越少,如果没有了free memory怎么办?前面说到,这种模式主要是工作在SGA自动管理模式下,如果free memory没有了,就会从SGA中的其他部分,比如buffer cache中取得memory chunk,加入到缺少内存的mini heap中。正常情况下这种机制没有问题。
完全使用SGA自动管理有一个缺陷就是,如果应用系统绑定变量做得不好,或者由于BUG,child cursor过多,导致shared pool会变得很大,甚至超过10G,严重的比buffer cache还大,另一方面,在buffer cache和shared pool之间频繁地调整大小,可能会导致严重的解析问题和其他性能问题。针对这个问题,通常有2种解决办法:一种就是关闭SGA自动管理,即将 SGA_TARGET设置为0,以9i的方式来设置shared_pool_size,db_cache_size这些参数,来手动管理SGA;第二种就 是sga_target仍然大于0,即自动管理SGA,但是通过设置shared_pool_size,db_cache_size等参数限制这些内存组 件的最小大小,而只留给系统极少的自动调整空间。
而出现问题的这套系统,正是使用了第二种方式,开启了SGA自动调整,但是留给自动调整的空间极少。SGA_TARGET为 35G,buffer_cache_size为30G,shared_pool_size为4G,再加上large_pool等组件,几乎没有什么可自动 调整的余地。这种方式下,就存在了问题。下面来做一个按时间的分析:
  1. 时间T1,数据库启动,shared pool只消耗了极少量的内存。
  2. 时间T2至时间T3,Oracle进程请求shared pool内存,Oracle会向操作系统以指定的粒度为单位(比如16MB)请求物理内存,加入到所请求内存所在的mini heap中。直至shared pool的大小达到shared pool最大容许的大小。这个容许大小由各参数计算而来。比如说SGA_TARGET为10G,其他组件的参数设置后最小值为 8G,shared_pool_size的值为1G,但是shared pool的最大容许大小为2G。这个时候,每个sub pool的mini heap的大小已经固定。在到达shared pool最大容许大小这一阶段,可能会从buffer cache等组件中占用。
  3. 时间T4,Oracle进程请求shared pool内存,这个时候只能从free list或age out内存块后获取内存,对于sub pool的第1个mini heap,只能从free list中获取,因为这个mini heap中的已用内存全是perm,是不能age out的。
  4. 时间T5,Oracle进程请求shared sub pool中第1个mini heap的内存,但是free list中已经没有内存。所以报ORA-04031错误。
在上面的时间点T5那里,如果SGA有较大的自动调整空间,比如说完全没有限制,即buffer_cache_size等参数很少或为0,这样在请 求第1个mini heap中的内存时,完全可以从buffer cache中占用,这样的后果是使shared pool越来越大。
而本文案例的ORA-04031,正是由于SGA自动管理,而自动调整的余地又太小,最终使sub pool的第1个mini heap空间用光。当然我们可以分析为什么会用光,这个就显得更为复杂,这跟数据量、应用系统都有很大的关系。而系统中第1次出现ORA-04031错误 的进程,是一个job进程,而此后大部分出现的错误均是job进程,能检查job代码,发现在做大量的表的大量数据的UPDATE操作,这可能是引起 gcs shadows和gcs resources大量内存使用的原因。在一套RAC数据库中,gcs和ges相关的perm内存占用可能会比较大。
那么除了调整应用,应该怎么样解决这样问题?这里的解决方法是增加shared_pool_size参数到6G,同时将sga_target设置为0,再重启。
而另一种可能的办法是将参数“_enable_shared_pool_durations”设置为FALSE。这一参数为FALSE,将会使 shared pool内存分配时,不再使某一类型的内存(比如perm)必须要求在一个固定的mini heap中。而实际上,sga_target设置为0之后,这一个参数自动会设为FALSE(由于这一参数是静态参数,所以修改了sga_target之 后需要重启才会使这个隐含参数改变),所以建议的解决办法是设置sga_target参数,而不建议修改隐含参数。当然还有一种办法是完全让Oracle 自动管理SGA,将buffer_cache_size和shared_pool_size等参数设置为0,但是正如前面所说,这种方法有比较大的缺陷。

Oracle : /dev/shm

http://www.xifenfei.com/1605.html

一、/dev/shm理论
/dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里。因此在linux下,就不需要大费周折去建ramdisk,直接使用/dev/shm/就可达到很好的优化效果。 /dev /shm/需要注意的一个是容量问题,在linux下,它默认最大为内存的一半大小,使用df -h命令可以看到。但它并不会真正的占用这块内存,如果/dev/shm/下没有任何文件,它占用的内存实际上就是0字节;如果它最大为1G,里头放有 100M文件,那剩余的900M仍然可为其它应用程序所使用,但它所占用的100M内存,是绝不会被系统回收重新划分的,否则谁还敢往里头存文件呢?
默认系统就会加载/dev/shm ,它就是所谓的tmpfs,有人说跟ramdisk(虚拟磁盘),但不一样。象虚拟磁盘一样,tmpfs 可以使用您的 RAM,但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备,并需要一个 mkfs 之类的命令才能真正地使用它,tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。
  tmpfs有以下优势:
  1,动态文件系统的大小。
  2,tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中,读写几乎可以是瞬间的。
  3,tmpfs 数据在重新启动之后不会保留,因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载,绑定的操作。
二、修改/dev/shm大小
默认的最大一半内存大小在某些场合可能不够用,并且默认的inode数量很低一般都要调高些,这时可以用mount命令来管理它。
#mount -o size=1500M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm
在2G的机器上,将最大容量调到1.5G,并且inode数量调到1000000,这意味着大致可存入最多一百万个小文件。
如果需要永久修改/dev/shm的值,需要修改/etc/fstab
tmpfs /dev/shm tmpfs defaults,size=1.5G 0 0
#mount -o remount /dev/shm
三、/dev/shm应用
  首先在/dev/shm建个tmp文件夹,然后与实际/tmp绑定
  #mkdir /dev/shm/tmp
  #chmod 1777 /dev/shm/tmp
  #mount –bind /dev/shm/tmp /tmp(–bind )
  在使用mount –bind olderdir newerdir命令来挂载一个目录到另一个目录后,newerdir的权限和所有者等所有信息会发生变化。挂载后的目录继承了被挂载目录的所有属性,除了名称。Oracle 11g的amm内存管理模式就是使用/dev/shm,所以有时候修改MEMORY_TARGET或者MEMORY_MAX_TARGET会出现ORA-00845的错误

Oracle : ASMM

http://jolly10.itpub.net/post/7268/453064

Automatic Shared Memory Management(ASMM)是ORACLE10g另外一个自动管理的功能。

Automatic Shared Memory Management(ASMM)是ORACLE10g另外一个自动管理的功能。
只需指定SGA_TARGET参数(SAG的总大小),数据库将会根据负载和历史信息来自动分配SAG的每个组件。
启用ASSM需将STATISTICS_LEVEL参数设为TYPICAL或ALL,并且SGA_TARGET参数为非0.
ASSM自动分配以下SGA组件:
--DB_CACHE_SIZE
--SHARED_POOL_SIZE
--LARGE_POOL_SIZE
--JAVE_POOL_SIZE
以下的组件还需要手动来管理
--LOG_BUFFER
--DB_KEEP_CACHE_SIZE,DB_RECYCLE_CACHE_SIZE,DB_nK_CACHE_SIZE
--STREAMS_POOL_SIZE
--Fixed-SGA area and internal allocations
手动管理的组件也包括在SAG_TARGET中,比如SGA_TARGET是400M,LOG_BUFFER为1M,DB_KEEP_CACHE_SIZE为500M,那么可供ASSM来自动管理的大小只有349M。
SAG_TARGET参数可以通过ALTER SYSTEM来动态的改变大小,但不能超过SGA_MAX_SIZE参数大小,SGA_MAX_SIZE不是动态可以改变的。
可以通过V$SGA_DYNAMIC_COMPONENTS视图来查看当前SGA组件的大小。
如SGA_TARGET设为0来关闭ASSM,当前各组件的SIZE将会写入SPFILE用来下次的启动。
动态SGA相关的视图:
V$SGA_CURRENT_RESIZE_OPS
V$SGA_RESIZE_OPS
V$SGA_DYNAMIC_COMPONENTS
V$SGA_DYNAMIC_FREE_MEMORY
ORACLE10G用MMAN进程来管理automatic shared memory.MMAN进程观察系统的负载来决定比较理想的内存分配。
根据负载的情况,ASSM做以下工作:
--在后台周期性捕获统计信息
--用不同的内存建议
--分析内存组件的情况
--如有需要移除内存
--如SPFILE被使用,关闭数据库时记录当前各组件大小
  当重新设置了sga_target的大小的时候,只有新值比当前组件的值大的时候才会立刻改变.如果你设置sga_target为8g,设置shared_pool_size为2g,你确信为了容纳必要的内存,共享池至少2g.当你把共享池调为1g的时候,不会立刻改变共享池的大小.它只会告诉自动内存调整算法在需要的时候,会把共享池改为1g.另外,如果一开始共享池是1g,你把它设置为2g,那么马上就生效.在重新改变操作中使用的内存是从一个或几个其它的自动调整的组件中得到了,手工的组件不受影响.
  
  手工改变大小的组件也可以动态的修改,但是他们的不同就是马上就是设置的值.这样,如果手工组件的值增加,额外的内存就是从一个或多个自动调整的组件中获得的.如果手工组件的值减少了,释放出来的内存就给了自动调整大小的组件.
在共享内存自动管理(ASMM)机制出现之前,共享内存的管理是一个十分复杂的工作。Oracle 9i开始支持部分SGA参数可以动态调整,这个功能大大提升了DBA进行内存管理的能力,调整部分内存参数不需要重启数据库。从9.0.1开始,共享池和default pool的大小可以动态修改,从9.2开始,又增加了LARGE POOL的动态调整。Oracle 10G则出现了一种革命性的技术-ASMM。共享内存自动管理可以把部分缓冲区的管理智能交给Oracle数据库管理器本身。RDBMS根据系统的负载情况,自动调整这些缓冲区,从而达到优化系统性能的作用。
在安装ORACLE 10G的时候,ASMM缺省是关闭的,因为SGA_TARGET参数的缺省值是0,当该参数为非0值,并且STATISTICS_LEVEL是TYPICAL 或者ALL的时候,ORACLE RDBMS启用ASMM。由于广大用户对ASMM还不了解,因此目前应用ASMM的数据库并不多,特别是大型数据库,很少使用ASMM。在最近的一些Oracle版本中,总是能够出现一些自动化管理的功能,广大用户也是在最初不理解,并不敢用的情况下,逐步消除了顾虑,并且广泛的应用了这些自动管理机制。以回滚段自动管理机制来说,该机制大大简化了DBA管理回滚段的工作,起到了十分好的效果。PGA自动管理的引入,也大大提高了PGA各种工作区的利用率,节省了大量宝贵的内存资源。因此我们有理由相信,ORACLE ASMM技术也将会大大减轻DBA管理共享内存的工作量。和其他自动管理机制一样,对于内存资源竞争不是很激烈的系统或者是系统压力不是很大的系统,使用ASMM可以减轻DBA的工作量。
ASMM的另外一个优势是能够把有限的内存资源合理分配,不会因为DBA设置错误而导致部分缓冲区性能下降。一个新的后台进程mman会对系统的缓冲区状态进行分析,根据目前系统的负载情况,根据一定的策略对缓冲区进行调整。其处理过程如下:
? 首先,周期性采集系统的状态
? 生成或分析建议直方图
? 根据直方图找到合理的缓冲区调整方案
? 根据调整方案自动调整各个缓冲区的大小
使用ASMM也解决了一个以前一直困扰DBA的问题,那就是我们的系统往往是白天在做OLTP操作,夜晚有很多统计分析工作。白天和夜晚需要的内存分配策略是不同的。在ASMM技术出现之前,DBA没有很好的方法来解决这个矛盾,除非DBA能够每天进行参数调整。如果使用ASMM技术,可以通过ASMM技术自身的自动调节功能来动态分配各种内存缓冲区,从而起到DBA很难做到的作用。
ASMM有很多优点,但是ASMM也不是万能的,使用ASMM不当也会带来严重的系统性能问题,如果系统中的内存资源不足,或者系统的负载十分大,那么就需要DBA通过自己的工作手工调整来进行优化。如果内存已经不足,或者出现了明显的由于缓冲区引起的性能问题,那么就尽量不要使用ASMM。
目前ASMM并不能管理所有的SGA对象,随着ASMM技术的进一步发展,ASMM能够管理的SGA对象会越来越多,ASMM的人工智能也会越来越强大。以下缓冲区是可通过ASMM来管理的:
? SHARED POOL
? LARGE POOL
? JAVA POOL
? DB CACHE
要注意的是,10G ASMM只能管理DB CACHE中的DEFAULT池,而不能管理所有的DB CACHE。KEEP池、RECYCLE池和NK缓冲池都需要手工管理。另外LOG BUFFER和STREAM POOL等也需要手工管理。
和ASMM相关的ORACLE参数包括SGA_MAX_SIZE和SGA_TARGET。前者定义了SGA能使用的最大内存大小,SGA_TARGET设置了动态调整内存的各种缓冲池的总的大小。要注意的是SGA_TARGET是一个可以动态调整的参数,它限定了在进行ASMM处理的时候,所有内存缓冲区的总的大小,包含ASMM可以动态自动调整的缓冲池和需要手工配置的缓冲池的总的大小。如果SGA_TARGET设置为3G,DB_KEEP_CACHE_SIZE是1G,那么ASSM管理的缓冲池总的大小不能超过2G。
如果使用ASMM,调整SGA_TARGET是DBA的主要工作。SGA_TARGET可以动态调整。SGA_TARGET的最大值不能超过SGA_MAX_SIZE规定的大小。如果DBA调整SGA_TARGET的值,那么会引起被ASMM管理的缓冲区的变化,而不会引起手工管理的缓冲区的变化。
在使用ASMM的情况下,ASMM自动管理的缓冲池可以设置为0,也就是说不设置任何限制,由ASSM完全管理。如果某个ASMM自动管理的缓冲池设置了非零的值,那么ASMM会保证在任何情况下,这个缓冲池的大小不会小于这个参数设置值。在数据库运行的过程中,DBA可以动态调整ASMM管理的缓冲池的大小,如果设置的新值大于目前缓冲池的大小,并且是合理的,那么该设置会立即生效。如果设置的新值小于目前缓冲池的大小,ASMM会记录下这个设置建议,但是不会立即缩小缓冲池,而是会等待今后别的缓冲池需要扩展的时候才会释放。
对于一个使用ASMM的系统,可以随时改变为关闭ASMM,只要将SGA_TARGET设置为0。如果这个操作发生了,那么所有的ASMM管理的参数都会保留为当前的设置。
ASMM是ORACLE 10g的一项革命性的技术,其意义并不仅仅是简化DBA的管理难度。随着ASMM技术的日渐成熟,ASMM使ORACLE提供了一种对OLTP/OLAP应用自适应的能力,从而解决一直困扰DBA的混合型应用的问题。对于既有OLTP应用,又在部分时间(比如晚上或者月底)带有大量OLAP分析的系统来说,如果能够根据应用的特点,动态自动调整相关缓冲池,那么意义是十分巨大的。此类应用目前十分广泛,在电信、制造业、政府等行业应用里,都或多或少存在类似的问题。
在使用ASMM的情况下,通过SGA_TARGET可以设定SGA缓冲池的最大大小,另外可以通过设定ASMM管理缓冲池的参数来限制某个缓冲池的最小限制,以防止ASMM出现错误的设置,导致缓冲池抖动。在这些机制的保证下,只要DBA能够设置合理的配置,能够保证ASMM提供最佳的管理性能。

Oracle : ASM

http://space.itpub.net/?uid-7607759-action-viewspace-itemid-664212

 ORACLE10g版本推出时,为了简化RAC中存储端的配置,ORACLE新推出了ASM(Automatic Storage Management --自动存储管理)特性,该特性拥有易管理,高自动性,并且,拥有号称超越裸设备IO性能。升级到11gR2版本后,又被正名为传说中的ASMFS,这也说明了ORACLE对这一特性的重视程度。
  因此从今天起,三思决定花个三二分钟时间,跟大学一块学学关于ASM的那点儿事儿,另注,本文操作的数据库版本为10gR2。

1、About ASM 实例

ASM 实例与 ORACLE 实例差不多,都是 由 sga 和一堆后台进程组成,从功能上来看,区别在于oracle实例管理的是数据库,而asm实例只是管理asm盘阵。
  通过Oracle EM或DBCA都可以对asm进行一些配置,不过三思觉着管理asm括弧实例的最佳工具仍是sql*plus,在进入sql*plus前也需要设置ORACLE_SID的环境变量,该环境变量通常是+ASM[node#] 。
   ASM 实例没有数据字典之类的东东存储用户系统,因此最常见的连接认证方式就是操作系统认证as sysdba进入(OSDBA组的用户)。如果是通过远程连接 的话( 比如远程通过tnsnames或OEM管理),也可以使用密钥文件进行验证,该密钥文件直数据库的密钥文件在命名规则及使用规则上完全一模一样。如果使用 dbca建库的话,默认就会创建asm的密钥文件,当然也可以自行手动通过orapwd命令进行创建,与数据库的密钥文件有所不同的是,asm 的密钥文件对应的用户只有一个----sys。
    提示:什么是 ASMLib !
    即ASM support Library,是由ORACLE提供的简化管理操作系统管理的API 。

1.1、启动 / 关闭 ASM 实例

ASM 实例与DB实例高度相似,启动和停止实例的命令也一模一样,就启动来说,也同样拥有 NOMOUNT/MOUNT/OPEN /FORCE 几种状态。
  • NOMOUNT :仅启动实例;
  • MOUNT 、OPEN:启动实例并加载磁盘,注意加载的是磁盘组(如果当前未创建或配置任何磁盘组,则提示敬告信息),OPEN选项对于ASM实例无意义,等同于MOUNT。
  • FORCE :相当于先执行shutdown abort,然后再startup。
演示如下(注意别忘了先设置操作系统环境变量ORACLE_SID),先启动到NOMOUNT:
    [oracle@jssdbn1 ~]$ export ORACLE_SID=+ASM1
    [oracle@jssdbn1 ~]$ sqlplus / as sysdba
    SQL*Plus: Release 10.2.0.4.0 - Production on Wed May 19 08:34:22 2010
    Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
    Connected to an idle instance.
    SQL> startup nomount
    ASM instance started
    Total System Global Area  130023424 bytes
    Fixed Size                  2082208 bytes
    Variable Size             102775392 bytes
    ASM Cache                  25165824 bytes
    SQL> select name,state from v$asm_diskgroup;
    NAME                           STATE
    ------------------------------ -----------
    ASMDISK1                       DISMOUNTED
    ASMDISK2                       DISMOUNTED
    SQL> select instance_name,status from v$instance;
    INSTANCE_NAME    STATUS
    ---------------- ------------
    +ASM1            STARTED
加载磁盘组,注意,不是alter database哟:
    SQL> alter diskgroup all mount;
    Diskgroup altered.
    SQL> select name,state from v$asm_diskgroup;
    NAME                           STATE
    ------------------------------ -----------
    ASMDISK1                       MOUNTED
    ASMDISK2                       MOUNTED
这样,该ASM就可以提供存储服务了。
  提示一点,在10g版 本中,ASM是依赖于CSS守护进程的,因此在启动ASM 实例前要确保css守护进程已经启动 。 CSS(Cluster Synchronization Services) 守护进程 用来维持ASM 及客户端数据库实例间的一致性 同步 ,如果是通过dbca建库的话,那么CSS守护进程默认即会启动(跟随系统reboot)。
  检查css守护进程是否启动非常 简单 ,直接使用crsctl check cssd即可,如果启动的话会收到"CSS appears healthy"的返回消息,例如:
    [oracle@jssdbn1 ~]$ crsctl check cssd
    CSS appears healthy
关闭ASM实例,简单了,NORMAL/IMMEDIATE/TRANSACTIONAL/ABORT几个选项的定义与关闭普通数据库实例完全一模一样!例如:
    SQL> shutdown immediate
    ASM diskgroups dismounted
    ASM instance shutdown

1.2、关于ASM实例的初始化参数

ASM 实例的初始化参数形式上与数据库的初始化参数相同,也分spfile和pfile,操作方式也完全相同,只不过具体的参数及参数值略有差异,大多数数据库 的初始化参数在这里也能见到,并且某些参数意义都完全相同,同样也有一些参数虽然见到了,不过并不需要设置,这个可以理解,毕竟asm只有实例,相对比数 据库的初始化参数要简单的多了,还有一些参数则是数据库初始化参数中没有的。比如ASM开头的那几个初始化参数,俺争取把差异的部分都列出来写明了。
  ASM 实例在内存占用这块还是比较轻量级的,基本上有个100m空间就很充足了 ,因此内存这块相关参数就不说了,下面说说几个ASM实例特别需要的参数。
  首先,初始化参数中的INSTANCE_TYPE,该参数必须被设置为ASM,如:
    INSTANCE_TYPE=ASM
标识要启动的实例是ASM,而不是数据库实例(数据库实例对应类型为RDBMS)。
  与ASM相关的初始化参数有三个:
  • ASM_POWER_LIMIT :指定磁盘rebalance的程度,有0-11个级别,默认值为1,指定的级别越高,则rebalance的操作就会越快被完成(当然这也意味着这个时 间段内将占用更多的资源),指定级别较低的话,虽然rebalance操作会耗时更久,但对当前系统的IO及负载影响会更少,这中间的度需要DBA根据实 际情况衡量。另外,这个参数指定的只是一个默认值,在操作过程中,即可以随便动态修改,也可以在语句级命令行时指定power,覆盖该默认值。
    提示:关于rebalance操作,如果你没接触过,还不明白是什么意思,没关系,继续往下看!
  • ASM_DISKSTRING :用最简单的话说,就是设置ASM启动时检查的磁盘,该选项可以同时指定多个值,并且支持通配符。比如说,只检查/dev/dsk/下的设备,可以设置该 参数如下:/dev/dsk/*,默认情况下该参数为空,为空的话,表示ASM将查找系统中所有ASM拥有读写权限的设备。
  • ASM_DISKGROUPS :指定实例启动或alter diskgroup all mount语句时要加载的磁盘组,如果为空的话,那么实际就仅启动到NOMOUNT状态了。如 果是使用SPFILE的话,该参数一般不需要手动修改,ASM能够自动更新该初始化参数中的值。
修改 ASM 实例初始化参数文件的命令规则与数据库初始化参数完全相同 ,比如说:
    SQL> alter system set asm_power_limit=5 sid='*';
    System altered.

Oracle : MEMORY_TARGET not supported on this system


转自:http://home.ixpub.net/space.php?uid=9727518&do=blog&id=408111
今天在升级oracle11g11.1.0.6版本数据库到 11.1.0.7版本,在安装补丁p6890831_111070_Linux-x86.zip后,接着通过dbua升级数据库时,出现“MEMORY_TARGET not supported on this system”的提示,接着数据库升级就中止了,于是,仔细查阅了这个问题,原来oracle 11g版本不但在升级时会出现这个问题,如果设置MEMORY_TARGET不当,也会出现此问题。
其实,这个问题是SGA的设置超出了操作系统/dev/shm大小导致的。
下面是老杨写的关于此错误的一篇文章:
Oracle 11gLinux版本在修改了MEMORY_TARGET或者SGA_TARGET后 启动可能会报错:
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-00845: MEMORY_TARGET not supported on this system

这个问题是由于设置SGA的大小超过了操作系 统/dev/shm的大小:
[root@enterprice64 ~]# df -k /dev/shm
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 4089416 0 4089416 0% /dev/shm

Oraclemetalink的文档:Doc ID:Note:460506.1中进行了说明。解决这个问题只有两个方 法,一种是修改初始化参数,使得初始化参数中SGA的设置小于/dev/shm的大小,另一种方法就是调整/dev/shm的 大小。
修改/dev/shm的大小可以通过修改/etc/fstab来实现:
[root@enterprice64 ~]# vi /etc/fstab
LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
LABEL=/data /data ext3 defaults 1 2
devpts /dev/pts devpts gid=5,mode=620 0 0
#tmpfs /dev/shm tmpfs defaults 0 0
tmpfs /dev/shm tmpfs defaults,size=10240M 0 0
LABEL=/home /home ext3 defaults 1 2
LABEL=/opt /opt ext3 defaults 1 2
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
LABEL=/usr /usr ext3 defaults 1 2
LABEL=/var /var ext3 defaults 1 2
LABEL=SWAP-sda8 swap swap defaults 0 0
~
~
"/etc/fstab" 13L, 965C written
[root@enterprice64 ~]# umount /dev/shm
[root@enterprice64 ~]# mount /dev/shm
[root@enterprice64 ~]# df -k /dev/shm
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 10485760 0 10485760 0% /dev/shm
[root@enterprice64 ~]# su - oracle
[oracle@enterprice64 ~]$ sqlplus "/ as sysdba"

www.ixdba.net

SQL*Plus: Release 11.1.0.6.0 - Production on Tue Oct 23 15:42:42 2007
Copyright (c) 1982, 2007, Oracle. All rights reserved.
Connected to an idle instance.
SQL> startup
ORACLE instance started.

Total System Global Area 4743446528 bytes
Fixed Size 2143824 bytes
Variable Size 3892316592 bytes
Database Buffers 805306368 bytes
Redo Buffers 43679744 bytes
Database mounted.
Database opened.

修改/etc/fstab,重新mount /dev/shm,然后就可以启动数据库了。

2012年12月25日 星期二

Oracle : buffer busy waits

 

buffer busy waits

A buffer busy wait occurs if multiple processes want to access a buffer in the buffer cache concurrently.
The type of buffer that causes the wait can be queried with v$waitstat. v$waitstat lists the waits per buffer type for buffer busy waits only. Therefore, the following SQL statement always returns 0
select
  (select total_waits from v$system_event
  where event='buffer busy waits')
-  /* minus */
  (select sum(count) from v$waitstat)
from
  dual;

Type of block waited for

Buffer busy waits is one of the events that Oracle records while it is running.








http://www.itpub.net/thread-815871-1-1.html

Oracle Wait Interface读书笔记之Buffer busy waits事件

当进程需要存取SGA中的buffer的时候,它会依次执行如下步骤的操作:
1.获得cache buffers chains latch,遍历那条buffer chain直到找到需要的buffer header
2.根据需要进行的操作类型(读或写),它需要在buffer header上获得一个共享或独占模式的buffer pin或者buffer lock
3.若进程获得buffer header pin,它会释放获得的cache buffers chains latch,然后执行对buffer block的操作
4.若进程无法获得buffer header pin,它就会在buffer busy waits事件上等待
进 程之所以无法获得buffer header pin,是因为为了保证数据的一致性,同一时刻一个block只能被一个进程pin住进行存取,因此当一个进程需要存取buffer cache中一个被其他进程使用的block的时候,这个进程就会产生对该block的buffer busy waits事件。
截至 Oracle 9i,buffer busy waits事件的p1,p2,p3三个参数分别是file#,block#和id,分别表示等待的buffer block所在的文件编号,块编号和具体的等待原因编号,到了Oracle 10g,前两个参数没变,第3个参数变成了块类型编号,这一点可以通过查询v$event_name视图来进行验证:
PHP code:--------------------------------------------------------------------------------
Oracle 9i
SQL> select parameter1,parameter2,parameter3 from v$event_name where name='buffer busy waits';
PARAMETER1 PARAMETER2 PARAMETER3
------------------------ ------------------------ ------------------------
file# block# id
Oracle 10g
PARAMETER1 PARAMETER2 PARAMETER3
------------------------ ------------------------ ------------------------
file# block# class#
--------------------------------------------------------------------------------
在诊断buffer busy waits事件的过程中,获取如下信息会很有用:
1.获取产生buffer busy waits事件的等待原因编号,这可以通过查询该事件的p3参数值获得
2.获取产生此事件的SQL语句,可以通过如下的查询获得:
select sql_text from v$sql t1,v$session t2,v$session_wait t3
where t1.address=t2.sql_address and t1.hash_value=t2.sql_hash_value
and t2.sid=t3.sid and t3.event='buffer busy waits';
3.获取等待的块的类型以及所在的segment,可以通过如下查询获得:
PHP code:--------------------------------------------------------------------------------
select 'Segment Header' class,a.segment_type,a.segment_name,a.partition_name from dba_segments a,v$session_wait b
where a.header_file=b.p1 and a.header_block=b.p2 and b.event='buffer busy waits'
union
select 'Freelist Groups' class,a.segment_type,a.segment_name,a.partition_name from dba_segments a,v$session_wait b
where a.header_file=b.p1 and b.p2 between a.header_block+1 and (a.header_block+a.freelist_groups) and a.freelist_groups>1 and b.event='buffer busy waits'
union
select a.segment_type||' block' class,a.segment_type,a.segment_name,a.partition_name from dba_extents a,v$session_wait b
where a.file_id=b.p1 and b.p2 between a.block_id and a.block_id+a.blocks-1 and b.event='buffer busy waits' and not exists(select 1 from dba_segments where
header_file=b.p1 and header_block= b.p2);--------------------------------------------------------------------------------
查 询的第一部分:如果等待的块类型是segment header,那么可以直接拿buffer busy waits事件的p1和p2参数去dba_segments视图中匹配header_file和header_block字段即可找到等待的 segment名称和segment类型,进行相应调整
查询的第二部分:如果等待的块类型是freelist groups,也可以在dba_segments视图中找出对应的segment名称和segment类型,注意这里的参数p2表示的freelist groups的位置是在segment的header_block+1到header_block+freelist groups组数之间,并且freelist groups组数大于1
查询的第三部分:如果等待的块类型是普通的数据块,那么可以用p1、p2参数和dba_extents进行联合查询得到block所在的segment名称和segment类型
对于不同的等待块类型,我们采取不同的处理办法:
1.data segment header:
进 程经常性的访问data segment header通常有两个原因:获取或修改process freelists信息、扩展高水位标记,针对第一种情况,进程频繁访问process freelists信息导致freelist争用,我们可以增大相应的segment对象的存储参数freelist或者freelist groups;若由于数据块频繁进出freelist而导致进程经常要修改freelist,则可以将pctfree值和pctused值设置较大的差 距,从而避免数据块频繁进出freelist;对于第二种情况,由于该segment空间消耗很快,而设置的next extent过小,导致频繁扩展高水位标记,解决的办法是增大segment对象的存储参数next extent或者直接在创建表空间的时候设置extent size uniform
2.data block:
某一或某些数据块被多个进程同时读写,成为热点块,可以通过如下这些办法来解决这个问题:
(1)降低程序的并发度,如果程序中使用了parallel查询,降低parallel degree,以免多个parallel slave同时访问同样的数据对象而形成等待降低性能
(2)调整应用程序使之能读取较少的数据块就能获取所需的数据,减少buffer gets和physical reads
(3) 减少同一个block中的记录数,使记录分布于更多的数据块中,这可以通过若干途径实现:可以调整segment对象的pctfree值,可以将 segment重建到block size较小的表空间中,还可以用alter table minimize records_per_block语句减少每块中的记录数
(4)若热点块对象是类似自增id字段的索引,则可以将索引转换为反转索引,打散数据分布,分散热点块
3.undo segment header:
undo segment header争用是因为系统中undo segment不够,需要增加足够的undo segment,根据undo segment的管理方法,若是手工管理模式,需要修改rollback_segments初始化参数来增加rollback segment,若是自动管理模式,可以减小transactions_per_rollback_segment初始化参数的值来使oracle自动增 多rollback segment的数量
4.undo block:
undo block争用是由于应用程序中存在对数据的读和写同时进行,读进程需要到undo segment中去获得一致性数据,解决办法是错开应用程序修改数据和大量查询数据的时间
小 结:buffer busy waits事件是oracle等待事件中比较复杂的一个,其形成原因很多,需要根据p3参数对照Oracle提供的原因代码表进行相应的诊断,10g以后 则需要根据等待的block类型结合引起等待时间的具体SQL进行分析,采取相应的调整措施

 

 

http://www.dba-oracle.com/art_builder_bbw.htm

Causes of Oracle Buffer Busy Waits




One of the most confounding problems with Oracle is the resolution of buffer busy wait events. Buffer busy waits are common in an I/O-bound Oracle system, as evidenced by any system with read (sequential/scattered) waits in the top-five waits in the Oracle STATSPACK report, like this:
Top 5 Timed Events
                                                          % Total
 Event                         Waits        Time (s)     Ela Time
 --------------------------- ------------ ----------- -----------
 db file sequential read       2,598        7,146           48.54
 db file scattered read       25,519        3,246           22.04

 library cache load lock         673        1,363            9.26
 CPU time                      2,154          934            7.83
 log file parallel write      19,157          837            5.68
The main way to reduce buffer busy waits is to reduce the total I/O on the system. This can be done by tuning the SQL to access rows with fewer block reads (i.e., by adding indexes). Even if we have a huge db_cache_size, we may still see buffer busy waits, and increasing the buffer size won't help.
The resolution of a "buffer busy wait"  events is one of the most confounding problems with Oracle.  In an I/O-bound Oracle system, buffer busy waits are common, as evidenced by any system with read (sequential/scattered) waits in the top-five waits.
Reducing buffer busy waits reduces the total I/O on the system. This can be accomplished by tuning the SQL to access rows with fewer block reads by adding indexes, adjusting the database writer or adding freelists to tables and indexes.  Even if there is a huge db_cache_size , the DBA may still see buffer busy waits and, in this case, increasing the buffer size will not help.
The most common remedies for high buffer busy waits include database writer (DBWR) contention tuning, adding freelists to a table and index, implementing Automatic Segment Storage Management (ASSM, a.k.a bitmap freelists), and, of course, and adding a missing index to reduce buffer touches.
In order to look at system-wide wait events, we can query the v$system_event performance view. This view, shown below, provides the name of the wait event, the total number of waits and timeouts, the total time waited, and the average wait time per event.
select *
from
   v$system_event
where
   event like ‘%wait%’;
 

EVENT                       TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED AVERAGE_WAIT
--------------------------- ----------- -------------- ----------- ------------
buffer busy waits                636528           1557      549700   .863591232
write complete waits               1193              0       14799   12.4048617
free buffer waits                  1601              0         622   .388507183
The type of buffer that causes the wait can be queried using the v$waitstat view. This view lists the waits per buffer type for buffer busy waits, where COUNT is the sum of all waits for the class of block, and TIME is the sum of all wait times for that class:
select * from v$waitstat;

CLASS                   COUNT       TIME
 ------------------ ---------- ----------
 data block            1961113    1870278
 segment header          34535     159082
 undo header            233632      86239
 undo block               1886       1706

Buffer busy waits occur when an Oracle session needs to access a block in the buffer cache, but cannot because the buffer copy of the data block is locked. This buffer busy wait condition can happen for either of the following reasons:
  • The block is being read into the buffer by another session, so the waiting session must wait for the block read to complete.
     
  • Another session has the buffer block locked in a mode that is incompatible with the waiting session's request.
Because buffer busy waits are due to contention between particular blocks, there's nothing you can do until you know which blocks are in conflict and why the conflicts are occurring. Tuning therefore involves identifying and eliminating the cause of the block contention.

The v$session_wait performance view, shown below, can give some insight into what is being waited for and why the wait is occurring.
SQL> desc v$session_wait
 
 Name                                      Null?    Type
 ----------------------------------------- -------- ------------
 SID                                                NUMBER
 SEQ#                                               NUMBER
 EVENT                                              VARCHAR2(64)
 P1TEXT                                             VARCHAR2(64)
 P1                                                 NUMBER
 P1RAW                                              RAW(4)
 P2TEXT                                             VARCHAR2(64)
 P2                                                 NUMBER
 P2RAW                                              RAW(4)
 P3TEXT                                             VARCHAR2(64)
 P3                                                 NUMBER
 P3RAW                                              RAW(4)
 WAIT_TIME                                          NUMBER
 SECONDS_IN_WAIT                                    NUMBER
 STATE                                              VARCHAR2(19)

The columns of the v$session_wait view that are of particular interest for a buffer busy wait event are:
  • P1—The absolute file number for the data file involved in the wait.
     
  • P2—The block number within the data file referenced in P1 that is being waited upon.
     
  • P3—The reason code describing why the wait is occurring.

Here's an Oracle data dictionary query for these values:

select
   p1 "File #",
   p2 "Block #",
   p3 "Reason Code"
from
   v$session_wait
where
   event = 'buffer busy waits';


If the output from repeatedly running the above query shows that a block or range of blocks is experiencing waits, the following query should show the name and type of the segment:

select
   owner,
   segment_name,
   segment_type
from
   dba_extents
where
   file_id = &P1
and
  &P2 between block_id and block_id + blocks -1;


Once the segment is identified, the v$segment_statistics performance view facilitates real-time monitoring of segment-level statistics. This enables a DBA to identify performance problems associated with individual tables or indexes, as shown below.
select
   object_name,
   statistic_name,
   value
from
   V$SEGMENT_STATISTICS
where
   object_name = 'SOURCE$';
 
 
 
OBJECT_NAME   STATISTIC_NAME               VALUE
-----------  -------------------------     ----------
SOURCE$       logical reads                     11216
SOURCE$       buffer busy waits                   210
SOURCE$       db block changes                     32
SOURCE$       physical reads                    10365
SOURCE$       physical writes                       0
SOURCE$       physical reads direct                 0
SOURCE$       physical writes direct                0
SOURCE$       ITL waits                             0
SOURCE$       row lock waits
We can also query the dba_data_files to determine the file_name for the file involved in the wait by using the P1 value from v$session_wait for the file_id.
 
SQL> desc dba_data_files
 
 Name                                      Null?    Type
 ----------------------------------------- -------- -----------
 FILE_NAME                                          VARCHAR2(513)
 FILE_ID                                            NUMBER
 TABLESPACE_NAME                                    VARCHAR2(30)
 BYTES                                              NUMBER
 BLOCKS                                             NUMBER
 STATUS                                             VARCHAR2(9)
 RELATIVE_FNO                                       NUMBER
 AUTOEXTENSIBLE                                     VARCHAR2(3)
 MAXBYTES                                           NUMBER
 MAXBLOCKS                                          NUMBER
 INCREMENT_BY                                       NUMBER
 USER_BYTES                                         NUMBER
 USER_BLOCKS                                        NUMBER

Interrogating the P3 (reason code) value from v$session_wait for a buffer busy wait event will tell us why the session is waiting. The reason codes range from 0 to 300 and can be decoded.

Code Reason for wait
- A modification is happening on a SCUR or XCUR buffer but has not yet completed.
0 The block is being read into the buffer cache.
100 We want to NEW the block, but the block is currently being read by another session (most likely for undo).
110 We want the CURRENT block either shared or exclusive but the block is being read into cache by another session, so we have to wait until its read() is completed.
120 We want to get the block in current mode, but someone else is currently reading it into the cache. Wait for the user to complete the read. This occurs during buffer lookup.
130 Block is being read by another session, and no other suitable block image was found, so we wait until the read is completed. This may also occur after a buffer cache assumed deadlock. The kernel can't get a buffer in a certain amount of time and assumes a deadlock. Therefore it will read the CR version of the block.
200 We want to NEW the block, but someone else is using the current copy, so we have to wait for that user to finish.
210 The session wants the block in SCUR or XCUR mode. If this is a buffer exchange or the session is in discrete TX mode, the session waits for the first time and the second time escalates the block as a deadlock, so does not show up as waiting very long. In this case, the statistic: "exchange deadlocks" is incremented, and we yield the CPU for the "buffer deadlock" wait event.
220 During buffer lookup for a CURRENT copy of a buffer, we have found the buffer but someone holds it in an incompatible mode, so we have to wait.
230 Trying to get a buffer in CR/CRX mode, but a modification has started on the buffer that has not yet been completed.
231 CR/CRX scan found the CURRENT block, but a modification has started on the buffer that has not yet been completed.
Reason codes

As I mentioned at the beginning of this article, buffer busy waits are prevalent in I/O-bound systems. I/O contention, resulting in waits for data blocks, is often due to numerous sessions repeatedly reading the same blocks, as when many sessions scan the same index.
In this scenario, session one scans the blocks in the buffer cache quickly, but then a block has to be read from disk. While session one awaits the disk read to complete, other sessions scanning the same index soon catch up to session one and want the same block currently being read from disk. This is where the buffer busy wait occurs—waiting for the buffer blocks that are being read from disk.

The following rules of thumb may be useful for resolving each of the noted contention situations:
  • Data block contention—Identify and eliminate HOT blocks from the application via changing PCTFREE and or PCTUSED values to reduce the number of rows per data block. Check for repeatedly scanned indexes. Since each transaction updating a block requires a transaction entry, increase the INITRANS value.
     
  • Freelist block contention—Increase the FREELISTS value. Also, when using Parallel Server, be certain that each instance has its own FREELIST GROUPs.
     
  • Segment header contention—Again, increase the number of FREELISTs and use FREELIST GROUPs, which can make a difference even within a single instance.
     
  • Undo header contention—Increase the number of rollback segments.
Mark Bobak notes that buffer busy waits with P3=0 indicate disk I/O contention, indicating the freelists will not improve concurrency:
"buffer busy wait w/ P3=0 means the buffer is locked because the contents are being read from disk by another session. (See MOSC Doc ID 34405.1 for more details.)

This is most likely caused by multiple, concurrent sessions that are reading the same table or set of tables. In my experience, it's most often due to multiple, concurrent queries doing full table scans on the same table.

Since this a read concurrency problem, changing freelists will NOT help."
 In these cases, buffering-up the tables (e.g. KEEP pool), or using faster storage (SSD) can remove this disk enqueue wait evsnts.
Rewards

The identification and resolution of buffer busy waits can be very complex and confusing. Oracle provides the v$segment_statistics view to help monitor buffer busy waits, and the v$system_event views to identify the specific blocks for the buffer busy wait. While identifying and correcting the causes of buffer busy waits is not an intuitive process, the results of your efforts can be quite rewarding.



 http://allappsdba.blogspot.tw/2012/04/troubleshooting-buffer-busy-waits.html

Troubleshooting BUFFER BUSY WAITS

Note:
This wait indicates that there are some buffers in the buffer cache that multiple processes are attempting to access concurrently. Query V$WAITSTAT for the wait statistics for each class of buffer. Common buffer classes that have buffer busy waits include data block, segment header, undo header, and undo block.
BUFFER BUSY WAITS COUNT ON DATABASE:
set pagesize 5000
set lines 180
set long 5000
col username for a15
col osuser for a15
col program for a20
col "LOGON_TIME" for a23
col status for a8
col machine for a15
col SQL_TEXT for a90
col EVENT for a50
col P1TEXT for a10
col P2TEXT for a10
col P3TEXT for a10
col p1 for 9999999999999
col p2 for 9999999999999
col p3 for 9999999999999
col "LAST_CALL_HRS" for 99999.999
select event,count(event) "BUFFER_BUSY_WAITS/LOCK_COUNT" from v$session_wait having count(event)>= 1 and event like '%buffer busy waits%' group by event;
BUFFER_BUSY_WAITS SESSIONS DETAIL:
col event for a10
select s.sid,username,osuser,program,machine,status,to_char(logon_time,'DD-MON-YYYY HH24:MI:SS') "LOGON_TIME",last_call_et/3600 "LAST_CALL_HRS",sw.event from
v$session s,v$session_wait sw where s.sid=sw.sid and sw.event like '%buffer busy waits%';
SQL_TEXT OF BUFFER_BUSY_WAITS SESSIONS:
col "EVENT" for a25
select s.sid,username "USERNAME",sql_text "SQL_TEXT",sw.event "EVENT" from v$session s,v$session_wait sw,v$sqltext sq where s.sid=sw.sid and
sq.address = s.sql_address and sw.event like '%buffer busy waits% order by sw.sid,piece';
TYPE_OF_SEGMENT_CONTENDED_FOR
SELECT class, count FROM V$WAITSTAT WHERE count > 0 ORDER BY count DESC;
USE THE BELOW SQL_FILE TO IDENTIFY THE SEGMENT
set linesize 150
set pagesize 5000
col owner for a15
col segment_name for a30
SELECT owner,segment_name,segment_type FROM dba_extents WHERE file_id=&file AND &block_id BETWEEN block_id AND block_id + blocks -1 ;