1.2.5 X$KSMSP视图 Shared Pool 的空间分配和使用情况,可以通过一个内部视图来观察,这个视图就是X$KSMSP。 X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]其中每一行都代表着Shared Pool中的一个Chunk。以下是x$ksmsp的结构:
1.2.5 X$KSMSP视图
Shared Pool 的空间分配和使用情况,可以通过一个内部视图来观察,这个视图就是X$KSMSP。
X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]其中每一行都代表着Shared Pool中的一个Chunk。以下是x$ksmsp的结构:
12:03:45 sys@felix SQL>desc x$ksmsp
Name Null? Type
---------------------------- -------------------------
ADDR RAW(8)
INDX NUMBER
INST_ID NUMBER
KSMCHIDX NUMBER
KSMCHDUR NUMBER
KSMCHCOM VARCHAR2(16)
KSMCHPTR RAW(8)
KSMCHSIZ NUMBER
KSMCHCLS VARCHAR2(8)
KSMCHTYP NUMBER
KSMCHPAR RAW(8)
12:06:29 sys@felix SQL>
这里需要关注一下以下几个字段。
(1)x$ksmsp.ksmchcom是注释字段,每个内存块被分配以后,注释会添加在该字段中。
(2)x$ksmsp.ksmchsiz代表块大小。
(3)x$ksmsp.ksmchcls列代表类型,主要有4类,具体说明如下。
(1)free:即Free Chunks,不包含任何对象的Chunk,可以不受限制的被自由分配。
(2)recr:即Recreatable Chunks,包含可以被临时移出内存的对象,在需要的时候,这个对象可以被重新创建。例如,许多存储共享SQL代码的内存都是可以重建的。
(3)freeable:即Freeable Chunks,包含session周期或调用的对象,随后可以被释放。这部分内存有时候可以全部或部分提前释放。但是注意,由于某些对象是中间过程产生的,这些对象不能临时被移出内存(因为不可重建)。
(4)perm:即Permanent Memory Chunks,包含永久对象,通常不能独立释放
在这个测试数据库中,初始启动数据库,在x$ksmsp视图中存在12623个Chunk:
12:12:54 sys@felix SQL>select count(*) fromx$ksmsp;
COUNT(*)
----------
12623
12:12:56 sys@felix SQL>select count(*) fromdba_objects;
COUNT(*)
----------
75613
此时shared pool中的chunk数量增加
12:13:04 sys@felix SQL>select count(*) fromx$ksmsp;
COUNT(*)
----------
13892
12:13:09 sys@felix SQL>
这就是由于Shared Pool中进行SQL解析,请求空间,进而导致请求free空间分配、分割,从而产生了更多、更细碎的内存Chunk。
由此可以看出,如果数据库系统中存在大量的硬解析,不停请求分配free的Shared Pool内存,除了必需的SharedPool Latch等竞争外,还不可避免地会导致Shared Pool中产生更多的内存碎片(当然,在内存回收时,你可能看到Chunk数量减少的情况)。
继续进行一点深入研究,首先重新启动数据库:
12:13:09 sys@felix SQL>startup force;
ORACLE instance started.
Total System Global Area 417546240 bytes
Fixed Size 2228944 bytes
Variable Size 335547696 bytes
Database Buffers 75497472 bytes
Redo Buffers 4272128 bytes
Database mounted.
Database opened.
12:16:41 sys@felix SQL>
创建一张临时表用以保存之前x$ksmsp的状态:
CREATE GLOBAL TEMPORARY TABLE e$ksmsp ON COMMITPRESERVE ROWS AS
SELECTa.ksmchcom,
SUM(a.CHUNK) CHUNK,
SUM (a.recr) recr,
SUM (a.freeabl) freeabl,
SUM (a.SUM) SUM
FROM (SELECT ksmchcom, COUNT (ksmchcom) CHUNK,
DECODE (ksmchcls, 'recr', SUM (ksmchsiz), NULL)recr,
DECODE (ksmchcls, 'freeabl', SUM (ksmchsiz), NULL)freeabl,
SUM(ksmchsiz) SUM
FROM x$ksmspGROUP BY ksmchcom, ksmchcls) a
where 1 = 0
GROUP BYa.ksmchcom;
保存当前Shared Pool状态:
INSERT INTO E$KSMSP
SELECTa.ksmchcom,
SUM(a.CHUNK) CHUNK,
SUM(a.recr) recr,
SUM(a.freeabl) freeabl,
SUM(a.SUM) SUM
FROM(SELECT ksmchcom,
COUNT(ksmchcom) CHUNK,
DECODE(ksmchcls, 'recr', SUM(ksmchsiz), NULL) recr,
DECODE(ksmchcls, 'freeabl', SUM(ksmchsiz), NULL) freeabl,
SUM(ksmchsiz) SUM
FROM x$ksmsp
GROUPBY ksmchcom, ksmchcls) a
GROUP BYa.ksmchcom /
12:20:31 sys@felix SQL>INSERT INTO E$KSMSP
12:20:50 2 SELECT a.ksmchcom,
12:20:50 3 SUM(a.CHUNK) CHUNK,
12:20:50 4 SUM(a.recr) recr,
12:20:50 5 SUM(a.freeabl)freeabl,
12:20:50 6 SUM(a.SUM) SUM
12:20:50 7 FROM (SELECT ksmchcom,
12:20:50 8 COUNT(ksmchcom) CHUNK,
12:20:50 9 DECODE(ksmchcls, 'recr', SUM(ksmchsiz), NULL) recr,
12:20:50 10 DECODE(ksmchcls, 'freeabl',SUM(ksmchsiz), NULL) freeabl,
12:20:50 11 SUM(ksmchsiz)SUM
12:20:50 12 FROM x$ksmsp
12:20:50 13 GROUP BY ksmchcom,ksmchcls) a
12:20:50 14 GROUP BY a.ksmchcom ;
2788 rows created.
12:20:51 sys@felix SQL>
执行查询:
12:22:30 sys@felix SQL>select count(*) fromdba_objects;
COUNT(*)
----------
75614
13:18:32 sys@felix SQL>
比较查询前后shared pool内存分配的变化:
select a.ksmchcom,
a.chunk,
a.sum,
b.chunk,
b.sum,
(a.chunk - b.chunk) c_diff,
(a.sum - b.sum) s_diff
from(SELECT a.ksmchcom,
SUM(a.CHUNK) CHUNK,
SUM(a.recr) recr,
SUM(a.freeabl) freeabl,
SUM(a.SUM) SUM
FROM (SELECT ksmchcom,
COUNT(ksmchcom) CHUNK,
DECODE(ksmchcls, 'recr',SUM(ksmchsiz), NULL) recr,
DECODE(ksmchcls,'freeabl', SUM(ksmchsiz), NULL) freeabl,
SUM(ksmchsiz) SUM
FROM x$ksmsp
GROUP BY ksmchcom, ksmchcls) a
GROUP BY a.ksmchcom) a,
e$ksmsp b
wherea.ksmchcom = b.ksmchcom
and(a.chunk - b.chunk) 0;
KSMCHCOM CHUNK SUM CHUNK SUM C_DIFF S_DIFF
-------------------------------- -------------------- ---------- ---------- ---------- ----------
KGLS^2a03296c 3 12288 1 4096 2 8192
free memory 200 13585552 164 12075904 36 1509648
KGLH0^522f4e73 5 20480 3 12288 2 8192
KGLS^b9dac7f1 14 57344 3 12288 11 45056
KGLH0^c11a66b1 18 73728 2 8192 16 65536
KGLS^3fc2ae3a 12 49152 3 12288 9 36864
KGLH0^61ffddd0 18 73728 2 8192 16 65536
KGLHD 8965 5486488 6456 3979120 2509 1507368
SQLA^522f4e73 10 40960 5 20480 5 20480
KGLS^18717bf4 7 28672 6 24576 1 4096
KGLS^672109bb 3 12288 1 4096 2 8192
KGLH0^4a1d3fe3 18 73728 2 8192 16 65536
reserved stoppe 76 3648 62 2976 14 672
KGLH0^c165fb75 18 73728 2 8192 16 65536
KGLS^a7a0f1b0 14 57344 3 12288 11 45056
KGLS^470434f8 5 20480 1 4096 4 16384
modification 29 178872 20 123360 9 55512
KGLS^b96975f9 8 32768 1 4096 7 28672
KGLS^6e2f6b00 4 16384 3 12288 1 4096
KGLH0^7eef98e0 3 12288 2 8192 1 4096
KGI Session Sta 28 1840 24 1584 4 256
KGLS^e7c28658 3 12288 1 4096 2 8192
KGLH0^3d645f43 18 73728 2 8192 16 65536
KGLH0^1a8436ae 4 16384 3 12288 1 4096
parameter table 308 623840 264 534720 44 89120
KQR SO 1356 899136 773 536304 583 362832
KGLS^1cb5ff2d 10 40960 2 8192 8 32768
KGLS^cfa770fb 5 20480 1 4096 4 16384
KTC latch subh 23 80472 11 46688 12 33784
kpscad: kpscsco 7 576 6 504 1 72
kdlwss 28 11000 24 9408 4 1592
KGLS^518fa5d0 9 36864 1 4096 8 32768
KQR PO 5887 4067840 2616 2037936 3271 2029904
KGLS^d10c66e2 8 32768 2 8192 6 24576
KKSSP 28 15680 24 13440 4 2240
KGLS^6c13497e 6 24576 1 4096 5 20480
KGLNA 8 7048 5 3720 3 3328
KGLH0^7f01546f 18 73728 2 8192 16 65536
KGLDA 3541 850192 2076 498408 1465 351784
KGLS^ea4fb95d 5 20480 1 4096 4 16384
KGLH0^aaab13e6 18 73728 2 8192 16 65536
parameter handl 28 83328 24 71424 4 11904
42 rows selected.
13:18:43 sys@felix SQL>
12:22:30 sys@felix SQL>
简单分析一下以上结果:首先free memory的大小减少了89228(增加到另外5个组件中),这说明SQL解析存储占用了一定的内存空间;而Chunk从164增加为200,这说明内存碎片增加了,碎片增加是共享池性能下降的开始。
1.2.6 Shared Pool的转储与分析
使用如下命令可以对共享池LibraryCache信息进行转储分析:
ALTER SESSION SET EVENTS'immediate trace name LIBRARY_CACHE level LL';
其中LL代表Level级别,对于9.2.0及以后版本,不同Level含义如下:
(1)Level =1,转储Library Cache统计信息;
(2)Level =2,转储Hash Table概要;
(3)Level =4,转储Library Cache对象,只包含基本信息;
(4)Level =8,转储Library Cache对象,包含详细信息(如child references、pin waiters等);
(5)Level =16,增加heap sizes信息;
(6)Level =32,增加heap信息。
Library Cache由一个Hash表组成,而Hash表是一个由Hash Buckets组成的数组,每个hashBucket都是包含Library Cache Handle的一个双向链表。Library Cache Handle指向Library Cache Object和一个引用列表。Library Cache对象进一步分为依赖表、子表和授权表等。
首先通过以下命令对Library Cache进行转储:
13:18:43 sys@felix SQL>ALTER SESSION SET EVENTS'immediate trace name LIBRARY_CACHE level 4';
Session altered.
13:32:24 sys@felix SQL>
13:39:49 sys@felix SQL>col namespace for a30
13:40:04 sys@felix SQL>select gets,pins,reloads,INVALIDATIONS ,namespace fromv$librarycache;
GETS PINS RELOADS INVALIDATIONS NAMESPACE
---------- ---------- ---------- -------------------------------------------
6802 43040 31 120 SQL AREA
7440 10131 98 0 TABLE/PROCEDURE
1627 2329 0 0 BODY
279 344 0 0 TRIGGER
62 62 0 0 INDEX
233 264 0 0 CLUSTER
88 294 0 0 QUEUE
1 4 0 0 RULESET
17 17 0 0 SUBSCRIPTION
121 216 0 0 EDITION
3 0 0 0 DBLINK
59 0 0 0 OBJECT ID
3530 0 0 0 SCHEMA
1 0 0 0 DBINSTANCE
901 901 0 0 SQL AREA STATS
906 0 0 0 SQL AREA BUILD
16 rows selected.
Oracle 9i中通过新的方式记录Library Cache的使用状况。按不同的Hash Chain Size代表Library Cache中包含不同对象的个数。0表示Free的Bucket,>20表示包含超过20个对象的Bucket的个数。从以上列表中看到,包含一个对象的Buckets有217个,包含0个对象的Buckets有130855个。
重启数据库:
13:40:07 sys@felix SQL>startup force
ORACLE instance started.
Total System Global Area 417546240 bytes
Fixed Size 2228944 bytes
Variable Size 335547696 bytes
Database Buffers 75497472 bytes
Redo Buffers 4272128 bytes
Database mounted.
Database opened.
14:11:24 sys@felixSQL>select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------------------------ ------------------ ---------- ------------ -------------------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.
felix SQL>selectSQL_TEXT,VERSION_COUNT,HASH_VALUE,to_char(HASH_VALUE,'xxxxxxxxxx') HEX,ADDRESS
from v$sqlarea where sql_text like 'select * from%emp%';

