Admin-DB Storage Management

存储管理
1、数据物理的存储在数据文件中
数据文件、控制文件、联机重做日志文件
2、逻辑概念管理数据
数据库、表空间、段(segment)、区间(extent)、数据块(block)
1、一个表空间只能属于一个数据库、一个表空间可以包括多个数据文件
一个数据文件只能属于一个表空间
2、一个段可以跨越多个数据文件,普通表就是一个segment、索引也是 一个 segment
3、segment分配空间的最小单位就是extent,每个segment由一个或者多 extent组成
4、一个extent不能跨越多个数据文件因为一个extent是物理上连续的存储空间
5、一个extent由多个连续的block组成
6、block是oracle I/O的最小单位
表空间
1、系统表空间
里面存储的都是数据字典信息
2、非系统表空间
包含用户自己的数据、也包含临时和undo数据
对于存储用户数据的表空间,我们往往根据逻辑业务来划分数据库
例如一个业务系统数据库,我们分成了多个表空间
销售类表空间
采购类表空间
财务类表空间
人力资源表空间
等等
表空间的空间管理
在表空间中,段会进行扩展和收缩,分配的单元是extent
表空间的管理就是如何管理extent的分配和释放
1、数据字典管理(DMT)
2、本地管理(LMT)
数据字典管理
1、有两个数据字典表(FET$和UET$)
FET$(free extent)记录表空间中的可用空间
UET$(used extent)记录表空间中的已经分配的空间
表空间编号
文件编号
数据块编号
长度(多少个数据块)(因为是连续空间,因此知道了起点和长度以后,终点也就知道了)
一个extent在表中对应一条记录
分配空间后,就相当于从FET$中挖数据、释放空间以后,就相当于从UET$中挖数据
在extent不断的分配和释放中,FET$和UET$不断的变化
我们来看看能够产生的一些问题
注意:因为字典管理表空间几乎已经被淘汰,因此我们没有必要研究的很细。
1、使用SQL语句对两个表进行操作,本身是一种相对低效的方式
2、两个表之间的插入、删除,产生事务,伴随着锁的产生,有了锁以后,必然会产生锁的争用,引起锁等待,影响extent的分配和释放
3、事务会产生redo和undo,这也是使用SQL的缺点之一
4、SMON进程定期扫描FET$表,对其中相邻的可用空间进行合并,这会消耗一定的资源,FET$中记录很多的时候,资源消耗尤其严重
随着数据库的增长、事务量的增加,字典管理表空间已经不能满足需求,于是就是产生了本地管理表空间
本地管理表空间
1、不再使用两个表(FET$和UET$)
2、每一个数据文件头部选出6个数据块(从3到8),在其中存放bitmap来管理extent的分配和释放
每个bit位对应一个extent,0表示对应的extent还没有分配、1表示对应的extent已经分配
我们来分析一些位图
111100001100100011000
1、前四个extent已经分配,5678还没有分配,等等
2、如果需要分配extent,只要扫描文件的头部,找到那些值为0的bit位,分配该extent所对应的空间,然后将相应的bit为置为1即可
3、当需要释放extent的时候,只需要将对应的bit位设置为0即可
解决了字典管理表空间的问题
1、没有涉及到SQL语句
2、没有事务、没有锁、没有回滚和redo
3、空间的合并也非常的方便,因为连续为0就是可以合并的空间
用户数据都存放在这种类型的表空间中。
“设置为默认永久表空间”,如果创建用户的时候,没有指定默认表空间。
那么就使用这个表空间作为默认表空间。使用新建用户登录,创建对象的时候,如果没有指定明确的表空间,那么就使用这个默认的表空间。
这个选项是指定数据库默认表空间。
使用DBCA创建数据库的时候,默认创建了USERS表空间,并且将这个表空间作为数据库默认表空间。
没有数据库默认表空间、创建用户的时候也没有指定默认的表空间,那么该用户就使用system作为默认表空间,这显然不是我们希望的。
对于DBA来说,还是要明确数据库的默认表空间。查询database_properties
临时表空间
1、存放临时数据、需要时被覆盖、关闭后被删除
2、可以被所有的用户所使用
例如排序
首先在PGA中进行、如果数据量太大,不能在内存中完成,那么Oracle如下处理
1、将数据分割成多份,只取出一份放在PGA中进行排序
2、其余的放在临时表空间中
3、部分数据在PGA中排序完成以后,交换到临时表空间中,然后再从临时表空间中取出一份,放在PGA中继续排序,以此类推,直到将所有的数据排序完毕为止
设置为默认表空间
这是数据库级别的默认临时表空间
1、如果设置了这个选项,创建用户没有指定默认表空间,那么用户就使用这个临时表空间作为自己的默认临时表空间,用户所有的排序都在这个临时表空间中进行
2、如果没有指定数据库默认临时表空间、创建用户的时候,也没有指定默认的临时表空间,那么用户就使用system作为临时的表空间,这显然不是我们希望看到的
指定数据库的默认临时表空间还是很有必要的。
注意:一定不要出现一种情况
1、使用我们不希望使用的表空间,例如将system表空间作为默认永久和默认临时表空间。最好的用法就是
指定明确的数据库默认表空间和用户默认表空间,用户创建对象的时候,尽量指定表空间。
只读
1、表空间只读,不能写入
2、系统表空间、默认临时表空间、undo表空间,都不能设置为只读
3、只读表空间里面的数据不能够被修改,但是表可以删除,因为删除表只是在数据字典里面将相应的信息删除而已。
离线
1、系统表空间、默认临时表空间、undo表空间,都不能设置为离线

