Oracle的存储管理
一、表空间的概念和使用
[oracle@oracle3 ORCL]$ ll *.dbf
-rw-r----- 1 oracle oinstall 104865792 06-24 15:41 example01.dbf
-rw-r----- 1 oracle oinstall 1073750016 06-24 15:41 plsql01.dbf
-rw-r----- 1 oracle oinstall 356524032 06-24 15:41 sysaux01.dbf
-rw-r----- 1 oracle oinstall 545267712 06-24 15:41 system01.dbf
-rw-r----- 1 oracle oinstall 31465472 06-17 00:00 temp01.dbf
-rw-r----- 1 oracle oinstall 560996352 06-24 15:41 undotbs01.dbf
-rw-r----- 1 oracle oinstall 6561792 06-24 15:41 users01.dbf --初始情况下数据库所有的数据文件
SQL> select ts#,name from v$tablespace; --表空间
TS# NAME
---------- ------------------------------
0 SYSTEM
1 UNDOTBS1
2 SYSAUX
4 USERS
3 TEMP
6 EXAMPLE
7 PLSQL
7 rows selected.
select * from dba_data_files --数据表空间由数据文件组成
select * from dba_temp_files --临时表空间和临时文件对应关系
操作1:给表空间USERS添加一个数据文件,给表空间扩容。
SQL> alter tablespace users add datafile '/u01/oracle/oradata/ORCL/users02.dbf' size 1G;
Tablespace altered.
select * from dba_data_files --一个表空间有两个数据文件
结论:一个表空间可以对多个数据文件,但是一个数据文件不能跨两个表空间
SQL> conn /as sysdba
Connected.
SQL> create table xu(x int) tablespace users;
Table created. --创建表的时候指定表空间,表中增加数据到底进入文件4还是文件7,Oralce自己决定的。
如果创建表的时候没有指定表空间,用默认的表空间(不是系统表空间)。不能把数据表创建在SYSTEM表空间上。
操作2:创建一个表空间
SQL> create tablespace mytbs1 datafile '/u01/oracle/oradata/ORCL/mytbs101.dbf' size 500M;
Tablespace created.
如果表空间满了,说明数据文件用光了,此时,需要扩容表空间,即增加数据文件。
如果磁盘满了,新加一个磁盘,创建一个目录,将这个目录挂载到这个磁盘,然后新的数据文件创建在新的目录下。
操作3:删除表空间
SQL> alter tablespace mytbs1 offline; --离线的目的是让当前所有连接到这个表空间的进程断开。防止下一步被挂死。
Tablespace altered.
SQL> drop tablespace mytbs1 including contents and datafiles; --删除的时候包括物理文件也会删除
Tablespace dropped.
练习:创建一个表空间MYTBSTEST 大小500M(要求两个数据文件),将其扩容到1G(总共3个数据文件),再删除这个表空间.
###########################################################################################
二、段(segment)
一个表空间可以分若干个段。
select * from dba_segments where owner='SCOTT'
一个表、索引就是一个段,创建一个段其实就是创建了一个表或者索引。
三、区(extent)
select * from dba_extents where owner='SCOTT' and segment_name='TT'
段由区组成
往表中插入数据就是往段中插入数据,随之,区的数量会增加。
一个区内的空间在物理上是连续的,区与区之间不一定是连续的,段的空间也不是连续的。
表空间 > 段> 区 > 数据块
四、oracle分配extent大小的方法
select * from user_extents where segment_name='TT' --TT是一个段
A 先分配16个大小是64K的区
B 再分配63个大小是1M的区
C 再分配120个大小是8M的区
D 后面的区全部是64M大小的
oracle分配算法好处在哪里?
1、区越大,数据块在物理上越连续,越连续就越利于查询这个表
2、如果一开始就做成64M的区,可能这个表只有几条记录,大量空间会被浪费。
3、如果开始的时候全是小区,虽然空间不是很连续,但是由于数据量小,性能损耗几乎是可以忽略的。
4、随着数据量的加大,扫表的成本会越来越高,此时后面的数据需要大的区尽量连续。
如果知道这个表将来的数据量或者规模。可以将extent的大小设置为等长,固定的。
SQL> create tablespace mytbs2 datafile '/u01/oracle/oradata/ORCL/mytbs201.dbf' size 500M extent management local uniform size 32M;
Tablespace created. --创建等长大小的区,本例是32M。
SQL> create tablespace mytbs3 datafile '/u01/oracle/oradata/ORCL/mytbs301.dbf' size 500M extent management local uniform;
Tablespace created. --省略后面的size 表示区等长大小每个1M
###########################################################################################
五、大文件表空间
前面的表空间都是小文件表空间,8K大小数据块情况下,数据文件的上限是32G。从oralce10g版本开始,引入大文件表空间,数据文件上限是32T
SQL> create bigfile tablespace mybigtbs datafile '/u01/oracle/oradata/ORCL/mybigtbs01.dbf' size 2G;
Tablespace created. --oracle公司的限制,一旦创建大文件表空间,就只能创建一个数据文件
SQL> alter tablespace mybigtbs add datafile '/u01/oracle/oradata/ORCL/mybigtbs201.dbf' size 2G;
alter tablespace mybigtbs add datafile '/u01/oracle/oradata/ORCL/mybigtbs201.dbf' size 2G
*
ERROR at line 1:
ORA-32771: cannot add file to bigfile tablespace --不能添加文件到大文件表空间
SQL> select tablespace_name,bigfile from dba_tablespaces;
TABLESPACE_NAME BIG
------------------------------ ---
SYSTEM NO
UNDOTBS1 NO
SYSAUX NO
TEMP NO
USERS NO
EXAMPLE NO
PLSQL NO
MYTBS2 NO
MYTBS3 NO
MYBIGTBS YES --大文件表空间的标志
10 rows selected.
SQL> desc dba_tablespaces
Name Null? Type
----------------------------------------- -------- ----------------------------
TABLESPACE_NAME NOT NULL VARCHAR2(30) --表空间名字
BLOCK_SIZE NOT NULL NUMBER --块大小
INITIAL_EXTENT NUMBER --表空间创建段的时候初始情况下区的大小
NEXT_EXTENT NUMBER --段的下一个区的大小
MIN_EXTENTS NOT NULL NUMBER --段中最少一个区
MAX_EXTENTS NUMBER --段中最大的区
PCT_INCREASE NUMBER --oracle10g中是废弃的参数
MIN_EXTLEN NUMBER --区的最小值
STATUS VARCHAR2(9) --表空间状态
CONTENTS VARCHAR2(9) --PERMANENT数据表空间 UNDO表空间 TEMPORARY临时表空间
LOGGING VARCHAR2(9) --表空间的事务是否写日志
FORCE_LOGGING VARCHAR2(3)
EXTENT_MANAGEMENT VARCHAR2(10) --管理方式是本地的
ALLOCATION_TYPE VARCHAR2(9) --区的分配方法:SYSTEM 自动分配区的算法 UNIFORM 创建者自己指定的区大小
PLUGGED_IN VARCHAR2(3) --
SEGMENT_SPACE_MANAGEMENT VARCHAR2(6) --段管理方式:SYSTEM SYSAUX TEMP都是手动管理方式,其他的都是自动管理方式
DEF_TAB_COMPRESSION VARCHAR2(8) --是否是数据压缩方式存储
RETENTION VARCHAR2(11)
BIGFILE VARCHAR2(3) --大文件标志
###########################################################################################
六、本地管理表空间的方法
SQL> desc dba_tablespaces
Name Null? Type
----------------------------------------- -------- ----------------------------
TABLESPACE_NAME NOT NULL VARCHAR2(30) --表空间名字
BLOCK_SIZE NOT NULL NUMBER --块大小
INITIAL_EXTENT NUMBER --表空间创建段的时候初始情况下区的大小
NEXT_EXTENT NUMBER --段的下一个区的大小
MIN_EXTENTS NOT NULL NUMBER --段中最少一个区
MAX_EXTENTS NUMBER --段中最大的区
PCT_INCREASE NUMBER --oracle10g中是废弃的参数
MIN_EXTLEN NUMBER --区的最小值
STATUS VARCHAR2(9) --表空间状态
CONTENTS VARCHAR2(9) --PERMANENT数据表空间 UNDO表空间 TEMPORARY临时表空间
LOGGING VARCHAR2(9) --表空间的事务是否写日志
FORCE_LOGGING VARCHAR2(3)
EXTENT_MANAGEMENT VARCHAR2(10) --管理方式是本地的
ALLOCATION_TYPE VARCHAR2(9) --区的分配方法:SYSTEM 自动分配区的算法 UNIFORM 创建者自己指定的区大小
PLUGGED_IN VARCHAR2(3) --
SEGMENT_SPACE_MANAGEMENT VARCHAR2(6) --段管理方式:SYSTEM SYSAUX TEMP都是手动管理方式,其他的都是自动管理方式
DEF_TAB_COMPRESSION VARCHAR2(8) --是否是数据压缩方式存储
RETENTION VARCHAR2(11)
BIGFILE VARCHAR2(3) --大文件标志
1、创建表空间的时候指定关于extent的扩展方式
create tablespace mytbs1 datafile '/u01/oracle/oradata/ORCL/mytbs101.dbf' size 500M (extent management local autoallocate); --本地管理方式,增长方式为自动增长
区的使用是靠数据文件头的位图来控制的,位图在数据文件中,理解为本地。
create tablespace mytbs1 datafile '/u01/oracle/oradata/ORCL/mytbs101.dbf' size 500M (extent management local uniform size xxxxx); --区的扩展方式为等量增长
2、创建表空间的时候可以设置数据文件的扩展方式
SQL> create tablespace mytbs4 datafile '/u01/oracle/oradata/ORCL/mytbs401.dbf' size 10M autoextend on next 1M maxsize 3G;
Tablespace created. --设置为数据文件自动扩展,每次扩展1M,到3G为止
可以既指定区的扩展方式,又指定数据文件的扩展方式
SQL> create tablespace mytbs5 datafile '/u01/oracle/oradata/ORCL/mytbs501.dbf' size 10M autoextend on next 1M maxsize 3G extent management local uniform size 2M;
Tablespace created.
设置数据文件扩展无上限(上限是32G) --oracle表空间文件硬限制
SQL> create tablespace mytbs4 datafile '/u01/oracle/oradata/ORCL/mytbs401.dbf' size 10M autoextend on next 1M maxsize unlimited;
Tablespace created. --不建议,因为磁盘空间处在不安全状态。
SQL> select file_id,autoextensible from dba_data_files; --文件扩展方式
FILE_ID AUT
---------- ---
4 YES
3 YES
2 YES
1 YES
5 YES
6 NO
7 NO
8 NO
9 NO
10 NO
11 YES
12 YES
12 rows selected.
select * from dba_data_files --文件自动扩展的参数
文件的扩展方式可以随意去调整
SQL> alter database datafile 12 autoextend off; --文件大小关闭的时候是多大就是多大,用完为止
Database altered.
SQL> alter database datafile 12 autoextend on;
Database altered.
SQL> alter database datafile 12 autoextend off;
Database altered.
SQL> alter database datafile 12 autoextend on next 5M maxsize 10G;
Database altered.
###########################################################################################
七、创建非标准块大小的表空间
1、先创建非标准块大小的内存区域,要有这个内存空间才能创建这个非标准块,否则报错
ORA-29339: tablespace block size 4096 does not match configured block sizes
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_4k_cache_size big integer 0
改spfile参数后:
SQL> show parameter 4k
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_4k_cache_size big integer 32M
2、创建4K大小数据块的表空间
SQL> create tablespace my4ktbs blocksize 4k datafile '/u01/oracle/oradata/ORCL/my4ktbs.dbf' size 300M;
Tablespace created.
SQL> select tablespace_name,block_size from dba_tablespaces;
TABLESPACE_NAME BLOCK_SIZE
------------------------------ ----------
SYSTEM 8192
UNDOTBS1 8192
SYSAUX 8192
TEMP 8192
USERS 8192
EXAMPLE 8192
PLSQL 8192
MYTBS2 8192
MYTBS3 8192
MYBIGTBS 8192
MYTBS4 8192
MYTBS5 8192
MY4KTBS 4096
13 rows selected.
###########################################################################################
八、用户默认的表空间
创建表的时候不指定表空间的话,默认用用户缺省的表空间
select username,default_tablespace from dba_users where username='SCOTT' --USERS
创建表时候指定了表空间,就用指定的表空间
SQL> create table xyt (x int) tablespace mytbs4;
Table created.
select * from dba_tables where owner='SCOTT' --查询表对应的表空间
将用户默认的表空间修改
SQL> conn /as sysdba
Connected.
SQL> alter user scott default tablespace mytbs2; --仅仅是政策的修改
User altered.
scott下所有的表对应表空间是不会变化的。因为数据已经进入数据文件成了既定的事实,无法修改。
SQL> conn scott/scott
Connected.
SQL> create table xyz(x number);
Table created. --此时是MYTBS2
用户默认的表空间从哪里来的。
SQL> conn /as sysdba
Connected.
SQL> create user xp identified by xp default tablespace mytbs4;
User created.
如果不指定,发现默认的表空间是USERS
SQL> drop user xp;
User dropped.
SQL> create user xp identified by xp; 继承数据库默认的数据表空间给用户作为默认的数据表空间
User created.
select * from database_properties where property_name='DEFAULT_PERMANENT_TABLESPACE' --USERS
系统默认的数据表空间是不能删除的
SQL> drop tablespace users including contents and datafiles;
drop tablespace users including contents and datafiles
*
ERROR at line 1:
ORA-12919: Can not drop the default permanent tablespace
修改系统默认的数据表空间
SQL> alter database default tablespace mytbs5;
Database altered. --发现其他用户从数据库默认表空间继承过来的默认表空间都会变化。不建议操作。
SQL> alter database default tablespace users;
Database altered.
###########################################################################################
九、用户的临时表空间
作用
A PGA--支撑运算(hash 、sort、 bitmap merge),如果PGA区域不够用,计算空间会借用临时表空间--临时文件
B 可以在临时表空间上创建临时表,但是临时表的数据是不会永久保存的,当事务结束的时候,临时表的数据会自动清空
select username,temporary_tablespace from dba_users --当前数据库只有一个临时表空间TEMP,所有用户都用TEMP
SQL> select * from database_properties where property_name='DEFAULT_TEMP_TABLESPACE';
PROPERTY_NAME PROPERTY_VALUE
-----------------------------------------------
DEFAULT_TEMP_TABLESPACE TEMP --系统默认的临时表空间
SQL> create user xp identified by xp default tablespace mytbs2 temporary tablespace temp;
User created. --如果不指定就用系统默认的
创建临时表空间
SQL> create temporary tablespace temp01 tempfile '/u01/oracle/oradata/ORCL/temp101.dbf' size 300M;
Tablespace created.
select * from dba_temp_files --两个临时表空间
用户默认的临时表空间可以修改
SQL> alter user xp temporary tablespace temp01;
User altered.
数据库默认的临时表空间也可以修改
SQL> alter database default temporary tablespace temp01;
Database altered.
SQL> alter database default temporary tablespace temp;
Database altered.
数据库上所有的临时表空间都可以删除,暂时不报错,但是要用到的时候发现没有,就会报错了。
SQL> alter user scott temporary tablespace temp01;
User altered.
SQL> conn /as sysdba
Connected.
SQL> drop tablespace temp01 including contents and datafiles;
Tablespace dropped.
SQL> conn scott/scott
Connected.
SQL> create table testa as select * from all_objects;
Table created.
SQL> create table testb as select * from all_objects;
Table created.
SQL> select * from testa a,testb b order by 1,2,3,4,5,6,7,8,9,10;
select * from testa a,testb b order by 1,2,3,4,5,6,7,8,9,10
--大量的排序算法,PGA空间不够,会用临时表空间
*
ERROR at line 1:
ORA-00959: tablespace 'TEMP01' does not exist
SQL> conn /as sysdba
Connected.
SQL> alter user scott temporary tablespace temp; --改回去
User altered.
SQL> conn scott/scott
Connected.
SQL> select * from testa a,testb b order by 1,2,3,4,5,6,7,8,9,10; --此时不报错
###########################################################################################
十、UNDO 表空间--为了保护数据的一致性而存储数据旧的镜像的表空间
感受一些数据一致性的控制
当修改数据未提交的时候,修改的进程直接修改数据块,这个数据库块的旧的镜像被转移到UNDO中存储,此时没有提交的时候为了防止其他用户修改发生错乱,这个行会被加锁,如果查询这个数据的话,发现有锁,就直接到UNDO中去查询数据的旧的镜像。
一个数据库只能有一个UNDO是有效的。
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO --UNDO的管理方式:AUTO
undo_retention integer 900 --undo数据在undo段中保留的最大时间为900s
undo_tablespace string UNDOTBS1 --当前数据库默认的undo表空间
SQL> select * from v$rollname;
USN NAME
---------- ------------------------------
0 SYSTEM --第一个undo段在系统表空间上SYSTEM,系统用户使用的undo空间,系统事务用 的,例如操作数据字典的系统层面的回滚段
-----------------------------------------
1 _SYSSMU1$
2 _SYSSMU2$
3 _SYSSMU3$
4 _SYSSMU4$
5 _SYSSMU5$
6 _SYSSMU6$
7 _SYSSMU7$
8 _SYSSMU8$
9 _SYSSMU9$
10 _SYSSMU10$ --是在UNDO表空间上的UNDOTBS1
11 rows selected.
undo_retention--从事务结束之后(commit或者rollback之后),旧的数据在undo保存的最大时间是900s,但是这个不是硬性限制,当UNDO空间不够用的时候,这个空间是有可能在900s内被覆盖的。
select * from v$rollstat --UNDO段使用的统计情况
UNDO段空间不足的时候需要加数据文件扩容
比如:修改了20G数据,但是此时UNDO段只有10G,旧的镜像空间是不足的,此时会发生ORA-01555的错误,此时需要扩容UNDO 表空间
案例:修改(切换)当前数据库的UNDO表空间
1、创建一个新的UNDO 表空间
SQL> create undo tablespace undotbs2 datafile '/u01/oracle/oradata/ORCL/undo02.dbf' size 2G;
Tablespace created.
2、切换
alter tablespace undotbs1 offline; --回滚没有提交的数据
SQL> alter system set undo_tablespace=undotbs2 scope=both;
System altered.
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS2
3、删除旧的
SQL> drop tablespace undotbs1 including contents and datafiles;
Tablespace dropped.
4、扩容
SQL> alter tablespace undotbs2 add datafile '/u01/oracle/oradata/ORCL/undotbs201.dbf' size 500M;
Tablespace altered.
SQL> select * from v$rollname;
USN NAME
---------- ------------------------------
0 SYSTEM --系统回滚段在SYSTEM表空间中是不会变化的
11 _SYSSMU11$ --跟之前相比变了11-20
12 _SYSSMU12$
13 _SYSSMU13$
14 _SYSSMU14$
15 _SYSSMU15$
16 _SYSSMU16$
17 _SYSSMU17$
18 _SYSSMU18$
19 _SYSSMU19$
20 _SYSSMU20$
11 rows selected.
练习:
1、创建一个表空间(区大小是4M,数据文件自动增长,步长1M,上限是500M)和临时表空间(大小300M)。
2、创建一个用户ZCL,指定上面的表空间和临时表空间为这个用户的默认的表空间和临时表空间
3、切换这个用户ZCL的临时表空间和数据表空间到TEMP和USERS
4、切换数据库的UNDO表空间到UNDOTBS上(2GB)
5、再给这个UNDO表空间扩容到2.5GB
----------------------------------------------------------------------------------------------------------------
###########################################################################################
临时表空间组(10g)
需求:创建两个临时表空间组
组名 表空间 数据文件
------------------------------------------------------------------------------------
grp1 tempa tempb tempa01.dbf tempa02.dbf tempb01.dbf tempb02.dbf
grp2 tempc tempd tempc01.dbf tempc02.dbf tempd01.dbf tempd02.dbf
--------------------------------------------------------------------------------------
1、创建临时表空间tempa tempb tempc tempd 并添加到组
SQL> create temporary tablespace tempa tempfile '/u01/oracle/oradata/ORCL/tempa01.dbf' size 200M,'/u01/oracle/oradata/ORCL/tempa02.dbf' size 200M tablespace group grp1;
Tablespace created.
SQL> create temporary tablespace tempb tempfile '/u01/oracle/oradata/ORCL/tempb01.dbf' size 200M,'/u01/oracle/oradata/ORCL/tempb02.dbf' size 200M tablespace group grp1;
Tablespace created.
SQL> create temporary tablespace tempc tempfile '/u01/oracle/oradata/ORCL/tempc01.dbf' size 200M,'/u01/oracle/oradata/ORCL/tempc02.dbf' size 200M tablespace group grp2;
Tablespace created.
SQL> create temporary tablespace tempd tempfile '/u01/oracle/oradata/ORCL/tempd01.dbf' size 200M,'/u01/oracle/oradata/ORCL/tempd02.dbf' size 200M tablespace group grp2;
Tablespace created.
确认:
select a.group_name,a.tablespace_name,b.file_name from dba_tablespace_groups a,dba_temp_files b
where a.tablespace_name = b.tablespace_name
2、创建用户的时候可以指定临时表空间组
SQL> create user zcl identified by zcl temporary tablespace grp1;
User created.
3、切换现有的用户临时表空间到临时表空间组
SQL> alter user zcl temporary tablespace grp2;
User altered.
select * from dba_users --确认
4、将数据库默认的临时表空间切换到临时表空间组上
SQL> alter database default temporary tablespace grp1;
Database altered.
5、将已经有的临时表空间从一个组移动到另外一个组
SQL> alter tablespace tempb tablespace group grp2;
Tablespace altered.
6、将已经建好的临时表空间添加到组
SQL> alter tablespace temp tablespace group grp1;
Tablespace altered.
7、扩容临时表空间组:直接给表空间加临时文件即可
8、删除临时表空间组:直接删除掉对应的临时表空间即可
总结:临时表空间组就是一个逻辑分组的概念,不是一个表空间对象。目的是为了让临时表空间资源在用户之间分开不争用。
###########################################################################################
十一、oracle的三级位图技术--深入剖析表空间本地管理方式
1、创建一个测试表空间
SQL> conn /as sysdba
Connected.
SQL> create tablespace henry datafile '/u01/oracle/oradata/ORCL/henry01.dbf' size 100M extent management local uniform;
Tablespace created.
2、授权给用户
SQL> grant dba to scott;
Grant succeeded.
SQL> conn scott/scott
Connected.
3、创建一个测试段
SQL> create table test(a varchar2(10)) tablespace henry;
Table created.
4、查询视图
select * from dba_extents where owner='SCOTT' and segment_name='TEST' order by block_id --现在有一个extent
区的数据从文件的块9开始
1~8块数据是什么? 一个8K数据块大小的数据文件预留前8个块作为文件头
5、将数据块1~3 dump出来
SQL> alter system dump datafile 15 block min 1 block max 3;
System altered.
[oracle@oracle3 udump]$ pwd
/u01/oracle/admin/ORCL/udump --这目录中存储的是server processes进程的跟踪文件,一个进程结束,这个文件的写入就结束。重新连接的话,会产生新的跟踪文件
找到最近的跟踪文件
Start dump data blocks tsn: 22 file#: 15 minblk 1 maxblk 3
Block 1 (file header) not dumped: use dump file header command --数据块1没有dump出来
------------
buffer tsn: 22 rdba: 0x03c00002 (15/2) --文件15的块2
scn: 0x0000.002839ee seq: 0x02 flg: 0x00 tail: 0x39ee1d02
frmt: 0x02 chkval: 0x0000 type: 0x1d=KTFB Bitmapped File Space Header --位图文件空间头
Hex dump of block: st=0, typ_found=1
---------------------------------------------------------------
File Space Header Block:
Header Control:
RelFno: 15, Unit: 128, Size: 12800, Flag: 1
AutoExtend: NO, Increment: 0, MaxSize: 0
Initial Area: 7, Tail: 12680, First: 1, Free: 98
Deallocation scn: 0.0
Header Opcode:
Save: No Pending Op
--------------------------------------------------------------------
buffer tsn: 22 rdba: 0x03c00003 (15/3)
scn: 0x0000.002839ee seq: 0x01 flg: 0x00 tail: 0x39ee1e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap --位图文件的空间位图
Hex dump of block: st=0, typ_found=1
File Space Bitmap Block:
BitMap Control: --位图控制句柄
RelFno: 15, BeginBlock: 9, Flag: 0, First: 1, Free: 63487
0100000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
........
End dump data blocks tsn: 22 file#: 15 minblk 2 maxblk 3
01 一组(16进制) = 0000 0001
每8个bytes为一组,组和组之间是从左往右读,组内是从右往左读
读取:1000 0000 表示当前extent使用是:userd free free free free free free free
6、手工分配一个区
SQL> alter table test allocate extent;
Table altered.
SQL> alter system dump datafile 15 block 3;
System altered.
File Space Bitmap Block:
BitMap Control:
RelFno: 15, BeginBlock: 9, Flag: 0, First: 2, Free: 63486
0300000000000000 0000000000000000 0000000000000000 0000000000000000
03=0000 0011 反过来:1100 0000 used used free free free free free free
手动分配4个区
SQL> alter table test allocate extent;
Table altered.
SQL> alter table test allocate extent;
Table altered.
SQL> alter table test allocate extent;
Table altered.
SQL> alter table test allocate extent;
Table altered.
SQL> alter system dump datafile 15 block 3;
System altered.
File Space Bitmap Block:
BitMap Control:
RelFno: 15, BeginBlock: 9, Flag: 0, First: 6, Free: 63482
3F00000000000000 0000000000000000 0000000000000000 0000000000000000
3F= 0011 1111 反过来:1111 1100 used used used used used used free free
块3~8全部是位图,分解后按照区的大小加乘就是文件的上限32G。这个位图仅仅是记录已经格式化过的区。
---------------------------------------------------------------------------------------------
研究下文件的第9个块
SQL> alter system dump datafile 15 block 9;
System altered.
*** 2014-06-25 15:10:28.120
Start dump data blocks tsn: 22 file#: 15 minblk 9 maxblk 9
buffer tsn: 22 rdba: 0x03c00009 (15/9)
scn: 0x0000.00283ce2 seq: 0x01 flg: 0x04 tail: 0x3ce22001
frmt: 0x02 chkval: 0x75c5 type: 0x20=FIRST LEVEL BITMAP BLOCK --一级位图块
Hex dump of block: st=0, typ_found=1
Dump of First Level Bitmap Block
--------------------------------
nbits : 4 nranges: 1 parent dba: 0x03c0000b -父块的物理地址parent data block address
poffset: 0
unformatted: 60 total: 64 first useful block: 4
owning instance : 1
instance ownership changed at
Last successful Search
Freeness Status: nf1 0 nf2 0 nf3 0 nf4 0
Extent Map Block Offset: 4294967295
First free datablock : 4
Bitmap block lock opcode 0
Locker xid: : 0x0000.000.00000000
Inc #: 0 Objd: 57927
HWM Flag: Not Set
Highwater:: 0x03c0000d ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x03c00009 Length: 64 Offset: 0
0:Metadata 1:Metadata 2:Metadata 3:Metadata --元数据:块9、10、11、12
4:unformatted 5:unformatted 6:unformatted 7:unformatted 没有格式化
8:unformatted 9:unformatted 10:unformatted 11:unformatted
12:unformatted 13:unformatted 14:unformatted 15:unformatted
16:unformatted 17:unformatted 18:unformatted 19:unformatted
20:unformatted 21:unformatted 22:unformatted 23:unformatted
24:unformatted 25:unformatted 26:unformatted 27:unformatted
28:unformatted 29:unformatted 30:unformatted 31:unformatted
32:unformatted 33:unformatted 34:unformatted 35:unformatted
36:unformatted 37:unformatted 38:unformatted 39:unformatted
40:unformatted 41:unformatted 42:unformatted 43:unformatted
44:unformatted 45:unformatted 46:unformatted 47:unformatted
48:unformatted 49:unformatted 50:unformatted 51:unformatted
52:unformatted 53:unformatted 54:unformatted 55:unformatted
56:unformatted 57:unformatted 58:unformatted 59:unformatted
60:unformatted 61:unformatted 62:unformatted 63:unformatted
--------------------------------------------------------
End dump data blocks tsn: 22 file#: 15 minblk 9 maxblk 9
--------------------------------------------------------
DBA Ranges : --块10的64个位置标示的是块73~136
--------------------------------------------------------
0x03c00049 Length: 64 Offset: 0
0:unformatted 1:unformatted 2:unformatted 3:unformatted
4:unformatted 5:unformatted 6:unformatted 7:unformatted
8:unformatted 9:unformatted 10:unformatted 11:unformatted
12:unformatted 13:unformatted 14:unformatted 15:unformatted
16:unformatted 17:unformatted 18:unformatted 19:unformatted
20:unformatted 21:unformatted 22:unformatted 23:unformatted
24:unformatted 25:unformatted 26:unformatted 27:unformatted
28:unformatted 29:unformatted 30:unformatted 31:unformatted
32:unformatted 33:unformatted 34:unformatted 35:unformatted
36:unformatted 37:unformatted 38:unformatted 39:unformatted
40:unformatted 41:unformatted 42:unformatted 43:unformatted
44:unformatted 45:unformatted 46:unformatted 47:unformatted
48:unformatted 49:unformatted 50:unformatted 51:unformatted
52:unformatted 53:unformatted 54:unformatted 55:unformatted
56:unformatted 57:unformatted 58:unformatted 59:unformatted
60:unformatted 61:unformatted 62:unformatted 63:unformatted
--------------------------------------------------------
End dump data blocks tsn: 22 file#: 15 minblk 10 maxblk 10
create or replace function getfbin(p_dba in varchar2) return varchar2 is
l_str varchar2(255) default null;
begin
l_str:='datafile is '||dbms_utility.data_block_address_file(to_number(ltrim(p_dba,'0x'),'xxxxxxxx'))||chr(10)||
' datablock is '||dbms_utility.data_block_address_block(to_number(ltrim(p_dba,'0x'),'xxxxxxxx'));
return l_str;
exception when others then
return '';
end;
select getfbin('0x03c0000b') from dual; --文件15块11
SQL> alter system dump datafile 15 block 11;
System altered.
Start dump data blocks tsn: 22 file#: 15 minblk 11 maxblk 11
buffer tsn: 22 rdba: 0x03c0000b (15/11)
scn: 0x0000.00283ce5 seq: 0x04 flg: 0x04 tail: 0x3ce52104
frmt: 0x02 chkval: 0x655d type: 0x21=SECOND LEVEL BITMAP BLOCK ==二级位图块
Hex dump of block: st=0, typ_found=1
Dump of Second Level Bitmap Block
number: 2 nfree: 2 ffree: 0 pdba: 0x03c0000c --父块地址
Inc #: 0 Objd: 57927
opcode:2
xid:
L1 Ranges : level 1的范围
--------------------------------------------------------
0x03c00009 Free: 5 Inst: 1 块9
0x03c0000a Free: 5 Inst: 1 块10
--------------------------------------------------------
End dump data blocks tsn: 22 file#: 15 minblk 11 maxblk 11
12--11--9
10
137
138
二级位图块中存一级位图块范围。
三级位图块存储二级位图块和一级位图块的混合视图
SQL> alter system dump datafile 15 block 12;
System altered.
Start dump data blocks tsn: 22 file#: 15 minblk 12 maxblk 12
buffer tsn: 22 rdba: 0x03c0000c (15/12)
scn: 0x0000.00283cea seq: 0x01 flg: 0x04 tail: 0x3cea2301
frmt: 0x02 chkval: 0x49e4 type: 0x23=PAGETABLE SEGMENT HEADER --三级位图块--页表段头
Hex dump of block: st=0, typ_found=1----------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 128
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c0000d ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c0000d ext#: 0 blk#: 4 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Level 1 BMB for High HWM block: 0x03c00009
Level 1 BMB for Low HWM block: 0x03c00009
--------------------------------------------------------
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
L2 Array start offset: 0x00001434
First Level 3 BMB: 0x00000000
L2 Hint for inserts: 0x03c0000b
Last Level 1 BMB: 0x03c0000a
Last Level II BMB: 0x03c0000b
Last Level III BMB: 0x00000000
Map Header:: next 0x00000000 #extents: 1 obj#: 57927 flag: 0x10000000
Inc # 0
Extent Map 区的映射
-----------------------------------------------------------------
0x03c00009 length: 128 块9
Auxillary Map --辅助映射图
--------------------------------------------------------
Extent 0 : L1 dba: 0x03c00009 块9是一级位图块 Data dba: 0x03c0000d 数据从13开始
--------------------------------------------------------
Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x03c0000b
End dump data blocks tsn: 22 file#: 15 minblk 12 maxblk 12
块137和138已经是第二个区的数据:
--------------------------------------------------------
DBA Ranges : 块137
--------------------------------------------------------
0x03c00089 Length: 64 Offset: 0
0:Metadata 1:Metadata 2:unformatted 3:unformatted --metadata是自己137和138
4:unformatted 5:unformatted 6:unformatted 7:unformatted
8:unformatted 9:unformatted 10:unformatted 11:unformatted
12:unformatted 13:unformatted 14:unformatted 15:unformatted
16:unformatted 17:unformatted 18:unformatted 19:unformatted
20:unformatted 21:unformatted 22:unformatted 23:unformatted
24:unformatted 25:unformatted 26:unformatted 27:unformatted
28:unformatted 29:unformatted 30:unformatted 31:unformatted
32:unformatted 33:unformatted 34:unformatted 35:unformatted
36:unformatted 37:unformatted 38:unformatted 39:unformatted
40:unformatted 41:unformatted 42:unformatted 43:unformatted
44:unformatted 45:unformatted 46:unformatted 47:unformatted
48:unformatted 49:unformatted 50:unformatted 51:unformatted
52:unformatted 53:unformatted 54:unformatted 55:unformatted
56:unformatted 57:unformatted 58:unformatted 59:unformatted
60:unformatted 61:unformatted 62:unformatted 63:unformatted
--------------------------------------------------------
--------------------------------------------------------
DBA Ranges : --块138
--------------------------------------------------------
0x03c000c9 Length: 64 Offset: 0
0:unformatted 1:unformatted 2:unformatted 3:unformatted
4:unformatted 5:unformatted 6:unformatted 7:unformatted
8:unformatted 9:unformatted 10:unformatted 11:unformatted
12:unformatted 13:unformatted 14:unformatted 15:unformatted
16:unformatted 17:unformatted 18:unformatted 19:unformatted
20:unformatted 21:unformatted 22:unformatted 23:unformatted
24:unformatted 25:unformatted 26:unformatted 27:unformatted
28:unformatted 29:unformatted 30:unformatted 31:unformatted
32:unformatted 33:unformatted 34:unformatted 35:unformatted
36:unformatted 37:unformatted 38:unformatted 39:unformatted
40:unformatted 41:unformatted 42:unformatted 43:unformatted
44:unformatted 45:unformatted 46:unformatted 47:unformatted
48:unformatted 49:unformatted 50:unformatted 51:unformatted
52:unformatted 53:unformatted 54:unformatted 55:unformatted
56:unformatted 57:unformatted 58:unformatted 59:unformatted
60:unformatted 61:unformatted 62:unformatted 63:unformatted
--------------------------------------------------------
创建测试数据
SQL> insert into test select object_id from dba_objects;
50821 rows created.
SQL> commit;
Commit complete.
SQL> alter system dump datafile 15 block 9;
System altered.
--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x03c00009 Length: 64 Offset: 0
0:Metadata 1:Metadata 2:Metadata 3:Metadata
4:FULL 5:FULL 6:FULL 7:FULL
8:FULL 9:FULL 10:FULL 11:FULL
12:FULL 13:FULL 14:FULL 15:FULL
16:FULL 17:FULL 18:FULL 19:FULL
20:FULL 21:FULL 22:FULL 23:FULL
24:FULL 25:FULL 26:FULL 27:FULL
28:FULL 29:FULL 30:FULL 31:FULL
32:FULL 33:FULL 34:FULL 35:FULL
36:FULL 37:FULL 38:FULL 39:FULL
40:FULL 41:FULL 42:FULL 43:FULL
44:FULL 45:FULL 46:FULL 47:FULL
48:FULL 49:FULL 50:FULL 51:FULL
52:FULL 53:FULL 54:FULL 55:FULL
56:FULL 57:FULL 58:FULL 59:FULL
60:FULL 61:FULL 62:FULL 63:FULL
--------------------------------------------------------
块10:
--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x03c00049 Length: 64 Offset: 0
0:FULL 1:75-100% free 2:75-100% free 3:75-100% free
4:FULL 5:75-100% free 6:75-100% free 7:75-100% free
8:0-25% free 9:75-100% free 10:75-100% free 11:75-100% free
12:75-100% free 13:75-100% free 14:75-100% free 15:75-100% free
16:75-100% free 17:75-100% free 18:75-100% free 19:75-100% free
20:75-100% free 21:75-100% free 22:75-100% free 23:75-100% free
24:75-100% free 25:75-100% free 26:75-100% free 27:FULL
28:FULL 29:75-100% free 30:75-100% free 31:FULL
32:FULL 33:75-100% free 34:75-100% free 35:FULL
36:FULL 37:75-100% free 38:75-100% free 39:FULL
40:FULL 41:75-100% free 42:75-100% free 43:FULL
44:75-100% free 45:75-100% free 46:75-100% free 47:FULL
48:75-100% free 49:75-100% free 50:75-100% free 51:FULL
52:75-100% free 53:75-100% free 54:75-100% free 55:FULL
56:75-100% free 57:75-100% free 58:75-100% free 59:FULL
60:75-100% free 61:75-100% free 62:75-100% free 63:FULL
--------------------------------------------------------
结论:数据块的状态 unformated
0~25% free
25~50% free
50~75% free
75~100% free
FULL
当插入数据时候从三级位图中找空闲块插入数据的。
三级位图技术--段的自动管理方式。
SQL> select tablespace_name,segment_space_management from dba_tablespaces;
TABLESPACE_NAME SEGMEN
------------------------------ ------
SYSTEM MANUAL
SYSAUX AUTO
TEMP MANUAL
USERS AUTO
UNDOTBS2 MANUAL
EXAMPLE AUTO
PLSQL AUTO
MYTBS2 AUTO --自动管理方式就是ASSM(auto segment space management)
MYTBS3 AUTO
MYBIGTBS AUTO
MYTBS4 AUTO
MYTBS5 AUTO
MY4KTBS AUTO
TEMPA MANUAL
TEMPB MANUAL
TEMPC MANUAL
TEMPD MANUAL
HENRY AUTO
18 rows selected.
MANUAL--手工管理方式。
找空闲数据块时候,根据freelist(段的属性)中的块来找,内存中的一个链表
--------------------------FREE list
数据块有两个参数:PCTFREE PCTUSED
10 40
A 当数据块的使用量超过90的时候,认为块满了,从freelist上拿掉
B 当删除数据删除的数据少于40%的时候,认为是空闲块。
C server processes会将空块和少于40%空间的块按需放到freelist上
D 当对空间有需求的时候,进程从freelist上拿数据来操作的。
FREElist GROUP -治标不治本的
PCTFREE--1、判断是否是满块 ,A 行不能跨块的 B 当update某个字段时候,可能行会变长,一块存不下一行了,发生行迁移,这个是影响性能的
2、判断是否从freelist上拿下来 。不用
SQL> select dbms_metadata.get_ddl('TABLE','EMP') from dual;
DBMS_METADATA.GET_DDL('TABLE','EMP')
--------------------------------------------------------------------------------
CREATE TABLE "SCOTT"."EMP"
( "EMPNO" NUMBER(4,0),
"ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0),
CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO") USING INDEX
PCTFREE 10
INITRANS 2 --索引数据块初始化打开的事务槽数
MAXTRANS 255 --索引数据块最大支撑255个进程访问
COMPUTE STATISTICS --采集收集性能数据
存储参数
STORAGE(INITIAL 65536 --第一个extent的大小
NEXT 1048576 --下一类区的大小
MINEXTENTS 1 --最少一个extent
MAXEXTENTS 2147483645 --最多的区数
PCTINCREASE 0 --区的增长百分比,ASSM下是废弃的参数
FREELISTS 1 --ASSM下是废弃的参数
FREELIST GROUPS 1 --ASSM下是废弃的参数
BUFFER_POOL DEFAULT) --指定主键索引使用的缓冲区是缺省的缓冲区
TABLESPACE "USERS" ENABLE,
CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "SCOTT"."DEPT" ("DEPTNO") ENABLE --外键
) PCTFREE 10 --表段的PCTFREE参数
PCTUSED 40 --ASSM下是废弃的参数
INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS 2147483645
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT) --指定表使用的缓冲区是缺省的缓冲区
TABLESPACE "USERS"
###########################################################################################
十二:表空间扩展
方法1:直接给表空间添加数据文件
方法2:将数据文件设置为自动扩展
A 创建表空间的时候指定数据文件是自动扩展的
B 改变数据文件为自动扩展
方法3:resize方法
SQL> alter database datafile 15 resize 200M;
Database altered.
SQL> alter database datafile 15 resize 100M;
Database altered.
SQL> alter database datafile 15 resize 5M;
alter database datafile 15 resize 5M
*
ERROR at line 1:
ORA-03297: file contains used data beyond requested RESIZE value --缩小的时候不能影响已经有的数据的存储
SQL> alter database datafile 15 resize 20M;
Database altered.
###########################################################################################
十三、限制用户对表空间访问
需求:显限制用户HR只能使用表空间MYTBS2空间中10M的空间
SQL> conn scott/scott
Connected.
SQL> alter user hr quota 10M on henry;
User altered.
SQL> conn hr/hr
Connected.
SQL> create table test tablespace henry as select * from all_objects;
Table created.
SQL> insert into test select * from all_objects;
40914 rows created.
SQL> commit;
Commit complete.
SQL> insert into test select * from all_objects;
40914 rows created.
SQL> commit;
Commit complete.
SQL> insert into test select * from all_objects;
40914 rows created.
SQL> commit;
Commit complete.
select sum(bytes)/1024/1024 from dba_extents where segment_name='TEST' and owner='HR' --19M
SQL> conn scott/scott
Connected.
SQL> select * from dba_sys_privs where grantee='HR';
GRANTEE PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
HR CREATE VIEW NO
HR UNLIMITED TABLESPACE(限制表空间) NO --这个权限会覆盖quota
HR CREATE DATABASE LINK NO
HR CREATE SEQUENCE NO
HR CREATE SESSION NO
HR ALTER SESSION NO
HR CREATE SYNONYM NO
7 rows selected.
SQL> revoke unlimited tablespace from hr; --回收权限
Revoke succeeded.
SQL> conn hr/hr
Connected.
SQL> truncate table test;
Table truncated.
SQL> insert into test select * from all_objects;
40914 rows created.
SQL> commit;
Commit complete.
SQL> insert into test select * from all_objects;
40914 rows created.
SQL> commit;
Commit complete.
SQL> insert into test select * from all_objects;
insert into test select * from all_objects
*
ERROR at line 1:
ORA-01536: space quota exceeded for tablespace 'HENRY' --配额不够了
select sum(bytes)/1024/1024 from dba_extents where segment_name='TEST' and owner='HR' --10M
SQL> conn /as sysdba
Connected.
SQL> alter user hr quota 5M on henry; --再改为5M
User altered.
此时再插入数据是可以的,但是仅仅是将已经开辟的extents的空间填满而已,大小不会超过10M
监控表空间配额的方法:
select username,
tablespace_name,
(case max_bytes
when -1 then
'NULL'
else
to_char(max_bytes / 1024 / 1024 || 'MB')
end) as qutoas
from dba_ts_quotas
##########################################################################################
实操案例:重命名数据文件或者移动数据文件
需求:将数据文件henry01.dbf改名为henry201.dbf
1、将数据文件对应的表空间离线
SQL> conn /as sysdba
Connected.
SQL> alter tablespace henry offline;
Tablespace altered.
2、修改名字
[oracle@oracle3 ORCL]$ mv henry01.dbf henry201.dbf
3、修改数据字典
SQL> alter tablespace henry rename datafile '/u01/oracle/oradata/ORCL/henry01.dbf' to '/u01/oracle/oradata/ORCL/henry201.dbf';
Tablespace altered.
4、将表空间online
SQL> alter tablespace henry online;
Tablespace altered.
练习:在/u01/oracle/oradata/ORCL/下创建一个目录data,将USERS表空间的数据文件移动到data目录下。
###########################################################################################
案例:监控表空间的使用
SQL> desc dba_free_space --表空间剩余空间大小,一行是一个连续的空间,显示的是数据文件空间的剩余大小
Name Null? Type
----------------------------------------- -------- ----------------------------
TABLESPACE_NAME VARCHAR2(30)
FILE_ID NUMBER --文件号
BLOCK_ID NUMBER --连续空间的起始数据块号
BYTES NUMBER --剩余空间
BLOCKS NUMBER
RELATIVE_FNO NUMBER
监控语句:发现表空间不足的要及时扩容
select tbs,
sum(totalM),
sum(usedM),
sum(remaindM),
round(sum(usedM) / sum(totalM), 2) as usedPer,
round(sum(remaindM) / sum(totalM), 2) as remaindPer
from (select b.FILE_ID id,
b.TABLESPACE_NAME tbs,
b.BYTES / 1024 / 1024 totalM,
(b.BYTES - sum(a.BYTES)) / 1024 / 1024 usedM,
sum(a.BYTES) / 1024 / 1024 remaindM
from dba_free_space a, dba_data_files b
where a.FILE_ID = b.FILE_ID
group by b.FILE_ID, b.TABLESPACE_NAME, b.BYTES
order by b.TABLESPACE_NAME)
group by tbs
监控即将用完的表空间是否可以扩容了,如果数据文件是可以自动扩展的,表空间使用率基本上接近于100%的。
建议:将SYSTEM表空间和SYSAUX表空间的文件自动扩展关闭的,防止滥用。
SQL> alter database datafile 1 autoextend off;
Database altered.
SQL> alter database datafile 1 resize 1G;
Database altered.
SQL> alter database datafile 3 autoextend off;
Database altered.
SQL> alter database datafile 3 resize 500M;
Database altered.
做成自动作业:SP 每天查询存储的使用,将结果插入一个表进行监控。
SQL> set long 10000
SQL> select dbms_metadata.get_ddl('TABLESPACE','HENRY') from dual;
DBMS_METADATA.GET_DDL('TABLESPACE','HENRY')
--------------------------------------------------------------------------------
CREATE TABLESPACE "HENRY" DATAFILE
'/u01/oracle/oradata/ORCL/henry201.dbf' SIZE 104857600
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1048576 SEGMENT SPACE MANAGEMENT AUTO --创建语句
ALTER DATABASE DATAFILE '/u01/oracle/oradata/ORCL/henry201.dbf' RESIZE 524288000 --resize语句
###########################################################################################
案例:将表空间设置为只读
SQL> alter tablespace henry read only;
Tablespace altered.
SELECT * FROM dba_tablespaces --status是read only
SQL> alter tablespace henry read write;
Tablespace altered. --设置为可读写
将表空间设置为只读,执行时候,是否有发生完全检查点事件?
SQL> select checkpoint_change#,file# from v$datafile_header where tablespace_name='HENRY';
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2809745 15
SQL> alter tablespace henry read only;
Tablespace altered.
SQL> select checkpoint_change#,file# from v$datafile_header where tablespace_name='HENRY';
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2810026 15 --设置为只读会强制生成检查点,并将这个表空间的脏块写入到数据文件更新数据文件头部
SQL> select checkpoint_change#,file# from v$datafile_header;
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2809745 1
2809745 2
2809745 3
2809745 4
2809745 5
2809745 6
2809745 7
2809745 8
2809745 9
2809745 10
2809745 11
2809745 12
2809745 13
2809745 14 --其他的数据文件是不受影响的
2810026 15
15 rows selected.
SQL> select checkpoint_change#,file# from v$datafile_header where tablespace_name='HENRY';
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2810026 15
SQL> alter tablespace henry read write; --要生成一个完全检查点的,但是没有业务数据更新的,仅仅是完全检查点的更新
Tablespace altered.
SQL> select checkpoint_change#,file# from v$datafile_header where tablespace_name='HENRY';
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2810098 15 --
SQL> select checkpoint_change#,file# from v$datafile_header;
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2809745 1
2809745 2
2809745 3
2809745 4
2809745 5
2809745 6
2809745 7
2809745 8
2809745 9
2809745 10
2809745 11
2809745 12
2809745 13
2809745 14 --其他的文件无影响
2810098 15
15 rows selected.
###########################################################################################
对一个表空间下的一个数据文件进行离线和在线是检查点的变化情况
移动一个表空间下面的个别数据文件
场景:假设这个表空间由10000个数据文件,只是移动其中的1个文件,整个表空间离线的话,导致其他的数据文件上正在进行事务中断,这个操作会导致客户端程序中的数据丢失,这个在生产是严重的事故。
问题1:是否可以对个别数据文件离线 --可以
问题2:假如离线的话,导致一个表空间下数据文件的头部的SCN不一致,怎么处理?--oracle允许一个表空间下的数据文件头部的SCN是不一致的
问题3:离线的数据文件中的数据如果有用户要修改,数据库会怎么处理。--无法修改,但是其他的数据文件是可以操作的
1、给henry表空间添加一个数据文件
SQL> alter tablespace henry add datafile '/u01/oracle/oradata/ORCL/henry202.dbf' size 300M;
Tablespace altered.
select * from dba_data_files where tablespace_name='HENRY' --文件15和16
select * from user_tables --看到表XXXX和TEST在henry表空间上,这两个表一定在文件15上
2、将文件移动
[oracle@oracle3 ORCL]$ mkdir data
[oracle@oracle3 ORCL]$ pwd
/u01/oracle/oradata/ORCL
将文件15 /u01/oracle/oradata/ORCL/henry201.dbf 移动到data下
3、将数据文件离线
SQL> alter database datafile 15 offline;
Database altered.
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2814157 15 --检查点是没有变化的,文件15上有脏块没有写入磁盘的话这个操作也是不会写入的。
2814751 16
SQL> select online_status,file_id from dba_data_files where file_id in(15,16);
ONLINE_STATUS FILE_ID
-------------------- ----------
RECOVER 15 --当前文件状态是恢复状态。如果这个文件在离线过程中,刚才离线之前没有写入文件脏块可能会被覆盖掉
ONLINE 16
尝试在henry表空间上做事务
SQL> insert into test select * from test;
insert into test select * from test
*
ERROR at line 1:
ORA-00376: file 15 cannot be read at this time
ORA-01110: data file 15: '/u01/oracle/oradata/ORCL/henry201.dbf' --离线的文件是不能操作的
SQL> create table tu(x int) tablespace henry;
Table created. --这个表一定在文件16上
4、移动这个文件
[oracle@oracle3 ORCL]$ mv henry201.dbf data/
5、更新数据字典
SQL> alter tablespace henry rename datafile '/u01/oracle/oradata/ORCL/henry201.dbf' to '/u01/oracle/oradata/ORCL/data/henry201.dbf';
Tablespace altered.
6、让这个文件15在线
SQL> alter database datafile 15 online;
alter database datafile 15 online
*
ERROR at line 1:
ORA-01113: file 15 needs media recovery --需要恢复,因为离线时脏块信息没有写进文件,文件头也没变,所以离线后的脏块信息有可能改变了,这是就需要通过redo或归档日志来恢复。
ORA-01110: data file 15: '/u01/oracle/oradata/ORCL/data/henry201.dbf'
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2814157 15
2814751 16
SQL> alter system checkpoint;
System altered.
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2814157 15 --不管外部检查点怎么变化,文件15的检查点是不会变的。
2815197 16
SQL> recover datafile 15; --用归档文件恢复这个文件
Media recovery complete.
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2814861 15 --检查点变了。恢复到丢失的事务检查点为止
2815197 16
SQL> alter database datafile 15 online;
Database altered. --强制生成检查点并写入数据文件
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2815277 15 --有变化,检查点再变,因为online操作会把检查点再更新一次
2815197 16 --无变化,因为没有操作16
###########################################################################################
如果让整个表空间离线,检查点怎样变化?
SQL> alter tablespace henry offline;
Tablespace altered.
SQL> select checkpoint_change#,file# from v$datafile_header where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
0 15
0 16 --文件离线,header就看不到了
SQL> select checkpoint_change#,file# from v$datafile where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2815339 15
2815339 16 --这个值是从控制文件中看到的
整个表空间离线的话,是会强制脏块写入的。
SQL> alter tablespace henry online;
Tablespace altered.
SQL> select checkpoint_change#,file# from v$datafile where file# in(15,16);
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2815396 15
2815396 16
检查点会再一次改变,因为online会引发系统事件,生成新的检查点
表空间的离线和在线是会强制写数据文件的,但是单个数据文件离线是不会写的。将来在线的时候用日志来恢复的。
SQL> select checkpoint_change#,file# from v$datafile_header;
CHECKPOINT_CHANGE# FILE#
------------------ ----------
2815224 1
2815224 2
2815224 3
2815224 4
2815224 5
2815224 6
2815224 7
2815224 8
2815224 9
2815224 10
2815224 11
2815224 12
2815224 13
2815224 14
2815396 15
2815396 16 --这个过程是不影响其他的数据文件的
16 rows selected.
尝试将归档关闭,再做这个操作:
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 1258291200 bytes
Fixed Size 1267260 bytes
Variable Size 301992388 bytes
Database Buffers 922746880 bytes
Redo Buffers 32284672 bytes
Database mounted.
SQL> alter database noarchivelog;
Database altered.
SQL> alter database open;
Database altered.
SQL> alter database datafile 15 offline;
alter database datafile 15 offline
*
ERROR at line 1:
ORA-01145: offline immediate disallowed unless media recovery enabled --不开归档这个操作是没办法做的
因为离线时没有将脏块信息写进数据文件,要在在线是通过redo或者归档日志将已经发生变化的脏块信息写进数据文件,但redo文件只能恢复最近三个redo文件的内容,如果离线时间太长,redo文件的信息将会被覆盖掉,所以必须开启归档模式,来保证当数据文件离线时间过长也能恢复数据。
###########################################################################################
UNDO表空间设置大小的依据
undotablespace = UR*UPS*block_size + 冗余
UR=undo_retention=900s
UPS=整个数据库每秒钟新增的数据块的数量
UPS*block_size=整个数据库每秒钟新增的数据块字节数
UPS=每天数据库的数据增量/24/3600/8192
select tbs,
sum(totalM),
sum(usedM),
sum(remaindM),
round(sum(usedM) / sum(totalM), 2) as usedPer,
round(sum(remaindM) / sum(totalM), 2) as remaindPer
from (select b.FILE_ID id,
b.TABLESPACE_NAME tbs,
b.BYTES / 1024 / 1024 totalM,
(b.BYTES - sum(a.BYTES)) / 1024 / 1024 usedM,
sum(a.BYTES) / 1024 / 1024 remaindM
from dba_free_space a, dba_data_files b
where a.FILE_ID = b.FILE_ID
group by b.FILE_ID, b.TABLESPACE_NAME, b.BYTES
order by b.TABLESPACE_NAME)
group by tbs
计算数据库每天的数据增量求平均值。
undotablespace = 900*(每天数据库的数据增量/24/3600) *1.2
注意:这种计算方式计算的数据增量,数据库以插入操作为主的,如果数据库delete和update操作也很多,这个公式没意义了。
###########################################################################################
ASSM下的高水位线HWM(high water mark)
MSSM方式下,HWM标记段上已经使用和没有使用的数据块的分界线,已经使用的表示已经被格式化过,没有使用过表示没有被格式化。
ASSM下,也是这个定义的,但是稍微有差别。 --ASSM表空间中段空间的自动管理方式
测试:
SQL> drop tablespace henry including contents and datafiles;
Tablespace dropped.
SQL> create tablespace henry datafile '/u01/oracle/oradata/ORCL/henry01.dbf' size 100M extent management local uniform size 128K segment space management auto;
Tablespace created.
SQL> conn scott/scott
Connected.
SQL> create table test tablespace henry as select * from dba_objects;
Table created.
SQL> conn scott/scott
Connected.
SQL> set autotrace trace stat --打开oracle自动跟踪工具
SQL> set linesize 1000
SQL> select count(1) from test;
自动跟踪出来的信息:
Statistics
----------------------------------------------------------
1089 recursive calls
0 db block gets --由于没有修改数据,当前读块次是0
969 consistent gets --一致性读块次
722 physical reads --物理读的块次
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
29 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> set autotrace off
SQL> delete from test where rownum<=20000;
20000 rows deleted.
SQL> commit;
Commit complete.
SQL> alter system flush shared_pool; --清掉缓存
System altered.
SQL> alter system flush buffer_cache; --清掉缓存
System altered.
SQL> set autotrace trace stat
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
274 recursive calls
0 db block gets
809 consistent gets
705 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
数据少了40%,但是IO没有减少?
SQL> set autotrace off
SQL> delete from test;
30822 rows deleted.
SQL> commit;
Commit complete.
SQL> alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> set autotrace trace stat
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
274 recursive calls
0 db block gets
809 consistent gets
704 physical reads
0 redo size
410 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
数据全删,但是IO还是这么大?
原因在于--delete操作不会使得段的HWM下降,而扫描表是从HWM开始往下扫的。
select * from user_extents where segment_name='TEST' --区是45个
将三级位图块dump出来
SQL> alter system dump datafile 15 block 11;
System altered.
*** 2014-06-27 16:45:06.737
*** ACTION NAME:() 2014-06-27 16:45:06.736
*** MODULE NAME:(SQL*Plus) 2014-06-27 16:45:06.736
*** SERVICE NAME:(SYS$USERS) 2014-06-27 16:45:06.736
*** SESSION ID:(431.14) 2014-06-27 16:45:06.736
Start dump data blocks tsn: 22 file#: 15 minblk 11 maxblk 11
buffer tsn: 22 rdba: 0x03c0000b (15/11)
scn: 0x0000.002ba585 seq: 0x01 flg: 0x04 tail: 0xa5852301
frmt: 0x02 chkval: 0x4915 type: 0x23=PAGETABLE SEGMENT HEADER
Hex dump of block: st=0, typ_found=1
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 45 #blocks: 720
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c002d6 ext#: 44 blk#: 13 ext size: 16 --HWM在文件15的块726上
select * from dba_extents where owner='SCOTT' and segment_name='TEST' --HWM在最后的区上
#blocks in seg. hdr's freelists: 0
#blocks below: 717
mapblk 0x00000000 offset: 44
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c002d6 ext#: 44 blk#: 13 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 717
mapblk 0x00000000 offset: 44
Level 1 BMB for High HWM block: 0x03c002b9
Level 1 BMB for Low HWM block: 0x03c002b9
--------------------------------------------------------
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
L2 Array start offset: 0x00001434
First Level 3 BMB: 0x00000000
L2 Hint for inserts: 0x03c0000a
Last Level 1 BMB: 0x03c002b9
Last Level II BMB: 0x03c0000a
Last Level III BMB: 0x00000000
Map Header:: next 0x00000000 #extents: 45 obj#: 58033 flag: 0x10000000
Inc # 0
Extent Map
-----------------------------------------------------------------
0x03c00009 length: 16
0x03c00019 length: 16
0x03c00029 length: 16
0x03c00039 length: 16
0x03c00049 length: 16
0x03c00059 length: 16
0x03c00069 length: 16
0x03c00079 length: 16
0x03c00089 length: 16
0x03c00099 length: 16
0x03c000a9 length: 16
0x03c000b9 length: 16
0x03c000c9 length: 16
0x03c000d9 length: 16
0x03c000e9 length: 16
0x03c000f9 length: 16
0x03c00109 length: 16
0x03c00119 length: 16
0x03c00129 length: 16
0x03c00139 length: 16
0x03c00149 length: 16
0x03c00159 length: 16
0x03c00169 length: 16
0x03c00179 length: 16
0x03c00189 length: 16
0x03c00199 length: 16
0x03c001a9 length: 16
0x03c001b9 length: 16
0x03c001c9 length: 16
0x03c001d9 length: 16
0x03c001e9 length: 16
0x03c001f9 length: 16
0x03c00209 length: 16
0x03c00219 length: 16
0x03c00229 length: 16
0x03c00239 length: 16
0x03c00249 length: 16
0x03c00259 length: 16
0x03c00269 length: 16
0x03c00279 length: 16
0x03c00289 length: 16
0x03c00299 length: 16
0x03c002a9 length: 16
0x03c002b9 length: 16
0x03c002c9 length: 16
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x03c00009 Data dba: 0x03c0000c
Extent 1 : L1 dba: 0x03c00019 Data dba: 0x03c0001a
Extent 2 : L1 dba: 0x03c00029 Data dba: 0x03c0002a
Extent 3 : L1 dba: 0x03c00039 Data dba: 0x03c0003a
Extent 4 : L1 dba: 0x03c00049 Data dba: 0x03c0004a
Extent 5 : L1 dba: 0x03c00059 Data dba: 0x03c0005a
Extent 6 : L1 dba: 0x03c00069 Data dba: 0x03c0006a
Extent 7 : L1 dba: 0x03c00079 Data dba: 0x03c0007a
Extent 8 : L1 dba: 0x03c00079 Data dba: 0x03c00089
Extent 9 : L1 dba: 0x03c00079 Data dba: 0x03c00099
Extent 10 : L1 dba: 0x03c00079 Data dba: 0x03c000a9
Extent 11 : L1 dba: 0x03c000b9 Data dba: 0x03c000ba
Extent 12 : L1 dba: 0x03c000b9 Data dba: 0x03c000c9
Extent 13 : L1 dba: 0x03c000b9 Data dba: 0x03c000d9
Extent 14 : L1 dba: 0x03c000b9 Data dba: 0x03c000e9
Extent 15 : L1 dba: 0x03c000f9 Data dba: 0x03c000fa
Extent 16 : L1 dba: 0x03c000f9 Data dba: 0x03c00109
Extent 17 : L1 dba: 0x03c000f9 Data dba: 0x03c00119
Extent 18 : L1 dba: 0x03c000f9 Data dba: 0x03c00129
Extent 19 : L1 dba: 0x03c00139 Data dba: 0x03c0013a
Extent 20 : L1 dba: 0x03c00139 Data dba: 0x03c00149
Extent 21 : L1 dba: 0x03c00139 Data dba: 0x03c00159
Extent 22 : L1 dba: 0x03c00139 Data dba: 0x03c00169
Extent 23 : L1 dba: 0x03c00179 Data dba: 0x03c0017a
Extent 24 : L1 dba: 0x03c00179 Data dba: 0x03c00189
Extent 25 : L1 dba: 0x03c00179 Data dba: 0x03c00199
Extent 26 : L1 dba: 0x03c00179 Data dba: 0x03c001a9
Extent 27 : L1 dba: 0x03c001b9 Data dba: 0x03c001ba
Extent 28 : L1 dba: 0x03c001b9 Data dba: 0x03c001c9
Extent 29 : L1 dba: 0x03c001b9 Data dba: 0x03c001d9
Extent 30 : L1 dba: 0x03c001b9 Data dba: 0x03c001e9
Extent 31 : L1 dba: 0x03c001f9 Data dba: 0x03c001fa
Extent 32 : L1 dba: 0x03c001f9 Data dba: 0x03c00209
Extent 33 : L1 dba: 0x03c001f9 Data dba: 0x03c00219
Extent 34 : L1 dba: 0x03c001f9 Data dba: 0x03c00229
Extent 35 : L1 dba: 0x03c00239 Data dba: 0x03c0023a
Extent 36 : L1 dba: 0x03c00239 Data dba: 0x03c00249
Extent 37 : L1 dba: 0x03c00239 Data dba: 0x03c00259
Extent 38 : L1 dba: 0x03c00239 Data dba: 0x03c00269
Extent 39 : L1 dba: 0x03c00279 Data dba: 0x03c0027a
Extent 40 : L1 dba: 0x03c00279 Data dba: 0x03c00289
Extent 41 : L1 dba: 0x03c00279 Data dba: 0x03c00299
Extent 42 : L1 dba: 0x03c00279 Data dba: 0x03c002a9
Extent 43 : L1 dba: 0x03c002b9 Data dba: 0x03c002ba
Extent 44 : L1 dba: 0x03c002b9 Data dba: 0x03c002c9
--------------------------------------------------------
Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x03c0000a
End dump data blocks tsn: 22 file#: 15 minblk 11 maxblk 11
SQL> truncate table test; --truncate有使HWM下降的功能
Table truncated.
select * from dba_extents where owner='SCOTT' and segment_name='TEST' --区变为1个,截断操作可以使HWM下降
SQL> set autotrace trace stat
SQL> alter system flush shared_pool;
System altered.
SQL> alter system flush buffer_cache;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
628 recursive calls
0 db block gets
97 consistent gets --IO明显降低很多
19 physical reads
0 redo size
410 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
9 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> conn /as sysdba
Connected.
SQL> alter system dump datafile 15 block 11;
System altered.
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 1 #blocks: 16
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c0000c ext#: 0 blk#: 3 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c0000c ext#: 0 blk#: 3 ext size: 16 --HWM在文件15的块12
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Level 1 BMB for High HWM block: 0x03c00009
Level 1 BMB for Low HWM block: 0x03c00009
--------------------------------------------------------
Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0
L2 Array start offset: 0x00001434
First Level 3 BMB: 0x00000000
L2 Hint for inserts: 0x03c0000a
Last Level 1 BMB: 0x03c00009
Last Level II BMB: 0x03c0000a
Last Level III BMB: 0x00000000
Map Header:: next 0x00000000 #extents: 1 obj#: 58034 flag: 0x10000000
Inc # 0
Extent Map
-----------------------------------------------------------------
0x03c00009 length: 16
Auxillary Map
--------------------------------------------------------
Extent 0 : L1 dba: 0x03c00009 Data dba: 0x03c0000c
--------------------------------------------------------
Second Level Bitmap block DBAs
--------------------------------------------------------
DBA 1: 0x03c0000a
End dump data blocks tsn: 22 file#: 15 minblk 11 maxblk 11
高水位线是Oracle扫描表的起始点,如果删除操作太多导致段空间空间增多,碎片增加,块的状态出现的 75%~100% free 状态太多。考虑回收碎片了。
ASSM下HHWM和LHWM的特点:
1、所有在HHWM之上的数据块都是没有被格式化的。
2、所有在LHWM之下的数据块都是被格式化过的。
3、在HHWM和LHWM之间的数据块可能是格式化过的也可能是没有格式化过的。
4、Oracle扫描表的时候会扫到HHWM为止。
5、CAST方式创建的表,HHWM=LHWM
CAST方式 = create table xxxx as select 。。。。。。。。。
如果LHWM之下出现了未被格式化过的块,oralce访问这个表的时候会报错,ORA-08103错误,查询这个这个表或者给这个表加索引都会报错。
SQL> insert into test select * from all_objects;
50293 rows inserted
SQL> commit;
Commit complete
alter system dump datafile 15 block 11;
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 45 #blocks: 720
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c002d9 ext#: 44 blk#: 16 ext size: 16 --
#blocks in seg. hdr's freelists: 0
#blocks below: 701
mapblk 0x00000000 offset: 44
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c002d9 ext#: 44 blk#: 16 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 701
mapblk 0x00000000 offset: 44
Level 1 BMB for High HWM block: 0x03c002b9
Level 1 BMB for Low HWM block: 0x03c002b9
--------------------------------------------------------
SQL> select getfbin('0x03c002d9') from dual;
GETFBIN('0X03C002D9')
--------------------------------------------------------------------------------
datafile is 15
datablock is 729 --HHWM=LHWM=块729上
破坏HHWM之下的数据块,将其设置为未被格式化过的。
[root@oracle3 ~]# dd if=/dev/zero of=/u01/oracle/oradata/ORCL/henry01.dbf bs=8192 seek=714 count=1 conv=notrunc
1+0 records in
1+0 records out
8192 bytes (8.2 kB) copied, 2.9692e-05 seconds, 276 MB/s
SQL> select count(1) from test; --此时由于缓存的作用,查询是不报错的
COUNT(1)
----------
50293
SQL> alter system flush buffer_cache; --清理缓存后。
System altered.
SQL> select count(1) from test;
select count(1) from test
*
ERROR at line 1:
ORA-08103: object no longer exists
唯一修复的办法是恢复这个数据块。备份文件+日志文件。 一定要备份文件存在,否则这个数据是恢复不了的。
SQL> truncate table test;
Table truncated. --此时HWM再块714之下
SQL> select count(1) from test;
COUNT(1)
----------
0
###########################################################################################
表空间收缩--shrink方法
原理--对表做一系列的dml操作(产生大量的redo),删除表末端的稀疏行,在表的底端重新插入,填满漏洞空间,逐步将剩余的空间留在表的末端,oracle重置表的HWM,释放自由空间。在操作的过程中,表的行上会暂时出现行级排它锁,某些行的操作会受到影响,大部分行是不受影响的,所以从全局上看,shrink操作不影响用户访问。
注意:数据量很大的表,年久失修,长时间没有做碎片回收,shrink操作时间就会很长,归档很多,操作前需要评估。
SQL> insert into test select * from dba_objects;
50933 rows inserted
SQL> commit;
Commit complete
SQL> alter system dump datafile 15 block 11;
System altered.
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 45 #blocks: 720
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c002d9 ext#: 44 blk#: 16 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 701
mapblk 0x00000000 offset: 44
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c002d9 ext#: 44 blk#: 16 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 701
mapblk 0x00000000 offset: 44
Level 1 BMB for High HWM block: 0x03c002b9
Level 1 BMB for Low HWM block: 0x03c002b9
--------------------------------------------------------
SQL> select getfbin('0x03c002d9') from dual;
GETFBIN('0X03C002D9')
--------------------------------------------------------------------------------
datafile is 15
datablock is 729 --HWM
SQL> alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> set autotrace trace stat
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
217 recursive calls
0 db block gets
731 consistent gets
705 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> delete from test where rownum<=10000;
10000 rows deleted
SQL> commit;
Commit complete
SQL> delete from test where rownum<=10000; --段上出现“漏洞”
10000 rows deleted
SQL> commit;
Commit complete
SQL> alter system flush shared_pool;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
1035 recursive calls
0 db block gets
891 consistent gets
723 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
29 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter table test enable row movement;
Table altered. --行要在物理上发生移动的
SQL> alter table test shrink space; --企业环境中这个操作要花费很长的时间。怎么处理这种环境。
Table altered.
SQL> alter system flush shared_pool;
System altered.
SQL> alter system flush buffer_cache;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
225 recursive calls
0 db block gets
461 consistent gets
437 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
select * from dba_extents where segment_name='TEST' and owner='SCOTT' --shrink之后有28个区
SQL> alter system dump datafile 15 block 11;
System altered.
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 28 #blocks: 448
last map 0x00000000 #maps: 0 offset: 2716
Highwater:: 0x03c001c7 ext#: 27 blk#: 14 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 431
mapblk 0x00000000 offset: 27
Unlocked
--------------------------------------------------------
Low HighWater Mark :
Highwater:: 0x03c001c7 ext#: 27 blk#: 14 ext size: 16
#blocks in seg. hdr's freelists: 0
#blocks below: 431
mapblk 0x00000000 offset: 27
Level 1 BMB for High HWM block: 0x03c001b9
Level 1 BMB for Low HWM block: 0x03c001b9
SQL> select getfbin('0x03c001c7') from dual;
GETFBIN('0X03C001C7')
--------------------------------------------------------------------------------
datafile is 15
datablock is 455 --证明HWM确实是下降了。
---------------------------------------------------------------------------------------------------------------------------
企业环境中--规模很大的表--用shrink操作是不现实
规模小的表--用shrink
思路--1、要达到什么样的状况才考虑碎片的回收? --二八原则:20%碎片率
2、在有限的时间窗口内怎么设计这个回收方案? --分工
3、怎样匹配现有技术团队参与这个方案?每个团队对于这个数据库的操作权限是不一样的。
团队分工:A 开发组(项目组)--对数据库权限是相对比较低,仅仅要求对项目所创建的用户SCOTT,下的对象的操作权限,包括表、SP开发,数据的抽取。
B DBA组--不关注业务细节,对数据库上所有的用户进行监控和维护,对数据库操作权限是比较大的。
C 优化组--较为关注业务细节,对业务上的SQL语句进行全面优化:执行计划的调试,统计数据的收集策略。
D 审计组--对ABC三组人员的行为进行监控和审计。
对于用户小表碎片回收--A组做。--直接开发SP,用用表过滤出小数据量、业务相关性弱的表,直接shrink
大型的业务表,流水账,设计到财务的数据--DBA组--此时需要用数据泵导入导出,需要相对大的权限操作表空间,所以才去导出,重建表,导入的方式。
D组监控
dbms_space.space_usage --这个是判断是否要重建的依据
###########################################################################################
每个表每一行都有一个rowid
select t.*,t.rowid from test t --每个表的每行都有一个rowid,可以理解为行的物理地址或者主键,行的物理地址发生了移动,rowid要变化。
行移动功能打开目的是为了让rowid变化。rowid是不存储在表空间中的,仅仅查询的时候根据对象号、行号、块号、文件号、行类型用一个加密的算法的函数得出rowid结果。
根据rowid反解出对象号、行号、块号、文件号、行类型:
create or replace function get_rowid(l_rowid in varchar2) return varchar2 is
ls_my_rowid varchar2(150);
row_type number;
obj_number number;
file_number number;
blk_number number;
row_number number;
begin
dbms_rowid.rowid_info(l_rowid,
row_type,
obj_number,
file_number,
blk_number,
row_number);
ls_my_rowid := 'row type is ' || to_char(row_type) || chr(10) ||
'object# is ' || to_char(obj_number) || chr(10) ||
'file# is ' || to_char(file_number) || chr(10) ||
'blk# is ' || to_char(blk_number) || chr(10) ||
'row# is ' || to_char(row_number);
return ls_my_rowid;
exception when others then
return 'error!';
end;
调用
SQL> select get_rowid('AAAOOhAAPAAAAAMAAD') from dual;
GET_ROWID('AAAOOHAAPAAAAAMAAD'
--------------------------------------------------------------------------------
row type is 1
object# is 58273
file# is 15
blk# is 12
row# is 3
select * from dba_objects where data_object_id=58273 --查询对象号
由于5个值联合起来不会重复,所以rowid是不会有重复值,可以认为是一个物理地址。
###########################################################################################
回收表空间碎片的move方法
回收表空间碎片的move方法,相对比较快,但是引发的影响比较大,会导致索引失效。
9i中用的比较多,但是随着数据量加大,这个方法用的场合越来越少。
原理--表表所有行从一个物理位置移动到另外一个物理位置,移动的过程中回收碎片。在同一个表空间内完成。
要求当前表的表空间必须有一倍于当前表存储大小的free空间。行所有的rowid都会变化。
SQL> insert into test select * from dba_objects;
50934 rows inserted
SQL> commit;
Commit complete
SQL> delete from test where rownum<=10000;
10000 rows deleted
SQL> delete from test where rownum<=10000;
10000 rows deleted
SQL> commit;
Commit complete
SQL> alter system flush buffer_cache;
System altered.
SQL> alter system flush shared_pool;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
1035 recursive calls
0 db block gets
1335 consistent gets
1163 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
29 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> delete from test where rownum<=15000;
15000 rows deleted
SQL> delete from test where rownum<=20000;
20000 rows deleted
SQL> commit;
Commit complete
SQL> alter system flush shared_pool;
System altered.
SQL> alter system flush buffer_cache;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
225 recursive calls
0 db block gets
1177 consistent gets
1147 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter table test disable row movement;
Table altered.
SQL> alter table test move; --不打开行移动功能也是可以的
Table altered.
select * from dba_extents where segment_name='TEST' and owner='SCOTT' --可以看到extent的块号都变了
SQL> alter system flush shared_pool;
System altered.
SQL> alter system flush buffer_cache;
System altered.
SQL> select count(1) from test;
Statistics
----------------------------------------------------------
1035 recursive calls
0 db block gets
563 consistent gets
399 physical reads
116 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
29 sorts (memory)
0 sorts (disk)
1 rows processed
但是这里还有一个问题:move操作由于会改变表的rowid,而表中如果有索引的话(索引中是要存储rowid),所有的索引会失效,此时我们需要重建索引,重建索引的代价在数据库中是很高的,重建索引的时间(对于大表来说)很长,这种方法要慎用
总结:1、空间损耗 2、rowid的失效而引发的其他问题。
#########################################################################################
SYSAXU表空间
SYSAXU表空间--辅助表空间,对应的管理用户是SYSMAN,也属于系统用户。
管理范畴--oralce其他组件:logminer等。oracle组件用SYSMAN用户管理,耗用的表空间是SYSAUX
select * from v$sysaux_occupants --oracle初始化的组件有26个,
SQL> desc v$sysaux_occupants
Name Null? Type
----------------------------------------- -------- ----------------------------
OCCUPANT_NAME VARCHAR2(64) --组件名
OCCUPANT_DESC VARCHAR2(64) --组件的功能描述
SCHEMA_NAME VARCHAR2(64) --所属的用户
MOVE_PROCEDURE VARCHAR2(64) --移动使用表空间使用的SP:SYSAUX如果不足的话,可以将组件使用的表空间移动到其他表空间上,移动的方法,oracle给我们封装了对应的存储过程。
MOVE_PROCEDURE_DESC VARCHAR2(64) --移动方法的描述
SPACE_USAGE_KBYTES NUMBER --当前该组件使用这个表空间SYSAUX的大小
SQL> exec SYS.DBMS_LOGMNR_D.SET_TABLESPACE('MYTBS4');
PL/SQL procedure successfully completed.
select * from v$sysaux_occupants --发现 SPACE_USAGE_KBYTES变为0,表示在SYSAUX上不用空间了