select sql_text,
username,
ADDRESS,
HASH_VALUE,
to_char(HASH_VALUE, 'xxxxxxxxxx') HEX_HASH_VALUE,
CHILD_NUMBER,
CHILD_LATCH
from v$sqla, dba_users b
wherea.PARSING_USER_ID = b.user_id
andsql_text like 'select * from %emp%';
这里可以看出V$SQLAREA和V$SQL两个视图的不同之处,V$SQL中为每一条SQL保留一个条目,而V$SQLAREA中根据SQL_TEXT进行GROUP BY,通过version_count计算子指针的个数。
在以上两次查询中,两条SQL 语句因为其代码完全相同,所以其ADDRESS、HASH_VALUE也完全相同。这就意味着,这两条SQL语句在共享池中的存储位置是相同的(尽管其执行计划可能不同),代码得以共享。在SQL解析过程中,Oracle将SQL文本转换为相应的ASCII数值,然后根据数值通过Hash函数计算其HASH_VALUE,再通过HASH_VALUE在Shared Pool中寻找是否存在相同的SQL语句,如果存在则进入下一步骤;如果不存在则尝试获取Shared Pool Latch,请求内存,存储该SQL代码。
注意到以上输出,仅仅是大小写的不同使得原本相同的SQL语句变成了两条“不同的代码”,所以从这里可以看出,SQL的规范编写非常重要。
SQL解析首先要进行的是语法解析,语法无误后进入下一个步骤,进行语义分析,在此步骤中,Oracle需要验证对象是否存在、相关用户是否具有权限、引用的是否是相同的对象。
对于先前的查询,实际上emp表来自不同的用户,那么SQL的执行计划也就不同了(当
然影响SQL执行计划的因素还有很多,包括优化器模式等),通 过 对 象 依 赖 关 系 可 以 看 到 这 个不同:
看一下Library Cache的结构:

Buffer Cache的管理,其中BucketàBHàBuffer的管理方式与以上LibraryCache的管理原理完全类似。
Library Cache Handle可以被看作库缓存对象的概要信息,Handle上存有指针指向LibraryCache Object,Handle中还包含对象名、namespace、时间戳、引用列表、锁定对象及pin对象列表等信息。这里还需要说明的是Handle上的指针指向的是Library Cache Object的Heap 0,库缓存对象可能占用多个内存Heap,Heap 0则记录了控制信息,包括对象类型、对象依赖表、指向其他Heap的指针等。
下图列举了主要Shared Pool对象的具体内存结构组成。
如果以上两个CRSR访问的是同一个对象,那么这两个SQL才会是真的共享。如果SQL虽然是相同的,访问的却是不同用户的数据表,子指针的概念就体现出来了。
接下来的Data Blocks是个重要的部分,每个控制块包含一个heap descriptor,指向相应的heap memory,这个heap memory包含的就是Diana Tree、P-Code、SourceCode、Shared Cursor Context Area等重要数据,也就是通常所说的,解析过的SQL及执行计划树,真正到这里以后SQL才得以共享,也就真正地避免了硬解析。
至于Dictionary Cache信息则可以通过如下命令进行转储:
ALTER SESSION SET EVENTS 'immediate trace namerow_cache level N';
这里的N可以取的值如下:
(1)转储dictionarycache的统计信息;
(2)转储hash表的汇总信息;
(3)转储dictionarycache中的对象的结构信息。
使用Level 1进行转储,转储出来的内容就是V$ROWCACHE中的统计信息