2、表空间不能被读和写
Oracle10g中引入了这个技术,如果选中“使用大文件表空间”
只能包含一个数据文件,最多可以容纳40亿个数据块
(根据数据块的大小不同:2K、4K、8K、16K、32K)
可以容纳的数据从8T到128T
最好将这个特性配合ASM一起使用,如果放在文件系统中,那么需要设置文件系统支持大文件
默认不选用,默认使用smallfile

如果没有选择“数据文件满后自动扩展”,那么数据满后会报错。
对于DBA来说,不应该出现数据文件已经分配满,但是DBA不知晓的情况,应该例行性的查看空间使用情况。
为了方便,可以选择自动扩展,而且指定每次扩展的大小。
区空间分配
1、自动
Oracle根据当前区的数量自动的决定下一个区的大小,区的数量越多,下次分配的区越大
2、统一
所有的区的大小一样
建议使用统一大小,这样碎片就会没有
经典的存储管理
1、按照业务逻辑进行表空间的划分,例如销售类、采购类、财务类、以及人事类
2、按照数据量的大小进一步划分
通常分为三类:大表、中表、小表
3、所有表空间都使用本地管理以及uniform组合
4、大表所在的表空间的extent最大(例如8M),中表中等(例如1M)、小表最小(例如64K)
5、这样销售类就包含三个表空间,sales_big_tbs、sales_middle_tbs、sales_small_tbs,依此类推
9i以后引入的一个概念
前面已经讲了数据文件的空间管理,然后讲了如何对区的分配进行管理,下面讲如何对已经分配的区进行管理。
Segment被分配extent以后,如果使用这些extent呢,这就涉及了一个问题,如果进行段的空间管理。
数据文件的空间管理-对象的区间分配-区间分配给segment后,就成了段管理
段空间的管理(为段分配空间的时候,如何分配具体的数据块,段空间管理就是数据块的具体管理)
1、manual
Oracle9i以前,只能使用手工设定参数
每一个segment的第一个数据块中,都有一个seg header,这个seg header指向一个可用链表的起点,freelist链表上挂的都是可以用来进行插入操作的数据块
当服务器进程进行插入操作而需要可用数据块时,锁定seg header,遍历freelist,搜索具有足够空间进行插入的可用数据块,找到该数据块,将数据插入,然后释放对seg header的锁定
自动段空间管理(ASSM automatic segment space management)
对段空间进行管理的时候,建议使用automatic
我们来研究一下ASSM
对于段空间的手动管理,我们有两个参数
pctfree、pctused
在创建表或者索引的时候,可以指定这两个参数
1、pctfree:表示数据块里剩余的可用空间占数据块总空间的百分比,该参数默认是10
2、pctused:表示已经使用的空间占数据块总空间的百分比,该参数默认是40
当可用链表上的某个数据块不断被插入数据,从而导致该数据块里的剩余可用空间与数据块大小的百分比小于pctfree的值的时候,该数据块从可用链表上删除,不再用于insert操作,剩余空间被用于update操作
当删除某个数据块上的数据,导致该数据块已经使用的空间与数据块大小的百分比小于pctused的值的时候,说明这个数据块的可用空间已经足够多了,于是再次被挂到可用链表上
问题
当对某一个段的数据并行插入很多的时候,每一个插入都需要锁定seg header,然后遍历freelist,因为同一时间只能有一个插入锁定seg header,因此容易产生seg header锁等待
注意:锁等待是数据库里面的一个很严重的性能问题
段空间的manual管理主要是利用了seg header+freelist的方式来进行block的分配。
段空间的automatic管理主要是利用了BMB(bitmap block)
Oracle分配了很多的BMB块,这些BMB块组织成了层次状的索引结构。
1、若干数据块的地址+数据块的状态
2、六种状态(Unformated、<25%、25%-50%、50-75%、75-100%),分别表示数据块的可用空间的百分比
服务器进程根据插入的数据量的大小,来判断应该使用哪个数据块,假设当前的插入需要使用1KB的空间,同时数据块为8KB,则需要12.5%的空间,于是在叶子BMB块中找一个可用空间大于12.5%的数据块即可,当完成数据的插入以后,把被插入的数据块剩余的可用空间状态信息更新BMB块中的对应的条目
解决的问题
1、多个BMB来管理,而不是一个链表
2、多个进程可以同时使用多个BMB进行并行的插入,防止了对seg header的争用
在ASSM中,只能设置pctfree,而pctused、freelist等存储参数被忽略

