Oracle 表空间(SYSTEM表空间 和临时表空间) 段空间 管理技术
表空间及数据文件
定义:
用户存储数据文件的空间,被称为表空间,用于存储永久数据的表空间称为永久表空间,用于存储临时数据的表空间被称为临时表空间。
数据库的物理结构和逻辑结构
从物理结构上看,多个操作系统(OS Block)组成数据文件(DataFile),数据文件存储在物理存储之上。
从逻辑结构上来看,数据块是oracle的最小IO单位,数据块通常是由多个操作系统块(OS Block)组成,多个数据块组成区间(extent),区间是oracle创建对象时的最小空间分配单元;多个区间组成段(Segment),段存于表空间中,因此,表空间可以看成是一个容纳各种对象段(如数据表的表段、索引段)等的容器。
表空间可以包含一个或者,多个数据文件。因此可以被看成是一个文件组,Oracle就是由一列表空间组成。
表空间管理技术
由于区间(EXTENT)是oracle创建对象时的基本分配单位,所以表空间表空间管理技术实际上就是针对区间的管理技术。
- Oracle 8i以前的字段管理表空间技术(DMT)
- Orace 8i以后的本地管理表空间技术(LOCAL)
本地管理表空间上,oracle将存储信息保存在表空间头部的位图中。
8i以前,是字典管理表空间,当创建或删除对象时,Oracle的空间分配或回收是通过数据字典来记录和管理
在高并发系统中,这会导致性能衰减、空间碎片等难题
这已经是门过去的技术,这里就不赘述了。
8i开始,Oracle引入本地表空间管理
在每个表空间的数据文件的头部加入了一个位图区域
一个段的第一个区的第一个块是first level bitmap block
第二个块是secondlevelbitmapblock
第三个块才是段头块
这两个块是用来管理freeblock
段空间管理技术
Oracle 以区间(Extent)为单位将空间分配给对象段,而段内以则是以Block为单位进行空间的管理和使用的。
- 手工段空间管理MSSM
- 自动段空间管理ASSM
- 延迟段空间创建DSC 11g及以后独有
ASSM通过位图能够迅速有效地管理存储扩展和剩余区块(free block)
DSCT特性:当创建一个对象时,数据结构定义被存储,但是并不立即创建数据段,直到有第一行记录写入时才动态创建分配段空间
在高并发的DML操作环境中,ASSM可能出现性能瓶颈。
Oracle 10/11G已经将ASSM作为默认的表空间管理模式。
查看 段管理方式sql
select tablespace_name,extent_management,segment_space_management from dba_tablespaces;
oracle存储信息
oracle的存储信息可以通过不同的数据视图查询得到。
- 表空间信息记录 dba_tablespaces 记录表空间的逻辑信息
- 数据文件信息记录 dba_data_files 记录物理数据文件的信息
- 数据段信息 dba_segments
- 区间信息 dba_extent
- 段级统计信息 V$SEGMENT_STATISTICS
数据段中数据最终会被用户访问,哪些表和索引会被频繁使用,哪些对象存在频繁的逻辑读和物理读,这对于数据库性能优化有重要意义。通过以下几个动态性能视图实现:
- V$SEGSTAT_NAME视图记录了数据库收集段级统计信息的内容
- V$SEGMENT_STATISTICS包含了1)中统计指标的采样,通过查询其中信息,可以帮助我们找到哪些对象对物理读、逻辑读等重要内容。
--查询前10的SQL语句
select * from (select object_name,statistic_name,value from v$segment_statistics where statistic_name='physical reads' order by 3 desc) where rownum<11;
- 度量信息 dba_thresholds oracle10G中设置了一系列的监控规则,用于监控数据库的运行情况,这些规则被称为“度量”,用户可以根据度量进行调整,对于不同度量的阈值,可以通过 dba_thresholds 视图进行查询。
- 突出警告信息 dba_outstanding_alerts oracle10g通过dba_outstanding_alerts视图记录数据库活动报警信息,这些信息知道警告清除或者复位才会从这个视图中消失。
select t.object_name,t.object_type,t.reason,t.suggested_action from dba_outstanding_alerts t;
- 历史警告信息 dba_alert_history 历史告警信息查询。
物理读(Physical Reads)
从磁盘读取数据块到内存的操作叫物理读,当SGA里的高速缓存(Cache Buffer)里面不存在这些数据块时,就会产生物理读,另外。像全表扫描、磁盘排序等操作也可能产生物理读,原因也是因为ORACLE数据库需要访问的数据块较多,而有些数据块不在内存当中,需要从磁盘读取。
逻辑读(Logical Reads)
概念1:逻辑读指ORACLE从内存读到的数据块数量。一般来说, logical reads = db block gets + consistent gets
概念2:逻辑读指的就是从Buffer Cache中读取数据块。按照访问数据块的模式不同,可以分为当前模式读(Current Read)和一致性读(Consistent Read)。
这两个概念本质是一样的,只是措辞不一样。
SYSTEM 表空间
System表空间是oracle最重要的表空间,在创建数据库的时被最先创建,其中包含了数据库的元数据,对于数据库来说生死攸关。
- Ssytem表空间永远不可能offine,否则数据库无法打开,
- 如果system表空间故障,则数据库就要进行介质恢复。
- 数据库启动过程中也需要system表空间进行引导。
SYSAUX表空间及其组件
作为system表空间的辅助组件,以前一些使用system表空间或者独立表空间的数据库组件现在在sysaux表空间创建,通过分离这些组件,system表空间的负荷得以减轻。
BigFile 和smallFile表空间技术
Rowid与rdba的转换
临时表空间和临时文件
临时表空间是是oracle的一个特殊表空间,其表空间文件通常为临时文件。
临时表空间的典型用途是用于磁盘排序等操作,常见操作有 CREATE INDEX、 ANALYZE、SELECT DISTINCT、ORDER BY、GROUP BY、 UNION ALL、 INTERSECT、MINUS、SORT-MERGE JOINS、HASH JOIN等都可能会用到临时表空间。
当操作完成后,系统会自动清理临时表空间中的临时对象,自动释放临时段。这里的释放只是标记为空闲、可以重用,其实实质占用的磁盘空间并没有真正释放。这也是临时表空间有时会不断增大的原因。
临时表空间存储大规模排序操作(小规模排序操作会直接在RAM里完成,大规模排序才需要磁盘排序Disk Sort)和散列操作的中间结果.它跟永久表空间不同的地方在于它由临时数据文件(temporary files)组成的,而不是永久数据文件(datafiles)。临时表空间不会存储永久类型的对象,所以它不会也不需要备份。另外,对临时数据文件的操作不产生redo日志,不过会生成undo日志。
--记录oracle临时区间的使用
select t.TABLESPACE_NAME,t.EXTENTS_CACHED,t.EXTENTS_USED,t.BLOCKS_CACHED,t.BLOCKS_USED,t.BYTES_CACHED,t.BYTES_USED from v$temp_extent_pool t;
--查看当前正在排序的用户信息
select * from v$sort_usage t;
-- 查看排序段的使用情况
select t.TABLESPACE_NAME,t.TOTAL_EXTENTS,t.TOTAL_BLOCKS,t.USED_EXTENTS,t.ADDED_EXTENTS from v$sort_segment t;
--通过以下sql我们能获取正在使用临时段排序的用户
select a.SID,a.PROCESS,a.SERIAL#,to_char(a.LOGON_TIME,'YYYYMMDD HH24:MI:SS') LOGON,a.OSUSER,c.TABLESPACE,b.SQL_TEXT from v$session a,v$sql b,v$sort_usage c where a.SQL_ADDRESS=b.ADDRESS and a.SADDR=c.SESSION_ADDR;
--结合v$session视图,排序用户等更为详细的信息都可以查到
select b.TABLESPACE,b.SEGFILE#,b.SEGBLK#,b.BLOCKS,a.SID,a.SERIAL#,a.USERNAME,a.OSUSER,a.STATUS from v$session a ,v$sort_usage b where a.SADDR=b.SESSION_ADDR order by b.TABLESPACE,b.SEGFILE#,b.SEGBLK#,b.BLOCKS;
--根据session信息,排序的sql操作也可以查询得到
select sql_text from v$sqltext a where a.HASH_VALUE=(select * from v$session b where b.SID='&sid' )