数据库程序员面试分类真题21_第1页
数据库程序员面试分类真题21_第2页
数据库程序员面试分类真题21_第3页
数据库程序员面试分类真题21_第4页
数据库程序员面试分类真题21_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据库程序员面试分类真题21简答题1.

如何迁移SYS.AUD$表到其他表空间?正确答案:在日常的数据库维护中,经常出现SYSTEM表空间被撑满,在绝大多数情况下是因为数据库登录审计的功能被启动了(江南博哥),此时一般建议把SYS.AUD$相关对象迁移到其他表空间,从而避免SYSTEM被用完的风险。

在Oracle11g之前迁移方法如下:

ALTERTABLESYS.AUDIT$MOVETABLESPACEUSERS;

ALTERTABLESYS.AUDIT_ACTIONSMOVETABLESPACEUSERS;

ALTERTABLESYS.AUD$MOVETABLESPACEUSERS;

ALTERTABLESYS.AUD$MOVELOB(SQLBIND)STOREASSYS_IL0000000384C00041$$(TABLESPACEUSERS);

ALTERTABLESYS.AUD$MOVELOB(SQLTEXT)STOREASSYS_IL0000000384C00041$$(TABLESPACEUSERS);

ALTERINDEXSYS.I_AUDITREBUILDONLINETABLESPACEUSERS;

ALTERINDEXSYS.I_AUDIT_ACTIONSREBUILDONLINETABLESPACEUSERS;

从Oracle11g开始可以使用DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION进行迁移:

EXECDBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(AUDIT_TRAIL_TYPE=>DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,AUDIT_TRAIL_LOCATION_VALUE=>'USERS');

如下示例为授予审计的一些权限:

GRANTAUDITANYTOLHR_TEST;

GRANTAUDITSYSTEMTOLHR_TEST;

在Oracle11g之前通过手工清理的方式或自定义作业来定期清理SYS.AUD$表,如下:

TRUNCATEFROMSYS.AUD$;

DELETEFROMSYS.AUD$WHEREOBJ$NAME='EMP';[考点]审计

2.

如何正确地清理SYS.AUD$表?正确答案:如果AUD$表过大,那么直接TRUNCATEAUD$表,系统要立即释放大量的EXTENTS,会严重影响系统性能。可以通过如下2个步骤逐步释放EXTENTS。

1)清空数据并且保留原来的EXTENTS:

TRUNCATETABLESYS.AUD$REUSESTORAGE;

在这里,REUSESTORAGE是TRUNCATE的一个参数,表示保持原来的存储不变。一般情况下,SQL命令“TRUNCATETABLETABLE_NAME;”其实就是“TRUNCATETABLETABLE_NAMEDROPSTORAGE;”。DROPSTORAGE是TRUNCATETABLE的默认参数。

2)逐步回缩EXTENTS:

ALTERTABLESYS.AUD$DEALLOCATEUNUSEDKEEP5000M;

ALTERTABLESYS.AUD$DEALLOCATEUNUSEDKEEP2000M;

......

ALTERTABLESYS.AUD$DEALLOCATEUNUSEDKEEP10M;

需要注意的是,在执行的时候,可以根据实际情况调整每次回缩空间的大小。

若审计在OS和XML选项下进行手动删除审计文件。在Oracle11g中通过DBMS_AUDIT_MGMT包下的子过程进行手动或定期清理。[考点]审计

3.

审计有哪些类型?正确答案:Oracle中审计总体上可分为“标准审计”和“细粒度审计”,后者也称为“基于政策的审计”,在Oracle10g之后功能得到很大增强。其中,标准审计可分为用户级审计和系统级审计。用户级审计是任何Oracle用户都可设置的审计,主要是用户针对自己创建的数据库表或视图进行审计,记录所有用户对这些表或视图的一切成功和(或)不成功的访问以及各种类型的SQL操作。系统级审计只能由DBA设置,用以监测成功或失败的登录要求、监测GRANT和REVOKE操作以及其他数据库级权限下的操作。

在Oracle中分别支持以下三种标准审计类型,或者说,可以从3个角度去启用审计:

1)语句审计(StatementAuditing),对某种类型的SQL语句审计,不指定结构或对象。审计SQL语句的成功执行或不成功执行。这里从SQL语句的角度出发,进行指定。审计只关心执行的语句。例如,AUDITCREATETABLE语句,其中,AUDIT为使用审计的关键字。该语句表示对CREATETABLE语句的执行进行记录,不管这条语句是否为针对某个对象的操作。

2)权限审计(PrivilegeAuditing),对执行相应动作的系统特权的使用审计,对涉及某些权限的操作进行审计,这里强调“系统权限”,例如,“AUDITCREATETABLE;”命令,可以表咀对涉及“CREATETABLE”权限的操作进行审计。所以,在这种命令的情况下,既产生一个语句审计,又产生了一个权限审计。有时候语句审计和权限审计是相互重复的。

3)对象审计(ObjectAuditing),对一特殊模式对象上的指定对象的审计。对一个特殊模式对象上的DML语句进行审计。记录作用在指定对象上的操作。例如,AUDITSELECTONSCOTT.DEPT语句,表示指定SCOTT用户的DEPT表,审计对其进行的SELECT语句。

[考点]审计

4.

审计中BYACCESS和BYSESSION的区别是什么?正确答案:BYACCESS表示每一个被审计的操作都会生成一条AUDITTRAIL,而BYSESSION表示一个会话里面同类型的操作只会生成一条AUDITTRAIL,默认为BYSESSION。[考点]审计

5.

什么是细粒度审计?正确答案:从Oracle9i开始,引入了细粒度的对象审计,使得审计变得更为关注某个方面,并且更为精确。细粒度的审计可以在访问某些行和列时审计对表的访问,从而极大地减少审计表的记录数量。使用标准的审计,可以发现访问了哪些对象,以及由谁访问,但是无法知道访问了哪些行或列。细粒度审计被称为FGA(Fine-GrainedAudit),由DBMS_FGA的PL/SQL程序来实现。[考点]审计

6.

如何查看某一个会话是否被其他会话阻塞?正确答案:SQL语句如下:

SELECTABLOCKING_SESSION_STATUS,ABLOCKING_INSTANCE,ABLOCKING_SESSION,A.EVENTFROMGV$SESSIONAWHEREA.SID=1070;

由上图可知,1070会话被2号实例上的970会话阻塞。[考点]会话

7.

如何查到会话正在执行的SQL语句?正确答案:SQL语句如下:

SELECTB.SQL_ID,B.SQL_TEXTFROMGV$SESSIONA,GV$SQLBWHEREA.SQL_ID=B.SQL_IDANDA.INST_ID=B.INST_IDANDA.SID=1070;

通过SQL_ID这个字段,可以获取到某个会话正在执行的SQL语句。[考点]会话

8.

如何彻底杀掉会话?V$SESSION的STATUS为KILLED的情况下如何找到相关的后台OS进程?正确答案:一般情况下,可以通过执行SQL语句“ALTERSYSTEMKILLSESSION'SID,SERIAL#'”直接杀掉会话,当SESSION是ACTIVE的时候,ALTERSYSTEMKILLSESSION只是将SESSION的状态标识为KILLED,SERVER变为PSEUDO状态,但并不会释放SESSION持有的资源,所以,在执行完ALTERSYSTEMKILLSESSION后,会话还是一直存在。执行命令KILLSESSION的时候,后边加上IMMEDIATE,这样在没有事务的情况下,相关会话就会立即释放而不会变为KILLED的状态;当有事务存在的情况下,会先进行回滚相关的事务,然后释放会话所占有的资源。

另外,由于变为KILLED状态的会话的PADDR列都变成了另外一个值,因此,通过平常的连接方式就没有办法关联到后台进程,在Oracle11g下提供了CREATOR_ADDR列,该列可以关联到后台进程,对于Oracle10g可以通过特殊的SQL找到后台的进程号。

Oracle10g可以使用如下的脚本:

SEEECTINST_ID,SPID,PROGRAM,'KILL-9'||SPIDKILL9FROMGV$PROCESSA

WHEREPROGRAM!='PSEUDO'