Enabling logging
Yes:对该表空间里的表进行DML操作产生重做记录
No:对该表空间里的表进行DML操作不产生重做记录,加快了DML操 作,但是不安全,存储重要数据的表空间不要使用这个选项

CREATE SMALLFILE TABLESPACE "TBS" DATAFILE '/u01/app/oracle/oradata/ORACLR10G/datafile/tbs01.dbf' SIZE 100M AUTOEXTEND ON NEXT 1M MAXSIZE UNLIMITED LOGGING EXTENT MANAGEMENT LOCAL UNIFORM. SIZE 1M SEGMENT SPACE MANAGEMENT AUTO
上面是一个标准的建立表空间的语句。
1、SYSTEM是数据字典存放的表空间
2、SYSAUX从Oracle10g引入,作为辅助的系统表空间,创建数据库的时候创建,不能重命名、不能删除,存放了很多数据库的辅助功能,比如AWR等
3、temp是数据库的默认临时表空间
4、undotbs1为数据库的undo表空间
5、users是数据库的默认永久表空间
6、example为数据库的测试案例涉及的表所在的表空间
四种脱机模式
1、正常:离线前,Oracle会发出文件级别的CKPT,将离线的表空间所对应的位于buffer cache里的脏数据块全部写入到对应的数据文件里面,然后将表空间离线。通过这种方式,表空间数据没有损坏,下次ONLINE的时候,不需要恢复
2、立即:通常在表空间所对应的所有的数据文件损坏或者丢失的情况下采用这种模式
Oracle不会发出文件级别的CKPT,所有脏数据都不写入,表空间数据会被损坏,下次online需要恢复
3、临时
通常在表空间所对应的数据文件没有完全丢失或损坏的情况下会采用这种模式
Oracle发出CKPT,能写入的脏数据就写入,不能写入的就不写入
数据会被损坏,下次online时需要恢复
4、用于恢复
不再使用

转移表空间的方法
1、只能使用命令行,不能使用dbcontrol
2、分为两种
转移非system表空间
转移system表空间

对于非系统表空间,可以采用下面的方式。
alter tablespace tbsname offline;
!cp datafile of tablespace
alter tablespace tbsname rename datafile '' to '';
alter tablespace tbsname online;