C++中的众数函数详解在统计学中,众数指的是一组数据中出现次数最多的数值。在C++语言中,我们可以通过编写一个众数函数来找到任意一组数据中的众数。众数函数的实现可以采用多种不同的方法,下面将详细介绍其中两种常用的方法。第一种方法是使用哈希表来统计每个数字出现的次数。首先,我们需要定义一个哈希表,将每个数字作为键,出现次数作为值。然后,对于给定的数据集,我们遍

C++中的取余函数详解在C++中,取余运算符(%)用于计算两个数相除的余数。它是一种二元运算符,其操作数可以是任何整数类型(包括char、short、int、long等),也可以是浮点数类型(如float、double)。取余运算符返回的结果与被除数的符号相同。例如,对于整数的取余运算,我们可以使用以下代码来实现:inta=10;intb=3;

Vue.nextTick函数用法详解及在异步更新中的应用在Vue开发中,经常会遇到需要进行异步更新数据的情况,比如在修改DOM后需要立即更新数据或者在数据更新后需要立即进行相关操作。而Vue提供的.nextTick函数就是为了解决这类问题而出现的。本文就会详细介绍Vue.nextTick函数的用法,并结合代码示例来说明它在异步更新中的应用。一、Vue.nex

在Web应用程序中,缓存通常是用来优化性能的重要手段。Django作为一款著名的Web框架,自然也提供了完善的缓存机制来帮助开发者进一步提高应用程序的性能。本文将对Django框架中的缓存机制进行详解,包括缓存的使用场景、建议的缓存策略、缓存的实现方式和使用方法等方面。希望对Django开发者或对缓存机制感兴趣的读者有所帮助。一、缓存的使用场景缓存的使用场景