AND(INST_ID,ADDR)NOTIN(SELECTINST_ID,PADDRFROMGV$SESSION)

AND(INST_ID,ADDR)NOTIN(SELECTINST_ID,PADDRFROMGV$BGPROCESS)

AND(iNST_ID,ADDR)NOTIN(SELECTINST_ID,PADDRFROMGV$SHARED_SERVER);

Oracle11g可以使用如下的脚本:

SELECTA.INST_ID,A.SID||','||A.SERIAL#||','||(SELECTSPIDFROMGV$PROCESSBWHEREB.INST_ID=A.INST_ID

ANDA.CREATOR_ADDR=B.ADDR--ANDDECODE(A.STATUS,'KILLED',A.CREATOR_ADDR,A.PADDR)=B.ADDR)SESSIONID,

A.PADDR,A.STATUS,A.PROGRAM,

ALTERSYSTEMDISCONNECTSESSION'''||SID||','||SERIAL#||'''IMMEDIATE;'KILL_SESSION

FROMGV$SESSIONAWHEREA.USERNAME='SYS'ANDA.STATUS='KILLED';[考点]会话

9.

如何让普通用户可以杀掉自己用户的会话?正确答案:普通用户想要杀掉会话必须要具有ALTERSYSTEM的权限,但是由于该权限过大,用户可能使用该权限错杀其他用户的会话,所以,有没有其他办法可以实现该功能呢?该类问题也是DBA工作中常遇到的问题,下面给出一种解决方案。

首先,可以创建一个查询自己会话信息的视图,将该视图创建公共同义词,然后创建一个存储过程,该存储过程实现杀掉会话的需要,最后将该存储过程的执行权限赋给PUBLIC即可解决这个问题。[考点]会话

10.

SESSIONS和PROCESSES有什么关系?正确答案:在数据库安装完成后,常常需要设置SESSIONS和PROCESSES的大小。其中,SESSIONS指定了一个实例中允许的会话数,即能同时登录到数据库的并发用户数;PROCESSES指定了一个实例在操作系统级别能同时运行的进程数,包括后台进程与服务器进程。由于一个后台进程可能同时对应多个会话,所以,通常SESSIONS的值大于PROCESSES的值。

通过查找官方文档,可以知道SESSIONS参数的值在Oracle10g和11g中是不同的,见下表。属性Oracle10gOracle11gR2参数值的类型IntegerInteger默认值Derived:(1.1*PROCESSES)+5Derived:(1.5*PROCESSES)+22是否可以动态修改否否范围1~2311~216(即1~65536)注:在Oracle11gR1中,该参数值和10g足一样的,修改语句为“ALTERSYSTEMSETPROCESSES|SESSIONS=200SCOPE=SPFILE;”。

由于SESSIONS的值是根据PROCESSES的值计算得到的,所以,一般情况下只需要设置PROCESSES的值即可。在Oracle11gR2以下版本中,SESSIONS大小的计算公式为(1.1*PROCESSES)+5;在Oracle11gR2中,SESSIONS大小的计算公式为(1.5*PROCESSES)+22。若SESSIONS的当前值比计算值大,则SESSIONS的值可能保持不变;若SESSIONS的当前值比计算值小,则SESSIONS取计算值,即SESSIONS的值总是取MAX(当前值,计算值),但是这个也不是绝对的。

当数据库连接的并发用户已经达到SESSIONS的值时,又有新会话连接进来,就会报错:“ORA-00018,"maximumnumberofsessionsexceeded"”。

当Oracle需要启动新的PROCESS,而当前的进程数又已经达到PROCESSES参数时,就会报错:“ORA-00020:maximumnumberofprocesses(2048)exceeded”。

如果数据库上连接被占用完,当新的连接过来时,那么就会在客户端产生“ORA-12519,TNS:noappropriateservicehandlerfound”的报错信息。[考点]会话

11.

如何根据OS进程快速获得DB进程信息与正在执行的语句?正确答案:在OS上执行top命令之后就可以得到OS进程号,有了OS进程号后,就可以在数据库中直接查询:

SELECTB.SID,B.SERIAL#,C.SPID,B.SQL_IDFROMV$SESSIONB,V$PROCESSCWHEREB.PADDR=C.ADDRANDC.SPID=XXXX;[考点]会话

12.

怎么杀掉特定的数据库会话?正确答案:“ALTERSYSTEMKILLSESSION'SID,SERIAL#'IMMEDIATE;”或者“ALTERSYSTEMDISCONNECTSESSION'SID,SERIAL#'IMMEDIATE;”。

在Windows上还可以采用Oracle提供的orakill杀掉一个线程(其实就是一个Oracle进程)。在Linux上,可以直接利用kill-9杀掉数据库进程对应的OS进程。[考点]会话

13.

如何快速地清理Oracle的进程?正确答案:若想要快速清理掉Oracle的进程,最直接的办法是杀pmon进程。有如下3条命令可供选择,其中加粗的orcl替换成ORACLE_SID的值即可。

kill-9'ps-ef|greporcl|grep-vgrep|awk'{print$2}''

ps-ef|greporcl|grep-vgrep|awk'{print$2}'|xargskill-9

ipcs-m|greporacle|awk'{print$2}'|xargsipcrmshm

若想要快速杀掉集群的进程,则可以执行如下命令:

km-9'ps-ef|grepd.bin|grep-vgrep|awk'{print$2}''

注意,生产库上严禁使用,否则可能导致集群不能正常启动。[考点]会话

14.

等待事件有哪些分类?正确答案:Oracle的等待事件主要可以分为两类:空闲(Idle)等待事件和非空闲(Non-Idle)等待事件。

1)空闲等待事件指Oracle正等待某种工作,在诊断和优化数据库的时候,不用过多注意这部分事件。

2)非空闲等待事件专门针对Oracle的活动,指数据库任务或应用运行过程中发生的等待,这些等待事件是在调整数据库的时候需要关注与研究的。

通过如下的SQL语句可以查询等待事件的类型:

SELECTWAIT_CLASS#,WAIT_CLASS_ID,WAIT_CLASS,COUNT(*)AS"COUNT"FROM

V$EVENT_NAME

GROUPBYWAIT_CLASS#,WAIT_CLASS_ID,WAIT_CLASSORDERBYWAIT_CLASS#;[考点]等待事件

15.

什么是AdaptiveLogFileSync?正确答案:当前台进程提交事务(COMMIT)后,LGWR需要执行日志写出操作,而前台进程因此进入logfilesync等待。

在Oracle11g之前的版本中,LGWR执行写入操作完成后,会通知前台进程,这就是Post/Wait模式;在Oracle11gR2中,为了优化这个过程,前台进程通知LGWR写之后,可以通过定时获取的方式来查询写出进度,这被称为Polling模式。在Oracle中,这个特性被默认开启,通过隐含参数“_use_adaptive_log_file_sync”来控制(默认值为true),这个参数的含义是,数据库可以自适应地在Post/Wait和Polling模式间选择和切换。正是由于这个原因,带来了很多Bug,反而使得logfilesync的等待异常得高。因此,如果在Oracle版本中观察到这样的特征,那么就极有可能与此特性的Bug有关。

在Post/Wait和Polling机制之间的切换,Oracle会记录到LGWR进程的trace中,如下:

Logfilesyncswitchingtopolling

......

Logfilesyncswitchingtopost/wait

若遇到此问题,则通常将隐含参数“_use_adaptive_log_file_sync”设置为false,回归到以前的Post/Wait模式,这将会有助于问题的解决。关闭Polling模式的命令为

altersystemset"_use_adaptive_log_file_sync"=falsesid='*';[考点]等待事件

16.

请列举一次你曾经处理过的故障。正确答案:没有唯一答案,读者根据自己的维护经验讲解即可,下面给出一个作者曾经处理过的故障诊断案例。