对于系统表空间,可以采用下面的方式:
shutdown immediate
startup mount
!cp datafile
alter database rename file '' to '';
alter database open;

临时表空间和临时表空间组
1、临时表空间主要用来存放用户的临时数据,例如排序数据
2、Oracle10g中引入了临时表空间组的概念
1、临时表空间组是一组临时表空间
2、临时表空间组和临时表空间的名字不能相同
3、不能显式的创建和删除临时表空间组,因为临时表空间组中必须 要有成员,当第一个临时表空间被分配给临时表空间组的时候,临 时表空间组自动的创建,当最后一个临时表空间从临时表空间组退 出的时候,临时表空间组自动删除,这样保证了临时表空间组总是 有成员。
使用临时表空间组的好处
1、同一个用户,在不同的session里可以使用不同的临时表空间
每一个用户有一个默认的临时表空间,同一个用户登陆多个session的时候,如果不使用临时表空间组,那么所有的session使用同一个临时表空间,容易产生瓶颈问题。
2、在并行操作中,不同的从属进程可以使用不同的临时表空间
3、在数据库从面可以同时指定多个默认临时表空间

默认临时表空间组的出现,主要是为了分散用户对默认临时表空间的集中使用,通过将对临时表空间的使用分散到多个临时表空间上,提高了性能
ALTER TABLESPACE TEMP TABLESPACE GROUP TEMPGROUP
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE TEMPGROUP 
1、将临时表空间temp放置到临时表空间组tempgroup中去
2、临时表空间组tempgroup创建成功
3、将默认表空间设置为tempgroup(这是一个临时表空间组)
我们可以创建多个临时表空间,然后放置到默认临时表空间组中去,这样就可以负载临时表空间。
非默认数据块大小的表空间
1、Oracle9i开始,支持多个尺寸的表空间
2、OLTP应用中,短小、小数据量的事务较多,建议使用较小的数据块,一般不要超过8K
3、DSS或者数据仓库中,事务都比较大,涉及的数据量也很大,因此建议使用较大的数据块,比如16K、32K
4、那么混合型的数据库中怎么办?
Oracle提供了多尺寸数据块的特征
5、Oracle9i、10g中总共支持5种类型的数据块
2KB、4KB、8KB、16KB、32KB
选择其中一种为标准数据块、其余4种为非标准数据块
1、创建数据库的时候,指定标准数据块的大小,数据库创建完成以后,不能修改
2、系统表空间和临时表空间只能使用标准数据块的大小
3、参数db_block_size确定标准数据块的大小
4、标准数据块的buffer cache由db_cache_size指定
5、undo表空间可以使用非标准数据块的大小
6、如果要使用非标准数据块的大小,必须设定非标准数据块的buffer cache
db_Nk_cache_size
如果db_block_size设置为8K,那么不能再指定db_8k_block_size
减小 db_cache_size的大小,然后建立db_2k_cache_size,因为总数不能超过sga_max_size
参数修改以后,就可以直接建立非标准数据块的表空间了。(需要先设置db_nk_cache_size大小)

联机日志文件
1、联机重做日志文件记录的都是数据块的变化,例如数据块头部的变化也会产生重做记录
2、commit的时候会触发LGWR,因为LGWR是顺序写入的,这相对DBWR来说,速度就快得多,因此提交的时候,只要保证LGWR写完即可,这样提高了提交的速度
3、联机重做日志文件最主要的功能是为了进行恢复