PHP-FPM是一种常用的PHP进程管理器,用于提供更好的PHP性能和稳定性。然而,在高负载环境下,PHP-FPM的默认配置可能无法满足需求,因此我们需要对其进行调优。本文将详细介绍PHP-FPM的调优方法,并给出一些代码示例。一、增加进程数默认情况下,PHP-FPM只启动少量的进程来处理请求。在高负载环境下,我们可以通过增加进程数来提高PHP-FPM的并发

在PHP开发中,有时我们需要判断某个函数是否可用,这时我们便可以使用function_exists()函数。本文将详细介绍function_exists()函数的用法。一、什么是function_exists()函数?function_exists()函数是PHP自带的一个内置函数,用于判断某个函数是否被定义。该函数返回一个布尔值,如果函数存在返回True,

PHPstrpos()函数用法详解在PHP编程中,字符串处理是非常重要的一部分。PHP通过提供一些内置函数来实现字符串处理。其中,strpos()函数就是PHP中最常用的一个字符串函数之一。该函数的目的是在一个指定的字符串中搜索另一个指定字符串的位置,如果包含则返回这个位置,否则返回false。本文将通过详细分析PHPstrpos()函数的用法,助你更好

Gin框架是目前非常流行的Go语言Web框架之一。作为一个轻量级的框架,Gin提供了丰富的功能和灵活的架构,使得它在Web开发领域中备受欢迎。其中一个特别重要的功能是模板渲染。在本文中,我们将介绍Gin框架的模板渲染功能,并深入了解它的实现原理。一、Gin框架的模板渲染功能Gin框架使用了多种模板渲染引擎来构建Web应用程序。目前,它支持以下几种模板引擎:


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

WebStorm Mac version
Useful JavaScript development tools

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),