1.故障环境项目sourcedbdb类型RACdbversion.0db存储ASMOS版本及kernel版本AIX64位2.故障发生现象及报错信息有一套数据库做测试的时候,CPU利用率很高,当时抓取了CPU和AWR的信息。发生问题的时间段是19~23点,其中,nmon数据截图如下图所示。可以看到CPU的利用率是非常高的,下边来看看AWR中的数据。从等待事件中可以很明显地看出,“enq:SQ-contention”和“DFSlockhandle”这两个等待事件异常。“Top5TimedEvents”部分也是AWR报告中非常重要的部分,从这里可以看出等待事件中排在前五位的是哪些事件,从而基本上就可以判断出性能瓶颈在什么地方。在这里,“enq:SQ-contention”等待了172254次,等待时间为69652s,平均等待时间为69652/172254s=404ms,等待类别为Configuration即配置上的等待问题。3.有关序列等待的基础知识根据AWR报告的内容基本可以断定,只要解决了“enq:SQ-contention”和“DFSlockhandle”这两个等待事件即可解决问题。其实,“enq:SQ-contention”“rowcachelock”“DFSlockhandle”和“enq:SV-contention”这4个等待事件都与Oracle的序列有关,如下:SELECT*FROMV$EVENT_NAMEWHERENAMEIN('rowcachelock';'enq:SQ-contention','DFSlockhandle','enq:SV-contention');其中,PAREMETER1的值为“name|mode”或“type|mode”的事件为队列等待。在这类等待事件中,name代表队列的名称,type代表队列的类型,mode代表队列的模式。使用如下的SQL可以查询到锁的名称和请求的mode值:SELECTCHR(BITAND(P1,-16777216)/16777215)||CHR(BITAND(P1,16711680)/65535)"LOCK",BITAND(P1,65535)"MODE"FROMV$SESSION_WAITWHEREEVENTIN('enq:SQ-contention','DFSlockhandle','enq:SV-contention');其中,MODE值见下表。模式代码解释1NullMode2Sub-Shoe3Sub-Exclusive4Share5Share/Sub-Exclusive6Exclusive使用如下的SQL可以查询SQ和SV这两种锁的解释:SELECT*FROMV$LOCK_TYPEDWHERED.TYPEIN('SV','SQ');事实上,Oracle为了管理序列使用了如下表所示的三种锁。锁rowcachelockSQ锁(SequenceCache)SV锁(SequenceOrdering)产生的条件NOCACHECACHE+NOORDER或CACHE+ORDER(单实例)CACHE+ORDER(RAC)拥有的锁模式6-X(Exclusive)6-X(Exclusive)5-SSX(Share/Sub-Exclusive)表现出的等待事件rowcachelockenq:SQ-contentionOracle10g表现为DFSlockhandle,而Oracle11g中表现为enq:SV-contention简介在赋予了NOCACHE属性的序列上,在调用SEQUNECE.NEXTVAL过程中,将数据字典信息进行物理修改时拥有该锁,等待事件表现为rowcachelock赋予了CACHE属性的序列调刖NEXTVAL期间,应该以SSX模式获得SQ锁。若许多会话同时为了获取SQ锁而发生争用,则等待enq:SQ-contention事件在RAC上节点之间顺序得到保障的情况下,调用SEQUENCE.NEXTVAL期间拥有该锁。在RAC环境中,赋予CACHE+ORDER属性的序列上发生,在Oracle10g表现为DFSlockhandle,而在Oracle11g中表现为enq:SV-contention。解决办法:尽量设置为NOORDER并增大其CACHE值参数含义P1代表V$ROWCACHE中的CACHE#P1可以查询到锁的名称和请求的MODE值。P2值是序列的OBJECT_ID。因此,若利用P2值与DBA_OBJECTS的结合,就可以知道对哪个序列发生了等待现象P1可以查询到锁的名称和请求的MODE值解决办法尽量设置为NOORDER属性并增大其CACHE值,一般情况下可以增大到1000

在RAC上创建序列时,在赋予了CACHE属性的状态下,若没有赋予ORDER属性,则各节点将会把不同范围的序列值CACHE到内存上。比如,在拥有两个节点的RAC环境下,创建CACHE值为100的序列,则节点1使用1~100,节点2使用101~200。若两个节点之间都通过递增方式使用序列,则必须赋予ORDER属性。Oracle序列默认是NOORDER,如果设置为ORDER,那么在单实例环境没有影响,在RAC环境中,多实例实际缓存相同的序列,此时在多个实例并发取该序列的时候,会有短暂的资源竞争来在多实例之间进行同步。因此,性能相比NOORDER要差,所以RAC环境非必须的情况下不要使用ORDER,尤其要避免NOCACHEORDER组合。