日志切换
联机重做日志文件采用的是循环写的方式,一个日志写满以后,切换到下一个日志继续写
日志切换的步骤
1、从控制文件中得到下一个可用的联机重做日志文件
2、记录写入当前联机重做日志文件的最后一个日志块的SCN(high SCN),关闭当前联机重做日志文件
3、增加SCN,再次修改控制文件,将下一个联机重做日志文件标记为CURRENT,判断前一个联机重做日志文件里包含的重做记录所对应的脏数据块是否都已经写入到了数据文件中,如果没有,则标记为active,如果是,标 记为inactive,如果数据库是归档模式,那么LGWR将前一个联机重做日志文件加入到归档列表中,并唤醒ARCn进程进行归档
4、打开新的联机重做日志文件组中的所有的成员,记录当前日志序列号和第一个日志块的SCN,新一轮的重做记录开始
几个概念
1、当前日志文件的状态是CURRENT、前一个日志文件的状态为ACTIVE
内存中存在很多的脏数据块,脏数据块的写入是通过DBWn进程完成的
如果脏数据块没有积累到一定的程度,DBWn是不会写入数据文件的
ACTIVE状态的日志文件表示该日志文件里面的重做记录所对应的脏数据块还没有写入被DBWn进程写入到数据文件中
日志切换只是触发了增量CKPT,CKPT进程在控制文件中记录这个时刻检查点队列上的脏数据块在第一次被修改时所对应的日志块在日志文件中的地址,这个位置也叫做检查点位置,DBWn不会立刻写数据
DBWn启动以后,会将脏数据块写入到数据文件中,ACTIVE状态也会变为INACTIVE状态
检查当前日志文件状态:
select * from v$log;

手工启动一个完全检查点:
alter system checkpoint;

将检查点的跟踪启动起来(检查点的启动和结束时间会记录到跟踪文件中)
alter system set log_checkpoint_to_alert=true;

管理日志文件
1、创建日志文件组
2、向日志文件组中添加成员
3、删除日志文件组成员
可以通过dbcontrol来完成
清除不是删除,Oracle将日志组成员中损坏或者丢失的成员进行创建。状态变为unused

Oracle的OMF
从Oracle9i开始,引入了所谓的OMF概念(Oracle管理文件)
OMF包含的文件包括控制文件、联机重做日志文件、数据文件、备份文件
我们不需要为这些文件指定文件名字、路径以及大小
只有设置了下面的参数以后,才能够启用OMF
db_create_file_dest
db_create_online_log_dest_1(2.3...)
db_recovery_file_dest
对于OMF来说,删除表空间的时候,自动删除数据文件。
表空间默认大小是100M。
       如果我们设置了上面的三个参数,那么在创建表空间、创建联机重做日志文件、使用恢复区的时候,Oracle自动的管理这些文件的路径、大小、名称。
      我们在管理Oracle的时候,有的时候使用到了Oracle的OMF,有的时候没有使用到Oracle的OMF。上面的实验中,我们在建立表空间的时候,就使用到了OMF。
       如果我们手工的指定路径、名称,那么就没有使用OMF。

注意:OMF涉及的概念
1、三个参数
2、什么时候OMF起作用(没有指定文件的路径和名称的时候)
3、OMF管理路径、文件名称、文件大小

数据块的结构
数据块分为三个部分
1、数据块的头部
2、数据
3、可用空间

Oracle数据块的头部
1、记录了当前该数据块所属的segment的类型(数据或者索引)
2、数据块的地址信息
3、ITL(interested transaction list)槽
每当一个事务要更新数据块里的数据的时候,必须先在数据块的头部获取一个可用的ITL槽,然后将当前的事务ID、事务所使用的UNDO数据块的地址、SCN号以及当前事务是否提交的标记等信息注册到ITL槽里
只有占用槽的事务提交或者回滚以后,别的事务才能够获取这个ITL槽
事务在获取ITL槽的时候,发现所有的ITL槽都被使用,于是动态的创建一个新的ITL槽
定义segment的ITL槽的初始数量和最大数量
两个参数决定:inittrans、maxtrans
默认表的inittrans是1、索引的maxtrans是2
我们在学习这些参数的时候,最主要的目的就是在看错误日志的时候,在看一些调优方案的时候,当他们提到这些具体的细节的地方,我们能够有所反应,判断一些事情。觉察出一些解决的办法。
这些参数和具体的细节,并不能帮助我们去做什么事情。
数据块的头部
4、行目录
记录了每一行相对于起点的位移量
这样我们在读取行的时候,才能够确认位置所在
数据行是从数据块的底部开始插入的,空间不断的上涨
数据块头部则是从数据块的顶部开始插入,空间不断的向下增长
这种方式是为了充分的利用空间


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27064837/viewspace-745746/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/27064837/viewspace-745746/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值