我们知道,在Oracle10g以前,每个用户只能使用一个临时表空间,就是其默认临时表空间。如果用户的排序等操作很频繁,那么在临时表空间上的竞争仍然会激烈,为了减少竞争,我们可以创建多个临时表空间,分布在不同存储设备上,为不同的用户指定不同的临时表空间,以分散和缓解IO压力。
在Oracle10g中,Oracle通过新增加的临时表空间组功能,为我们潜在的实现了类似的功能。
临时表空间组允许将多个临时表空间加入到同一个组中,用户的默认临时表空间可以被指定为该临时表空间组,从而一个用户可以透明的使用多个临时表空间。
需要注意的是,临时表空间组无法显式创建,当第一个临时表空间分配给临时表空间组时该组自动创建,当组内所有临时表空间被移除时该组自动删除。一个临时表空间组至少包含一个临时表空间。
临时表空间组支持以下操作:
1. 临时表空间支持组间移动(如果目标组不存在,则自动创建)
2. 可以将组中的临时表空间从组中移除
3. 可以将目前不属于任何组的临时表空间加入一个组。
接下来让我们通过例子看一下临时表空间组的应用,系统环境为Oracle10.2.0.1,数据库使用的是ASM存储,通过如下命令可以创建一个临时表空间组:
SQL> create temporary tablespace temp1 2 tempfile size 10m tablespace group eyglegrp; Tablespace created. 通过dba_tablespace_groups视图我们可以查询数据库中存在的临时表空间组: SQL> select * from dba_tablespace_groups; GROUP_NAME TABLESPACE_NAME ------------------------------ ------------------------------ EYGLEGRP TEMP1复制
我们可以再向临时表空间组增加临时表空间:
SQL> create temporary tablespace temp2 2 tempfile size 10m tablespace group eyglegrp; Tablespace created. SQL> select * from dba_tablespace_groups; GROUP_NAME TABLESPACE_NAME ------------------------------ ------------------------------ EYGLEGRP TEMP1 EYGLEGRP TEMP2复制
通过dba_temp_files视图我们可以查询数据库中临时表空间及临时文件的归属情况:
SQL> select file_name,tablespace_name from dba_temp_files; FILE_NAME TABLESPACE_NAME --------------------------------------------- ------------------------------ +DATADG/smsboss/tempfile/temp.265.577731597 TEMP +DATADG/smsboss/tempfile/temp1.5416.611335143 TEMP1 +DATADG/smsboss/tempfile/temp2.5415.611335367 TEMP2复制
关于临时表空间组,可能会用到的一些操作还有:
1.移动临时表空间到新的临时表空间组
SQL> alter tablespace temp2 tablespace group eyglegp2; Tablespace altered. SQL> select * from dba_tablespace_groups; GROUP_NAME TABLESPACE_NAME ------------------------------ ------------------------------ EYGLEGRP TEMP1 EYGLEGP2 TEMP2复制
2.将临时表空间从临时表空间组中移出
SQL> alter tablespace temp2 tablespace group ''; Tablespace altered. SQL> select * from dba_tablespace_groups; GROUP_NAME TABLESPACE_NAME ------------------------------ ------------------------------ EYGLEGRP TEMP1复制
3.删除组中所有的临时表空间后,组会自动删除
SQL> select * from dba_tablespace_groups; GROUP_NAME TABLESPACE_NAME ------------------------------ ------------------------------ EYGLEGRP TEMP1 SQL> drop tablespace temp1 including contents and datafiles; Tablespace dropped. SQL> select * from dba_tablespace_groups; no rows selected复制
4.将数据库或者用户的默认临时表空间指定为临时表空间组
SQL> alter user eygle temporary tablespace eyglegrp; User altered.复制
临时表空间组的另外一个好处是,当同一个用户的以不同session连接数据库进行排序等操作时,Oracle可以为这些Session分配不同的临时表空间,在多Session排序的数据环境,我们可以发现类似如下的排序分担:
SQL> select username, session_num, tablespace from v$sort_usage; USERNAME SESSION_NUM TABLESPACE ---------- ----------- ---------- EYGLE 186 TEMP2 EYGLE 200 TEMP1复制
这种分担机制有利于分散负载、缓解IO竞争和压力。
然而在使用数据库的新特性的同时,需要关注的是,新特性可能同时会带来一些新的问题。以下是某用户的核心数据库系统,客户反映这个系统的主要问题是CPU消耗很高,经常处于90%以上运行。我们对数据库AWR采样生成了一个10小时的采样报告(如图1-14所示),这是一个运行于IBM P595之上的Oracle 10.2.0.2版本的RAC集群数据库:
图 AWR生成的10小时采样报告
从报告的DB Time/Elapsed = 8.6,可以获得的整体印象是,数据库处于较为繁忙的运行状态。数据库的负载概要信息(Load Profile)进一步显示,数据库每秒的逻辑读高达857 104.76次,SQL Parses每秒为750.16次,频繁的SQL解析和User Calls是CPU消耗的另外一方面的体现:
图 负载概要信息
为了了解SQL分析调用的信息,我们可以进一步来查看SQL Statistics 部分的Parse Calls模块内容,在这部分信息中,发现了一条可疑的高解析执行的SQL:
图Parse Calls的输出
排在第一位的这条SQL占据了78.62%的解析比重,在10小时的AWR报告采样中,共执行了两千多万次,平均每秒解析执行约600次,这个高解析执行的SQL以超乎寻常的频率解析执行引起了我们的注意,其SQL的完整文本为:
select min(bitmapped) from ts$ where dflmaxext =:1 and bitand(flags, 1024) =1024
直观判断这条SQL是和系统递归调用相关的,查询了底层的ts$视图,其调用如此频繁必然和大多数查询有关,尝试跟踪一下普通查询,我们发现这个SQL有很高的解析度。比如跟踪如下的SQL:
SQL> alter session set events '10046 trace name context forever,level 12'; Session altered. SQL> select count(*) from dba_indexes; COUNT(*) ---------- 5890复制
tkprof格式化后台跟踪文件可以发现,在这个查询中,后台ts$递归查询高达3305次,并且逻辑读很高:
select min(bitmapped) from ts$ where dflmaxext =:1 and bitand(flags,1024) =1024 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 3305 0.02 0.04 0 0 0 0 Execute 3305 0.24 0.30 0 0 0 0 Fetch 6610 0.90 1.05 0 317280 0 3305 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 13220 1.16 1.39 0 317280 0 3305复制
这使得我怀疑可能是某个Bug在作祟,检索Metalink,马上发现了相关Bug,Bug号为:5455880。该Bug的影响版本如图所示:
图Bug号为5455880的影响版本
客户的数据库版本为10.2.0.2,正好在受影响之列,这个Bug是说,当使用了Oracle 10g的临时表空间组特性时,后台的递归SQL可能会发生高昂的解析及执行:
When using a tablespace group as the temporary tablespace excessive recursive queried against TS$ can impact performance. The offending SQL is of the form: "select min(bitmapped) from ts$ where dflmaxext =:1 and bitand(flags,1024)=1024"复制
这个Bug在10.2.0.4之后修正,暂时的解决方案是停用临时表空间组。用户调整了临时表空间组的使用之后,这个SQL立即消失了,系统的解析等负载概要信息也发生了较大变化(使用$ORACLE_HOME/rdbms/admin/awrddrpt.sql可以生成两个时段的AWR比较报告),如图1-18所示:
图 两个时段的AWR比较报告
在使用Oracle的一些新特性时,一定要注意观察,看是否会引发一些新的问题,而DBA应该对系统中的一些异常SQL具有一定的敏锐性,要认真细致及时审查确认,才能保障数据库的持续稳定运行。