第二天视频1
1.physical
2.logical
只有ORACLE和DB2有表空间的概念
database->tablespaces->segments->extents->blocks->os block
select * from dba_tablespaces,按照段的内容和类型来分,分为三类。PERMANENT,UNDO,TEMPORARY
PERMANENT
和逻辑对应的是物理结构,也就是物理结构中的数据文件select * from dba_data_files,表空间和数据文件的关系就是物理结构和逻辑结构的关系,通过表空间管理起来,一个表空间可以包含多个数据文件,最多1023个。FILE_ID
临时文件单独放在select * from dba_temp_files数据字典里。
create tablespace test datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST01.DBF' SIZE 10M;
此时表空间多了一个,类型是永久的,对应的数据文件也多了一个,显示的是字节,大小是10M
create table t(id int) tablespace test;--把创建的表放在TEST上
表的定义放在system表空间里,属于原数据,数据放在test表空间里。
默认表空间都是online状态,alter tablespace test offline;--处于ONLINE状态的是可读写的
此时T上面的数据不可读取
SQL> select * from t;
select * from t
*
ERROR at line 1:
ORA-00376: file 5 cannot be read at this time
ORA-01110: data file 5: 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST01.DBF'
drop table t;--删除表只是删除表的定义,是可以的,10后g连定义都没删除,只是改个名字放在回收站里。
SQL> alter tablespace test online;
Tablespace altered.
SQL> select * from "BIN$ykIECTcbR/idA68JO25gGA==$0";
no rows selected
可以访问,但是无法进行DML操作。
flashback table t to before drop;--把t拿回来。
一个表空间里包含哪些段
select * from dba_segments where tablespace_name='TEST';--HEADER_FILE 5,HEADER_BLOCK 11,看一个段多大就看这个视图,但并不是特别准确
select * from dba_extents where segment_name='T';--T表没有数据,是创建表的时候分配的
从第9个块开始,连续8个,逻辑上连续
再创建个大点的表,只是复制数据
create table tt tablespace test as select * from dba_objects;--只是复制的基本的表结构和数据,不复制索引和约束
select * from dba_segments where tablespace_name='TEST' and segment_name='TT';--2M大小
select * from dba_extents where segment_name='TT';--17个extents,从17开始,因为T是从9开始,到16
前16个都是8个块,第17个128个块,也就是1024K,也就是1M,oracle自动调整分配单位
SQL> insert into tt select * from tt;
11393 rows created.
SQL> insert into tt select * from tt;
22786 rows created.
SQL> insert into tt select * from tt;
insert into tt select * from tt
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.TT by 128 in tablespace TEST--并未达到100%
空间不足,有几种解决办法(1.手动放大2.自动扩展3.增加数据文件)
SQL> alter database datafile 5 resize 20m;
Database altered.
SQL> insert into tt select * from tt;
45572 rows created.
SQL> insert into tt select * from tt;
insert into tt select * from tt
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.TT by 128 in tablespace TEST
又不够了
有时候表空间使用率只有60%,会提示空间不足,因为有磁盘空间,但磁盘空间不连续,ORACLE分配空间以EXTENTS为单位,要求一个EXTENTS内部逻辑上多个块必须连续。超过85%需要注意了。
oracle
第二天视频2(表空间扩展)
自动扩展可能会对性能有影响
alter database datafile 5 autoextend on next 1m maxsize 1024m;最大是32G
increment_by 单位是块的大小,128个块,是1M,AUTOEXTENSIBLE
insert into tt select * from tt;
此时TT已经有34个extents
前16个是8个块,然后是128个块
alter tablespace test add datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST02.DBF' size 10m autoextend on next 1m;--对目前表里的数据没有影响
这就给表空间TEST增加了一个数据文件,此时表空间没啥变化,数据文件增加了一个,有两个数据文件和表空间TEST对应。
再插入数据,oracle分配extents就会有两种选择,extent 可能在5号文件上,可能在6号文件上
再插入数据
SQL> insert into tt select * from tt;
182288 rows created.
select * from dba_extents where segment_name='TT';--EXTENT既有5号文件,又有6号文件
SQL> alter table t allocate extent (datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST02.DBF' size 40m);--extent原来一个,现在增加了40个
SQL> alter table tt allocate extent (datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST01.DBF' size 40m);分配的空间都在5号文件上,再插入数据,如果刚刚分配空间够的话,不会再分配
insert into tt select * from tt;--
select * from dba_extents where segment_name='TT';--没变化
T表只有1个字段,却又40M,有时候从segments中看到的数据是不准确的
SQL> insert into tt select * from tt where rownum<=100000;
select * from dba_extents where segment_name='TT';出现了1024,BLOCKS
SQL> create tablespace test1 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST03.DBF' size 10m autoextend on next 1m maxsize unlimited autoallocate;--ALLOCATION_TYPE:SYSTEM,这个属性没法修改
SQL> create tablespace test2 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST04.DBF' size 10m autoextend on next 1m maxsize unlimited uniform;--缺省值是1M
表T只有一条数据,却40M,进行表紧缩。表紧缩需要激活行移动.
SQL> alter table t shrink space;--把没有数据的空闲的释放出去
alter table t shrink space
*
ERROR at line 1:
ORA-10636: ROW MOVEMENT is not enabled
SQL> ALTER TABLE T ENABLE ROW MOVEMENT;
SQL> ALTER TABLE T SHRINK SPACE;.
select * from dba_segments where tablespace_name='TEST';--42008576,65536,紧缩后由原来的40M变为默认的64K
移动一下
SQL> alter table t move tablespace test2;
select * from dba_extents where segment_name='T';--128blocks 缺省1M(uniform的缺省值)
再创建一个表空间
SQL> create tablespace test3 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST05.DBF' size 10m autoextend on next 1m maxsize unlimited uniform. size 128k;
Tablespace created.
再移动一下
SQL> alter table t move tablespace test3;
select * from dba_extents where segment_name='T';--16 blocks
oracle
第二天视频3
oracle 的表空间和其他数据库对应
物理读更消耗CPU资源
一个OS FILE 对应多个extents
一个表最多有一千列,一个行片最多有256列,超过256列,一条数据就会有两个行片
数据库块的结构,放数据不是从块头开始放,而是从底下放,把中间空出来。因为块头占用的空间可能也不固定,
一个块根本没有放满,oracle每个块预留10%空间,PCT_FREE(DBA_TABLES)。为什么空闲呢?防止那种VARCHAR,刚开始放了1个字符,后来更新的时候放了100个。
数据文件过大,损坏恢复需要的时间长,备份的时间也长,从管理上和数据安全的角度来讲可以分成多个。也需要依赖于操作系统,FAT32格式 最多2个G。从性能上讲,如果文件都在一个不同的物理磁盘上,那肯定多个文件好,每个磁盘都有磁头,相当于并行工作
select * from v$filestat;--记录了读写的块次数
划分的时候都加进来,逻辑上
为什么第9个开始使用,第一个数据文件头,
select * from fet$那些块没有被使用
select * from uet$那些块被使用
SQL> create tablespace test4 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST06.DBF' size 10m autoextend on next 1m maxsize unlimited extent management local uniform. size 128k;--本地管理
SQL> create tablespace test5 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST07.DBF' size 10m autoextend on next 1m maxsize unlimited extent management dictionary uniform. size 128k;
create tablespace test5 datafile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\TEST\TEST07.DBF' size 10m autoextend on next 1m maxsize unlimited extent management dictionary uniform. size 128k
*
ERROR at line 1:
ORA-12913: Cannot create dictionary managed tablespace
字典管理
9.2之后默认LOCAL,不支持字典管理,如果想研究,在建库的时候把system表空间管理改为字典管理。
字典管理对并发性有影响
通过测试发现最多可以有1000列,每一row pieve最多255。
SQL> create table tt(id int);
表已创建。
SQL> edit
已写入 file afiedt.buf
1 declare
2 v_string varchar2(100);
3 begin
4 for i in 1..1000 loop
5 v_string := 'alter table tt add col'||i||' int' ;
6 execute immediate v_string;
7 end loop ;
8* end;
SQL> /
declare
*
第 1 行出现错误:
ORA-01792: 表或视图中的最大列数为 1000
ORA-06512: 在 line 6
SQL>
--===================
Row Format and Size
Oracle stores each row of a database table containing data for less than 256 columns as one or more row pieces. If an entire row can be inserted into a single data block, then Oracle stores the row as one row piece. However, if all of a row's data cannot be inserted into a single data block or if an update to an existing row causes the row to outgrow its data block, then Oracle stores the row using multiple row pieces. A data block usually contains only one row piece for each row. When Oracle must store a row in more than one row piece, it is chained across multiple blocks.
When a table has more than 255 columns, rows that have data after the 255th column are likely to be chained within the same block. This is called intra-block chaining. A chained row's pieces are chained together using the rowids of the pieces. With intra-block chaining, users receive all the data in the same block. Ifthe row fits in the block, users do not see an effect in I/O performance, because no extra I/O operation is required to retrieve the rest of the row.