有一点必须要注意,当没有赋予CACHE属性时,不管ORDER属性使用与否或RAC环境与否,一直等待rowcachelock事件。rowcachelock是可以在全局范围内使用的锁,单实例环境或多实例环境同样可以发生。如果使用了CACHE,而此时DB崩溃了,那么序列会从CACHE值之后重新开始,在CACHE中没有使用的序列会被跳过,这样就会导致序列不连续。在创建序列时,CACHE的默认值设定为较小的20。因此创建并发量多的序列时,CACHE值应该取1000以上的较大值。

另外,若一次性同时创建许多会话时,有时会发生enq:SQ-contention等待事件。其原因是V$SESSION.AUDSID列值是利用序列创建的。Oracle在创建新的会话后,利用名为SYS.AUDSES$的序列的NEXTVAL来创建AUDSID值。在Oracle10g下SYS.AUDSES$的CACHE值默认为20,但在Oracle11g下SYS.AUDSES$的CACHE值默认为10000,通过如下的SQL可以查询:

SELECT*FROMDBA_SEQUENCESDWHERED.SEQUENCE_NAME='AUDSES$';

4.故障解决过程

首先查洵出现问题时间段的ASH视图DBA_HIST_ACTIVE_SESS_HISTORY,通过该视图可以找到需要的序列名称。可以有多种查询方法:

SELECTD.SQL_ID,COUNT(1)FROMDBA_HISL_ACTIVE_SESS_HISTORYD

WHERED.SAMPLE_TIMEBETWEENTO_DATE('20160823170000','YYYYMMDDHH24MISS')AND

TO_DATE('20160823230000','YYYYMMDDHH24MISS')

ANDD.EVENT=enq:SQ-contention'GROUPBYD.SQL_ID;

可以看到SQL_ID为3jhvjgj7kbpmt的SQL最多,查看具体SQL内容:

SELECT*FROMV$SQLAWHEREA.SQL_IDIN('3jhvjgj7kbpmt');

由此可以知道,产生等待的序列名称为ONLNID,另外,也可以从DBA_HIST_ACTIVE_SESS_HISTORY视图的P2值获取到序列的名称,SQL语句如下:

SELECTD.EVENT,D.P1TEXLD.P1,D.P2TEXLD.P2,

CHR(BITAND(P1,-16777216)/16777215)||

CHR(BITAND(P1,16711680)/65535)"Lock",

BITAND(P1,65535)"Mode",D.BLOCKlNG_SESSION,D.BLOCKING_SESSION_STATUS,D.BLOCKING_SESSION_SERIAL#,

D.SQL_ID,TO_CHAR(D.SAMPLE_TIME,'YYYYMMDDHH24MISS')SAMPLE_TIME,D.*

FROMDBA_HIST_ACTIVE_SESS_HISTORYD

WHERED.SAMPLE_TIMEBETWEENTO_DATE('20160823170000','YYYYMMDDHH24MISS')AND

TO_DATE('20160823230000','YYYYMMDDHH24MISS')

ANDD.EVENT='enq:SQ-contention';

由以上的查询结果可知,序列的OBJECT_ID为47989,通过DBA_OBJECTS就可以查询到序列的名称了。另外,LOCK为SQ代表的是序列的CACHE锁(SEQUENCECACHE),MODE为6代表EXCLUSIVE排它锁。

SELECT*FROMDBA_OBJECTSDWHERED.object_id='47989';

知道了序列名称后,通过DBA_SEQUENCES视图就可以查询到序列的属性了:

SELECT*FROMDBA_SEQUENCESDWHERED.sequence_name='ONLNID';

可以看到,该序列是NOORDER属性,CACHE值为默认的20,对于并发值很高的系统而言,该默认值太低,所以需要调整到1000。可以执行SQL语句“ALTERSEQUENCEONLNlDCACHE1000;”调整其CACHE值即可解决该问题。[考点]等待事件

