《Oracle 数据结构知多少》
感兴趣的朋友,浏览《Oracle 数据结构知多少(一)》 http://space.itpub.net/26686207/viewspace-757937
本周又要继续开始“Oracle 数据结构系列之二”重点讲述表空间的存储属性,数据块的压缩,段空间存储属性等知识,欢迎广大亲们一起交流讨论,营造一个专家圈子,一起更上一层楼。长话短说,进入正题。我们在上一节已经把segment-extent-block概念一一讲明了,这里呢我们主要讲一讲它们在生产库上应用场景和如何设置。
二 数据库版本
LEO1@LEO1>select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux:Version 11.2.0.1.0 - Production
NLSRTL Version11.2.0.1.0 - Production
三 实验
1.创建表,分区表,大对象字段,分别查询出它们是否为段对象,给出SQL演示的整个过程。
段对象:Oracle所有分配存储空间的对象都叫段对象。例如 表 索引 分区 大对象等都称之为段对象
段对象是接近于应用层的,它是业务层面的一个含义,表空间逻辑上是由段对象组成的。
段的种类
数据段
LEO1@LEO1>create table t1 (x int,y int); 创建个表
Table created.
LEO1@LEO1>create index idx_t1 on t1(x); 表上创建个索引
Index created.
LEO1@LEO1>insert into t1 values(1,1); 只有插入数据后oracle才会真正创建索引
1 row created.
LEO1@LEO1>commit;
Commit complete.
LEO1@LEO1>select * from t1;
X Y
----------------------------------
1 1
select segment_name,segment_type,tablespace_name,extents,blocks,bytes/1024/1024from dba_segments where segment_name in ('T1','IDX_T1');
SEGMENT_NAMESEGMENT_TYPE TABLESPACE_N EXTENTS BLOCKS BYTES/1024/1024
------------------------------------------ ------------------ ------------------------------- ------------------------------
T1 TABLE LEO1 1 8 .0625
IDX_T1 INDEX LEO1 1 8 .0625
上面的表和索引都占用空间(多少extent block 容量),因此都可称为段对象
临时段
是临时表和中间状态的数据存储放的位置,常用于sort hash merge,不用永久保存,只做临时存储,临时段组成了临时表空间,只有在内存不够时,oracle才会在临时表空间上创建临时段。
注意:临时段上的操作不产生redo,因为无需保护,是一种中间状态,这样可以提高效率
LEO1@LEO1>select file#,name,status,enabled,bytes,blocks,block_size from v$tempfile;
FILE# NAME STATUS ENABLED BYTES BLOCKS BLOCK_SIZE
--------------------------------------------------------------------------------------------------------------------------------
1 /u01/app/oracle/oradata/LEO1/temp01.dbf ONLINE READ WRITE 128974848 15744 8192
经过查看临时段也分配存储空间了,块大小8k,15744个块,大小为128974848字节,因此说临时表 索引啊都可以称之为段对象,临时表的使用和演示后面进行,敬请期待!
回滚段
《Oracleundo我们需要掌握什么》 http://space.itpub.net/26686207/viewspace-757488这篇文章对undo段做了非常详细介绍,朋友们可以参考。
这里我们只是演示一下undo段所占用的空间
LEO1@LEO1>select tablespace_name,file_name,bytes/1024/1024,autoextensible fromdba_data_files where tablespace_name='UNDOTBS1';
TABLESPACE_N FILE_NAME BYTES/1024/1024 AUT
---------------------------------------------------------------------------------------------------------------------------------
UNDOTBS1 /u01/app/oracle/oradata/LEO1/undotbs01.dbf 165 YES
这就是undo表空间对应的undo数据文件,在数据库需要做回滚时就在undo表空间中创建undo段。
分区表的段对象
分区表中,一个分区对应一个段对象,如果有3个分区那么这张分区表就包含3个段对象,这时表已经不是段对象了,倒成了一个标签。
LEO1@LEO1>create tablespace par_data01 datafile size 10M autoextend off;
Tablespacecreated.
LEO1@LEO1>create tablespace par_data02 datafile size 10M autoextend off;
Tablespacecreated.
LEO1@LEO1>create tablespace par_data03 datafile size 10M autoextend off;
Tablespacecreated.
创建三个表空间分别存储三个分区
LEO1@LEO1>create table part_leo (name varchar2(20),age number,part_date date);
Table created.
LEO1@LEO1>insert into part_leo values ('leonarding1',100,to_date('2001-01-01','yyyy-mm-dd'));
insert intopart_leo values ('leonarding2',200,to_date('2002-02-02','yyyy-mm-dd'));
insert intopart_leo values ('Alan1',300,to_date('2003-03-03','yyyy-mm-dd'));
insert intopart_leo values ('Alan2',400,to_date('2004-04-04','yyyy-mm-dd'));
insert intopart_leo values ('tigerfish1',500,to_date('2005-05-05','yyyy-mm-dd'));
insert intopart_leo values ('tigerfish2',600,to_date('2006-06-06','yyyy-mm-dd'));
LEO1@LEO1>commit;
Commit complete.
LEO1@LEO1>select * from part_leo;
NAME AGE PART_DATE
--------------------------------- ---------
leonarding1 100 01-JAN-01
leonarding2 200 02-FEB-02
Alan1 300 03-MAR-03
Alan2 400 04-APR-04
tigerfish1 500 05-MAY-05
tigerfish2 600 06-JUN-06
创建一个表并插入6行记录,做分区表的原表
LEO1@LEO1>CREATE TABLE part_leo_super
PARTITION BY RANGE (part_date)
( PARTITION p1 VALUES LESS THAN(to_date('2002-12-01','yyyy-mm-dd'))
TABLESPACE par_data01, 比2002-12-01小的记录放入p1分区
PARTITION p2 VALUES LESS THAN(to_date('2004-12-01','yyyy-mm-dd'))
TABLESPACE par_data02, 比2004-12-01小的记录放入p2分区
PARTITION p3 VALUES LESS THAN(to_date('2006-12-01','yyyy-mm-dd'))
TABLESPACE par_data03, 比2006-12-01小的记录放入p3分区
PARTITION other VALUES LESS THAN(maxvalue)
TABLESPACE par_data03) 余下的记录放入par_data03分区
as select * from part_leo; 2 3 4 5 6 7 8 9 10 11
Table created.
采用CTAS方式创建分区表,三个分区分别存放在三个表空间上
LEO1@LEO1>select * from part_leo_super partition (p1); 第一分区的数据
NAME AGE PART_DATE
--------------------------------- ---------
leonarding1 100 01-JAN-01
leonarding2 200 02-FEB-02
LEO1@LEO1>select * from part_leo_super partition (p2); 第二分区的数据
NAME AGE PART_DATE
--------------------------------- ---------
Alan1 300 03-MAR-03
Alan2 400 04-APR-04
LEO1@LEO1>select * from part_leo_super partition (p3); 第三分区的数据
NAME AGE PART_DATE
--------------------------------- ---------
tigerfish1 500 05-MAY-05
tigerfish2 600 06-JUN-06
LEO1@LEO1>select segment_name,partition_name,tablespace_name,extents,blocks,bytes/1024/1024from dba_segments where segment_name='PART_LEO_SUPER';
SEGMENT_NAME PARTITION_NAME TABLESPACE_N EXTENTS BLOCKS BYTES/1024/1024
----------------------------------------------------------------------------------------------------------------------------------------
PART_LEO_SUPER OTHER PAR_DATA03 1 8 .0625
PART_LEO_SUPER P1 PAR_DATA03 1 8 .0625
PART_LEO_SUPER P2 PAR_DATA03 1 8 .0625
PART_LEO_SUPER P3 PAR_DATA03 1 8 .0625
每个分区都有独立的存储空间,因此可以说每个分区都是一个段对象(PARTITION_NAME)PART_LEO_SUPER这个名在分区表中不算段名了可以看成一个总名称!
大对象字段的段对象
我们为什么要创建大对象字段,普通的varchar2字段:最大支持4000个字符!
如果我们想在字段中存放一篇小说,一个文章,一篇blog怎么办?大对象字段就是解决这个问题的。
注:大对象与小对象字段的长度不一致导致碎片的一个原因,一般把大对象单独放在一个表空间中减少碎片的产生。
创建存放CLOB字段的表空间clob_data
LEO1@LEO1>create tablespace clob_data datafile size 10M autoextend off;
Tablespacecreated.
创建含CLOB(character large object)字段表
LEO1@LEO1>create table clob_table
(
name varchar2(20), 姓名
employment varchar2(30), 职业
school varchar2(30), 毕业院校
current_date date, 当前时间
discription clob 描述(字符型大对象字段)
)
tablespace leo1 存放于leo1表空间
lob (discription) 指定大对象字段
store as
(
tablespace clob_data 大对象存放的表空间
);
2 3 4 5 6 7 8 9 10 11 12 13 14
Table created.
我们通过下列数据字典找到刚刚创建的大对象
LEO1@LEO1>select table_name,column_name,segment_name,tablespace_name from dba_lobs wheretable_name='CLOB_TABLE';
TABLE_NAME COLUMN_NAME SEGMENT_NAME TABLESPACE_N
--------------------------------------------------------------------------------------------------------------------
CLOB_TABLE DISCRIPTION SYS_LOB0000074408C00005$$ CLOB_DATA
小结:由此看来大对象字段也占用表空间,凡是占用空间的对象都可称为段对象。
2.分别创建一个ASSM,MSSM管理的表空间。
MSSM—ManualSegment Space Management 手动段空间管理(手动设置对象的存储属性)
这种管理方式就是使用freelist管理数据块的分配和回收,是一种只针对数据块分配的管理方式,这种方式可以让DBA有更大的空间管理余地,更大自由发挥空间,在早期的Oracle上都是通过这种方式管理块分配的。
场景:对于一些数据块操作非常敏感的场合相对适用
参数:MSSM-由你设置freelists、freelistgroups、pctused、pctfree、initrans等参数来控制如何分配、使用段中的空间
缺点:1.需要设置更多的参数,例如上面所写的参数,操作复杂度更强
2.参数设置值比较难评估,需要大量的测试过程
3.需要了解数据库体系结构的DBA设置
注意:1.freelist空闲列表是放在段头里面的,如果有多个用户同时访问列表势必会引发段头争用,导致“buffer busy waits”等待事件发生,建议多设几个freelist,防止争用。
ASSM—AutomaticSegment Space Management 自动段空间管理(自动设置对象的存储属性)
这种管理方式就是使用“位图bitmap”管理数据块的分配和回收,1为占用块不可分配,0为空闲块可分配,由于计算机就是由二进制编码的,所以操作二进制代码是非常快捷的。现在Oracle 10g 11g 默认值都是ASSM段空间管理方式。
场景:希望数据块由Oracle自动分配管理的场合,不需要DBA介入太多
参数:ASSM-你只需控制一个参数pctfree,其他参数由Oracle自动管理,如果强行设置也将被忽略。
三层位图模式管理段空间:第一层BMB(bit map block)记录每个extent中数据块的存储信息,只管理当前的extent内块,放在extent头中,这是leaf节点
第二层BMB管理第一层BMB记录,这是branch节点
第三层BMB管理第二层BMB记录,放在段头中,这是root节点
ASSM段头包含了每个Extent存储信息
Extent区头包含BMB信息
优点:1.自动化管理段空间,无需手动设置大量参数,简化了操作
2.增大并发度,由于ASSM没有freelist概念,也就没有freelist列表争用情况,也就没有段头争用的情况,提高资源利用率。
缺点:1.全表扫描性能没有MSSM模式下好
2.大数据加载,会导致性能下降,因为要自动维护位图表,需要一定的开销
3.影响索引的集群因子(clustering factor)
(1) 设置db_create_file_dest参数
作用:指定Oracle创建某某文件的存放路径,设置后就可以在创建表空间时不指定文件路径了。
■ Datafiles
■ Tempfiles
■ Redo log files
■ Control files
■ Block change tracking files
LEO1@LEO1> showparameter db_create_file_dest
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_create_file_dest string
空,我们现在还没有初始化这个参数值
LEO1@LEO1>alter system set db_create_file_dest='/u01/app/oracle/oradata/LEO1/';
System altered.
LEO1@LEO1> showparameter db_create_file_dest
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_create_file_dest string /u01/app/oracle/oradata/LEO1/
现在我们已经设置好了参数
(2)创建MSSM和ASSM表空间
LEO1@LEO1>create tablespace leo_mssm segment space management manual;
Tablespacecreated.
LEO1@LEO1>create tablespace leo_assm segment space management auto;
Tablespacecreated.
我们创建了一个MSSM段管理表空间又创建一个ASSM段管理表空间,默认大小100M
LEO1@LEO1>select file#,name,bytes/1024/1024 from v$datafile;
FILE# NAME BYTES/1024/1024
----------------------------------------------------------------------------------------------------------------------------------------------
9 /u01/app/oracle/oradata/LEO1/LEO1/datafile/o1_mf_leo_mssm_8p9jorpx_.dbf 100
10 /u01/app/oracle/oradata/LEO1/LEO1/datafile/o1_mf_leo_assm_8p9jplb8_.dbf 100
数据文件名是系统自定义的。
LEO1@LEO1>select tablespace_name,segment_space_management from dba_tablespaces wheretablespace_name in ('LEO_MSSM','LEO_ASSM');
TABLESPACE_N SEGMEN
----------------------------------
LEO_ASSM AUTO
LEO_MSSM MANUAL
小结:我们根据实际需要来创建与业务匹配的表空间,宗旨技术为业务服务。


雷达卡







京公网安备 11010802022788号