17.

ROWID和ROWNUM有什么区别?正确答案:Oracle有两个著名的伪列ROWID和ROWNUM,下面分别来介绍。

1.ROWID

ROWID是一个伪列,既然是伪列,那么这个列就不是用户定义,而是系统自己给加上的。对每个表都有一个ROWID的伪列,但是表中并不物理存储ROWID列的值。不过可以像使用其他列那样使用它,但是不能删除该列,也不能对该列的值进行修改、插入。

ROWID对访问一个表中的给定的行提供了最快的访问方法,通过ROWID可以直接定位到相应的数据块上,然后将其读到内存。当创建一个索引时,该索引不但存储索引列的值,而且也存储索引值所对应的行的ROWID,这样通过索引就可以快速找到相应行的ROWID,通过该ROWID,就可以迅速将数据查询出来。这也就是在使用索引查询时,速度比较快的原因。

一般来说,当表中的行确定后,ROWID就不会发生变化,一旦一行数据插入数据库,ROWID在该行的生命周期内是唯一的,即使该行产生行迁移,行的ROWID也不会改变,UPDATE不会改变ROWID,INSERT更不会。从ROWID定义可知,只有当数据行的物理位置改变时才会导致ROWID改变,所以,只需要关心那些会导致数据物理位置变化的操作即可。

ROWID可以分为以下几种类型:

1)物理ROWID:存储堆组织表、表簇、表分区和索引分区中的行地址。

2)逻辑ROWID:存储索引组织表中的行地址。

3)外部ROWID:是外来表(如通过网关访问的DB2表)中的标识符。它们不是标准的Oracle数据库ROWID。

有一种数据类型称为通用ROWID或UROWID,支持各种ROWID。

当如下情况发生时,ROWID将发生改变,即当数据迁移到其他块的时候,ROWID就会改变:

1)对一个表做表空间的移动或重建后。

2)对一个表进行了exp/imp或expdp/impdp后。

3)MOVE、FLASHBACKTABLE、修改分区键值到另一个分区、分区表的分区数据转移到其他分区、SHRINKTABLE等。

通过DBMS_ROWID可以获取文件号、块号等信息,如下:

2.ROWNUM

ROWNUM是一个伪列,不是真正的列,在表中并不真实存在,它是Oracle数据库从数据文件或缓冲区中读取数据的顺序。切勿理解成记录的行号(这是很多人一直这样认为的),例如想查询第二行记录,按下面的方法是查询不到的:

SELECT*FROMSCOTT.TABLE_LHRWHEREROWNUM=2;

ROWNUM主要应用于Top-N查询中。[考点]性能诊断

18.

Oracle健康检查有哪些方面?正确答案:要想对数据库进行全面检查,内容比较多,下面列举部分检查项目:

1)数据库的实例是否运行,最近是否有自动重启现象。

2)ASM实例是否正常运行,剩余ASM磁盘空间有多大。

3)数据库的参数是否正常,数据库的参数近期是否被修改过。

4)数据库的表空间大小,是否有表空间快满了,表空间增长是否过快(系统表空间是否增长过快)。

5)是否有业务表创建在了SYSTEM表空间上,审计表是否在SYSTEM表空间上。

6)RMAN备份是否过期,备份是否可用,是否有控制文件的备份。

7)数据库JOB是否有运行错误。

8)数据库的告警日志是否有异常告警,例如ORA-4030、ORA-4031、ORA-60、ORA-600、ORA-01555等。

9)数据库归档空间、闪回恢复区是否足够。

10)是否有非常耗费资源的SQL曾经运行过,系统是否有VERSIONCOUNT过高的SQL。

11)DG、OGG是否运行正常,归档日志是否正常传递到TARGET端。

12)数据库是否开启了审计?

13)数据库有哪些普通索引、分区索引是失效的,系统是否有很大的索引从未使用过。

14)系统有哪些大表没有进行分区,哪些分区表的分区数过多,哪些分区表的各分区大小严重不均匀。

15)系统有哪些外键没有创建索引,系统组合索引列个数过多。

16)系统有哪些表使用了过时字段,例如LONG、CHAR。

17)系统有哪些表上创建的索引数过多。

18)系统拥有DBA角色的用户是否有变动。

19)近期是否有用户频繁使用错误密码进行登录系统。

20)表或索引是否含有很高的并行度。

21)系统是否含有无效的触发器。

22)系统是否含有CACHE值小于20并且已经产生等待的序列。

23)系统近期是否含有异常的等待事件。

24)系统是否含有登录时间很长却没有响应的会话。

25)系统是否含有统计信息过旧或从未收集过统计信息的表和索引。

26)系统有哪些全局临时表被收集了统计信息。

27)系统自动收集统计信息的JOB是否被禁用。

28)系统AWR、ASH功能是否被禁用。[考点]性能诊断

19.

在高并发、高负载的情况下,如何给表添加字段并设置DEFAULT值?正确答案:当Oracle表数据量上亿时,对表执行“ALTERTABLEXXXADDCOLUMN_XXVARCHAR2(2)DEFAULT'XXXt';”操作时,效率及安全性是必须要考虑的因素。若直接执行,则会在该过程中给表加上6级表锁,也就是连查询都需要等待,这在生产库上是相当危险的操作。因为Oracle在执行上述操作过程中,不仅要更新数据字典,还会刷新全部的记录,并且会使得Undo表空间暴涨,所以,正确的做法是将更新数据字典和更新字段值分开。

例如,表LKILL.T_KILL约有4500W的数据,直接添加一个字段C_LHR需要花费21min,如下:

修改为如下的方式,可以显著提高这个操作的性能,但表中原有的记录对于新添加的列为空,新增记录默认值会设置为LHR,那么原有记录的默认值就需要在系统空闲的时候进行批量更新、批量提交或采用系统包DBMS_PARALLEL_EXECUTE来更新,这样不至于大批量锁表。

[考点]性能诊断

20.

你们公司的数据库有多大?大一点的表有多大?有多少行?正确答案:对于数据库的大小,需要注意的问题是数据库的大小不能以表空间的分配大小而论,而应该以表空间的占用空间大小而论,并且需要减掉SYSTEM、SYSAUX、TEMP和Undo这些表空间占用的空间。因为有的系统Undo空间可能分配得很大,比如500GB,所以,计算数据库大小的时候应该排除这些表空间。

对于表空间大小,若有如下的结果:

可以说数据库大约有(2205-751-629-14-2)MB=809MB,而并非是2.2GB。

至于大一点的表有多大?有多少行?这个问题考查DBA对自己库的熟悉程度,通过下面的SQL语句可以查询一个表的大小:

可以看到最大的表是LKILL用户下的T_KILL表,大约7GB,约有4400W条的数据量,读者应该以自己实际管理的库为准。[考点]性能诊断

21.

如何监控数据库中的非常耗费性能SQL语句?正确答案:由于V$SQL_MONITOR和VSSQL_PLAN_MONITOR收集的信息每秒刷新一次,接近实时。当SQL执行完毕,信息并不会立即从V$SQL_MONITOR中删除,至少会保留1min。所以,根据这两个视图的数据来源及保留策略,可以写一个轻量级的JOB来针对性地监控这两个视图,从而可以实现:执行时间超过N小时、笛卡儿积SQL监控、分区表全分区扫描、SQL执行次数、解析次数过大、占用CPU过大等类型的SQL监控。至于消耗小于5s的CPU或I/O时间的SQL语句一般都是非常高效的,所以不用监控。

考虑到定时任务对Oracle数据库性能的影响,所以,可以通过Oracle的轻量级JOB来实现。Oracle的JOB分为一般性的JOB和轻量级的JOB(LightweightJobs)。使用轻量级的JOB可以提高JOB的性能,因为轻量级JOB适合于在短时间内执行非常频繁的JOB。

若想直接查询数据库耗费性能的SQL语句,可以直接使用视图VW_SQL_PP_LHR进行查询。若想查询历史记录,则可以通过表XB_SQL_MONITOR_PP_LHR来查询。另外,对于监控中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论