[转帖] ORACLE--逻辑架构(一)_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
2
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2745 | 回复: 1   主题: [转帖] ORACLE--逻辑架构(一)        上一篇   下一篇 
BozepTip
注册用户
等级:新兵
经验:66
发帖:1
精华:0
注册:2018-10-4
状态:离线
发送短消息息给BozepTip 加好友    发送短消息息给BozepTip 发消息
发表于: IP:您无权察看 2019-9-18 9:23:45 | [全部帖] [楼主帖] 楼主

数据库逻辑架构主要包含:tablespace->segment->extent->block->os-block以及datafile,也说明了其中数据文件的部分管理方式,这里接着从这里开始说起比较好:

1、系统提供每一个表空间说明

2、大文件表空间

3、表空间文件主从关系

4、EXTENTS与SEGMENTS

5、高水位线介绍

6、DELETE、TRUNCATE、DROP、SHRINK SPACE区别

7、BLOCK存储原理

付:本来应该将SEGMENT一起说明的,不过SEGMENT是说明起来最复杂,也是体系架构中最终的关键部分,所以SEGMENT以后单独写一篇文章说明;而本文中最复杂的部分在“块”的说明中。

1、系统提供每一个表空间说明

首先查看有哪些表空间:

SQL> select tablespace_name,CONTENTS
2  from dba_tablespaces;
TABLESPACE_NAME                CONTENTS
------------------------------ ---------
SYSTEM                         PERMANENT
UNDOTBS1                       UNDO
SYSAUX                         PERMANENT
TEMP                           TEMPORARY
USERS                          PERMANENT
EXAMPLE                        PERMANENT


其中:

PERMANENT:表示永久表空间

UNDO:回退表空间

TEMPORARY:表示为临时表空间。

SYSTEM:是整个数据库最重要的表空间,存储的是数据字典,表的定义、视图定义、存储过程定义、用户信息、索引信息等都放于系统表空间中,系统表空间必须在线,其余都依赖于这个表空间存在,付:这个表空间不允许改名字。

SYSAUX:10g后新特性,系统辅助表空间(ORACLE 7i的系统表空间只有不到70M,8i不到200M,9i达到400M以上),后来将一些最核心的要保留较小,将最核心的留在SYSTEM表空间,其余的放置于SYSAUX表空间,付:系统内部这个表空间不允许改名字。

其余表空间都可以改名字,就这两个表空间不允许改名字。

SQL> select table_name from dict where table_name like '%AUX%';
TABLE_NAME
------------------------------
GV$SYSAUX_OCCUPANTS
V$SYSAUX_OCCUPANTS
SQL> desc V$SYSAUX_OCCUPANTS


 名称

 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
OCCUPANT_NAME
OCCUPANT_DESC
SCHEMA_NAME
MOVE_PROCEDURE
MOVE_PROCEDURE_DESC
SPACE_USAGE_KBYTES
SQL> COL OCCUPANT_NAME for a35
SQL> col OCCUPANT_DESC for a60
SQL> col SCHEMA_NAME for a30
SQL> col MOVE_PROCEDURE for a50
SQL> col SPACE_USAGE_KBYTES for 9999999999999999
SQL> set lines 260
SQL> select OCCUPANT_NAME,OCCUPANT_DESC,MOVE_PROCEDURE,SPACE_USAGE_KBYTES
2  FROM V$SYSAUX_OCCUPANTS;
OCCUPANT_NAME                       OCCUPANT_DESC                                                MOVE_PROCEDURE                                     SPACE_USAGE_KBYTES
----------------------------------- ------------------------------------------------------------ -------------------------------------------------- ------------------
LOGMNR                              LogMiner                                                     SYS.DBMS_LOGMNR_D.SET_TABLESPACE                                 6080
LOGSTDBY                            Logical Standby                                              SYS.DBMS_LOGSTDBY.SET_TABLESPACE                                  896
STREAMS                             Oracle Streams                                                                                                         512
XDB                                 XDB                                                          XDB.DBMS_XDB.MOVEXDB_TABLESPACE                                 49600
AO                                  Analytical Workspace Object Table                            DBMS_AW.MOVE_AWMETA                                             21248
XSOQHIST                            OLAP API History Tables                                      DBMS_XSOQ.OlapiMoveProc                                         21248
XSAMD                               OLAP Catalog                                                 DBMS_AMD.Move_OLAP_Catalog                                      15936
SM/AWR                              Server Manageability - Automatic Workload Repository                                                                 19520
SM/ADVISOR                          Server Manageability - Advisor Framework                                                                              4928
SM/OPTSTAT                          Server Manageability - Optimizer Statistics History                                                                   3968
SM/OTHER                            Server Manageability - Other Components                                                                               4992
OCCUPANT_NAME                       OCCUPANT_DESC                                                MOVE_PROCEDURE                                     SPACE_USAGE_KBYTES
----------------------------------- ------------------------------------------------------------ -------------------------------------------------- ------------------
STATSPACK                           Statspack Repository                                                                                                     0
ODM                                 Oracle Data Mining                                           MOVE_ODM                                                          256
SDO                                 Oracle Spatial                                               MDSYS.MOVE_SDO                                                  41536
WM                                  Workspace Manager                                            DBMS_WM.move_proc                                                7040
ORDIM                               Oracle interMedia ORDSYS Components                                                                                    512
ORDIM/PLUGINS                       Oracle interMedia ORDPLUGINS Components                                                                                  0
ORDIM/SQLMM                         Oracle interMedia SI_INFORMTN_SCHEMA Components                                                                          0
EM                                  Enterprise Manager Repository                                emd_maintenance.move_em_tblspc                                  50880
TEXT                                Oracle Text                                                  DRI_MOVE_CTXSYS                                                  4736
ULTRASEARCH                         Oracle Ultra Search                                          MOVE_WK                                                             0
ULTRASEARCH_DEMO_USER               Oracle Ultra Search Demo User                                MOVE_WK                                                             0
OCCUPANT_NAME                       OCCUPANT_DESC                                                MOVE_PROCEDURE                                     SPACE_USAGE_KBYTES
----------------------------------- ------------------------------------------------------------ -------------------------------------------------- ------------------
EXPRESSION_FILTER                   Expression Filter System                                                                                              3712
EM_MONITORING_USER                  Enterprise Manager Monitoring User                                                                                    1600
TSM                                 Oracle Transparent Session Migration User                                                                              256
JOB_SCHEDULER                       Unified Job Scheduler                                                                                                  384


可以发现这些应用都是应用级别的,并非绝对的,所以放置于系统辅助表空间中,字段说明:
OCCUPANT_NAME:应用的名字
OCCUPANT_DESC:应用的描述信息
MOVE_PROCEDURE:要将其移动到另一个地方,需要使用哪一个过程。

USER表空间:本来是很普通的表空间,在10g后有一个新特性:

SQL> COL PROPERTY_NAME FOR A60
SQL> COL PROPERTY_VALUE FOR A35
SQL> COL DESCRIPTION FOR A60
SQL> l
1* SELECT * FROM DATABASE_PROPERTIES
SQL> /
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- ------------------------------------
DICT.BASE                                                    2                                   dictionary base tables version #
DEFAULT_TEMP_TABLESPACE                                      TEMP                                Name of default temporary tablespace
DEFAULT_PERMANENT_TABLESPACE                                 USERS                               Name of default permanent tablespace
DEFAULT_TBS_TYPE                                             SMALLFILE                           Default tablespace type
NLS_LANGUAGE                                                 AMERICAN                            Language
NLS_TERRITORY                                                AMERICA                             Territory
NLS_CURRENCY                                                 $                                   Local currency
NLS_ISO_CURRENCY                                             AMERICA                             ISO currency
NLS_NUMERIC_CHARACTERS                                       .,                                  Numeric characters
NLS_CHARACTERSET                                             ZHS16GBK                            Character set
NLS_CALENDAR                                                 GREGORIAN                           Calendar system
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- ------------------------------------
NLS_DATE_FORMAT                                              DD-MON-RR                           Date format
NLS_DATE_LANGUAGE                                            AMERICAN                            Date language
NLS_SORT                                                     BINARY                              Linguistic definition
NLS_TIME_FORMAT                                              HH.MI.SSXFF AM                      Time format
NLS_TIMESTAMP_FORMAT                                         DD-MON-RR HH.MI.SSXFF AM            Time stamp format
NLS_TIME_TZ_FORMAT                                           HH.MI.SSXFF AM TZR                  Time with timezone format
NLS_TIMESTAMP_TZ_FORMAT                                      DD-MON-RR HH.MI.SSXFF AM TZR        Timestamp with timezone format
NLS_DUAL_CURRENCY                                            $                                   Dual currency symbol
NLS_COMP                                                     BINARY                              NLS comparison
NLS_LENGTH_SEMANTICS                                         BYTE                                NLS length semantics
NLS_NCHAR_CONV_EXCP                                          FALSE                               NLS conversion exception
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- ------------------------------------
NLS_NCHAR_CHARACTERSET                                       AL16UTF16                           NCHAR Character set
NLS_RDBMS_VERSION                                            10.2.0.1.0                          RDBMS version for NLS parameters
GLOBAL_DB_NAME                                               ORCL103.REGRESS.RDBMS.DEV.US.ORACLE Global database name
.COM
EXPORT_VIEWS_VERSION                                         8                                   Export views revision #
DBTIMEZONE                                                   00:00                               DB time zone
SQL> alter database default tablespace SYSTEM;


数据库已更改。

SQL> SELECT * FROM DATABASE_PROPERTIES;
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- -------------------------------------
DICT.BASE                                                    2                                   dictionary base tables version #
DEFAULT_TEMP_TABLESPACE                                      TEMP                                Name of default temporary tablespace
DEFAULT_PERMANENT_TABLESPACE                                 SYSTEM                              Name of default permanent tablespace
DEFAULT_TBS_TYPE                                             SMALLFILE                           Default tablespace type
NLS_LANGUAGE                                                 AMERICAN                            Language
NLS_TERRITORY                                                AMERICA                             Territory
NLS_CURRENCY                                                 $                                   Local currency
NLS_ISO_CURRENCY                                             AMERICA                             ISO currency
NLS_NUMERIC_CHARACTERS                                       .,                                  Numeric characters
NLS_CHARACTERSET                                             ZHS16GBK                            Character set
NLS_CALENDAR                                                 GREGORIAN                           Calendar system
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- -------------------------------------
NLS_DATE_FORMAT                                              DD-MON-RR                           Date format
NLS_DATE_LANGUAGE                                            AMERICAN                            Date language
NLS_SORT                                                     BINARY                              Linguistic definition
NLS_TIME_FORMAT                                              HH.MI.SSXFF AM                      Time format
NLS_TIMESTAMP_FORMAT                                         DD-MON-RR HH.MI.SSXFF AM            Time stamp format
NLS_TIME_TZ_FORMAT                                           HH.MI.SSXFF AM TZR                  Time with timezone format
NLS_TIMESTAMP_TZ_FORMAT                                      DD-MON-RR HH.MI.SSXFF AM TZR        Timestamp with timezone format
NLS_DUAL_CURRENCY                                            $                                   Dual currency symbol
NLS_COMP                                                     BINARY                              NLS comparison
NLS_LENGTH_SEMANTICS                                         BYTE                                NLS length semantics
NLS_NCHAR_CONV_EXCP                                          FALSE                               NLS conversion exception
PROPERTY_NAME                                                PROPERTY_VALUE                      DESCRIPTION
------------------------------------------------------------ ----------------------------------- -------------------------------------
NLS_NCHAR_CHARACTERSET                                       AL16UTF16                           NCHAR Character set
NLS_RDBMS_VERSION                                            10.2.0.1.0                          RDBMS version for NLS parameters
GLOBAL_DB_NAME                                               ORCL103.REGRESS.RDBMS.DEV.US.ORACLE Global database name
.COM
EXPORT_VIEWS_VERSION                                         8                                   Export views revision #
DBTIMEZONE                                                   00:00                               DB time zone


默认表空间分系统级别和用户级别,DATABASE级别的创建后,如果创建用户不使用DEFALUT TABLESPACE指定,那么它就用DATABASE指定的DEFAULT TABLEPSACE了

2、大文件表空间

SQL> SELECT TABLESPACE_NAME,BIGFILE FROM DBA_TABLESPACES;
TABLESPACE_NAME                BIG
------------------------------ ---
SYSTEM                         NO
UNDOTBS1                       NO
SYSAUX                         NO
TEMP                           NO
USERS                          NO
EXAMPLE                        NO


大文件表空间的特性:
1、文件头大,从普通的8个块,可以到16个块。
2、长大到4G个块,每个块为8K,即每个数据文件可以达到32T大小,也就是一个表空间的最大的大小。
3、一个表空间至于一个数据文件,即表空间的最大大小不会变化。
为什么:ROWID决定,所谓大文件就是将文件编号的的区域划分给块编号了,所以一个数据文件可以存放更大的空间。

SQL> create bigfile tablespace tt2 datafile 'D:/ORACLE/ORADATA/ORCL103/DATAFILE/TT2.DBF' size 1m;


表空间已创建。

SQL> select * from dba_free_space;
TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
SYSTEM                                  1      61161     262144         32            1
SYSTEM                                  1      61961    6225920        760            1
UNDOTBS1                                2        185      65536          8            2
UNDOTBS1                                2        201     131072         16            2
UNDOTBS1                                2        241     262144         32            2
UNDOTBS1                                2        281      65536          8            2
UNDOTBS1                                2        313     196608         24            2
UNDOTBS1                                2        353      65536          8            2
UNDOTBS1                                2        385      65536          8            2
UNDOTBS1                                2        401      65536          8            2
UNDOTBS1                                2        441     262144         32            2
TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
UNDOTBS1                                2        513     131072         16            2
UNDOTBS1                                2        553     131072         16            2
UNDOTBS1                                2        577     131072         16            2
UNDOTBS1                                2        601     589824         72            2
UNDOTBS1                                2        681     262144         32            2
UNDOTBS1                                2        721     131072         16            2
UNDOTBS1                                2        745     131072         16            2
UNDOTBS1                                2        769     524288         64            2
UNDOTBS1                                2        841     262144         32            2
UNDOTBS1                                2        881     196608         24            2
UNDOTBS1                                2        913      65536          8            2
TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
UNDOTBS1                                2        929     262144         32            2
UNDOTBS1                                2        969    1769472        216            2
UNDOTBS1                                2       1209     131072         16            2
UNDOTBS1                                2       1233     393216         48            2
UNDOTBS1                                2       3201      65536          8            2
UNDOTBS1                                2       3721     851968        104            2
UNDOTBS1                                2       3833     393216         48            2
UNDOTBS1                                2       3889     458752         56            2
UNDOTBS1                                2       3953     131072         16            2
UNDOTBS1                                2       3977    1048576        128            2
UNDOTBS1                                2       4233    1048576        128            2
TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
UNDOTBS1                                2       4369     131072         16            2
UNDOTBS1                                2       4393      65536          8            2
UNDOTBS1                                2       4409     589824         72            2
SYSAUX                                  3      30945    8650752       1056            3
USERS                                   4        537     917504        112            4
USERS                                   4       1289     131072         16            4
USERS                                   4       2057   11534336       1408            4
USERS                                   4       3481     327680         40            4
EXAMPLE                                 5        465    2162688        264            5
EXAMPLE                                 5       1313     458752         56            5
EXAMPLE                                 5      10265   20774912       2536            5
TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
------------------------------ ---------- ---------- ---------- ---------- ------------
TT2                                     6         17     917504        112         1024


现在BLOCK_ID从第17个块开始,可使用块只有112个块。

SQL> alter database datafile 'D:/ORACLE/ORADATA/ORCL103/DATAFILE/TT2.DBF' autoextend on;


数据库已更改。 

SQL> c/max_blocks/maxblocks
1* SELECT file_name,maxblocks from dba_data_files
SQL> /
FILE_NAME                                                     MAXBLOCKS
------------------------------------------------------------ ----------
D:/ORACLE/ORADATA/ORCL103/DATAFILE/O1_MF_USERS_63S35M2X_.DBF    4194302
D:/ORACLE/ORADATA/ORCL103/DATAFILE/O1_MF_SYSAUX_63S35LWS_.DB    4194302
F
D:/ORACLE/ORADATA/ORCL103/DATAFILE/O1_MF_UNDOTBS1_63S35M1Y_.    4194302
DBF
D:/ORACLE/ORADATA/ORCL103/DATAFILE/O1_MF_SYSTEM_63S35LVC_.DB    4194302
F
D:/ORACLE/ORADATA/ORCL103/DATAFILE/O1_MF_EXAMPLE_63S37HQX_.D    4194302
FILE_NAME                                                     MAXBLOCKS
------------------------------------------------------------ ----------
BF
D:/ORACLE/ORADATA/ORCL103/DATAFILE/TT2.DBF                   4294967293


比普通的数据文件最大值大1024倍。

SQL> alter tablespace tt2 add datafile 'D:/ORACLE/ORADATA/ORCL103/DATAFILE/TT2.DBF' size 2m;
alter tablespace tt2 add datafile 'D:/ORACLE/ORADATA/ORCL103/DATAFILE/TT2.DBF' size 2m
*


第 1 行出现错误:
ORA-32771: 无法在大文件表空间中添加文件

大文件使用海量连续存储数据,对控制文件有好处,以前控制文件存储上百个数据文件信息,此时值存储一个即可。

SQL> ALTER TABLESPACE TBS_TEST DROP DATAFILE 'D:/ORACLE/ORADATA/ORCL102/TBS_TEST03.DBF';


表空间已更改。

SQL> ALTER TABLESPACE TBS_TEST DROP DATAFILE 'D:/ORACLE/ORADATA/ORCL102/TBS_TEST02.DBF';


表空间已更改。

SQL> drop tablespace TBS_TEST;


3、表空间文件主从关系

SQL> SELECT FILE_NAME,TABLESPACE_NAME FROM DBA_DATA_FILES
2  WHERE TABLESPACE_NAME='TBS_TEST';
FILE_NAME                                          TABLESPACE_NAME
-------------------------------------------------- ------------------------------------------------
D:/ORACLE/ORADATA/ORCL102/TBS_TEST01.DBF           TBS_TEST
D:/ORACLE/ORADATA/ORCL102/TBS_TEST02.DBF           TBS_TEST
SQL> ALTER TABLESPACE TBS_TEST ADD DATAFILE 'D:/ORACLE/ORADATA/ORCL102/TBS_TEST03.DBF' size 1m;


表空间已更改。

SQL> SELECT FILE_NAME,TABLESPACE_NAME FROM DBA_DATA_FILES
2  WHERE TABLESPACE_NAME='TBS_TEST';
FILE_NAME                                          TABLESPACE_NAME
-------------------------------------------------- ---------------------------------------------
D:/ORACLE/ORADATA/ORCL102/TBS_TEST01.DBF           TBS_TEST
D:/ORACLE/ORADATA/ORCL102/TBS_TEST02.DBF           TBS_TEST
D:/ORACLE/ORADATA/ORCL102/TBS_TEST03.DBF           TBS_TEST
SQL> ALTER TABLESPACE TBS_TEST DROP DATAFILE 'D:/ORACLE/ORADATA/ORCL102/TBS_TEST01.DBF';
ALTER TABLESPACE TBS_TEST DROP DATAFILE 'D:/ORACLE/ORADATA/ORCL102/TBS_TEST01.DBF'
*


第 1 行出现错误:
ORA-03263: 无法删除表空间 TBS_TEST 的第一个文件

表空间已删除。

4、EXTENTS与SEGMENTS

SQL> select tablespace_name,segment_name,extents,blocks,segment_type
2  FROM dba_segments
3  WHERE OWNER='SCOTT';
TABLESPACE_NAME                SEGMENT_NAME                                                                 EXTENTS     BLOCKS SEGMENT_TYPE
------------------------------ --------------------------------------------------------------------------------- ---------- ---------- -----
USERS                          PK_DEPT                                                                            1          8 INDEX
USERS                          DEPT                                                                               1          8 TABLE
USERS                          EMP                                                                                1          8 TABLE
USERS                          PK_EMP                                                                             1          8 INDEX
USERS                          BONUS                                                                              1          8 TABLE
USERS                          SALGRADE                                                                           1          8 TABLE
USERS                          TT                                                                                 1          8 TABLE
USERS                          AAA                                                                                1          8 TABLE
USERS                          TABLE_01                                                                           1          8 TABLE
USERS                          TABLE_02                                                                           1          8 TABLE
USERS                          PERSON                                                                             1          8 TABLE
TABLESPACE_NAME                SEGMENT_NAME                                                                 EXTENTS     BLOCKS SEGMENT_TYPE
------------------------------ --------------------------------------------------------------------------------- ---------- ---------- -----
USERS                          V_USER_OBJECTS                                                                    21        768 TABLE
USERS                          V_DBA_OBJECTS                                                                     21        768 TABLE
USERS                          TEST_OBJECTS                                                                       2         16 TABLE
USERS                          TEST                                                                               1          8 TABLE
ORA10TEST                      EMP_OTHER                                                                          1          8 TABLE
USERS                          TABLE_AJ_TEST                                                                      1          8 TABLE


已选择17行。

SQL> grant select any dictionary to scott;


授权成功。

SQL> CREATE TABLE AAA(COL1 NUMBER,COL2 VARCHAR2(20));


表已创建。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8


也就是说一个表只要以创建就有8个BLOCKS,这8个块为表头。

分配EXTENT(范围)的三种方式:

1、创建表和索引的时候要分配EXTENTS初步的范围
2、数据量增长的时候分配额外的范围
3、手工分配范围。

先插入一些数据:

SQL> INSERT INTO AAA SELECT 1,1 FROM EMP;


已创建14行。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8


发现BLOCKS没有变化,看来前8个BLOCK并不完全是头部,下面继续证明。

然后重复执行N次复制数据:

INSERT INTO AAA SELECT * FROM AAA;


当数据中途发生:

SQL> SELECT COUNT(1) FROM AAA;
COUNT(1)
----------
3584
SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8
1          4         57          8


此时跨越了数据文件,也有新的BLOCK_ID开始的8个块。说明EXTENT相互之间可以不连续存储,而EXTENT内部是连续分配的多个块。

继续增加N多次以后数据:

SQL> SELECT COUNT(1) FROM AAA;
COUNT(1)
----------
114688
SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8
1          4         57          8
2          6       1057          8
3          6       1065          8
4          6       1073          8
5          6       1081          8
6          6       1089          8
7          6       1097          8
8          6       1105          8
9          6       1113          8
10          6       1121          8
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       1129          8
12          6       1137          8
13          6       1145          8
14          6       1153          8
15          6       1161          8
16          6       1289        128


出现128块了?这么奇怪的事情,为什么变大了呢?其实当你继续插入的时候,到第72个EXTENT的时候会变成1024个块(8M),然后再到8192个块(64M)等等,这是一个规律,当ORACLE发现数据量很大的时候,分配的范围就会越来越大,因为这样方便插入,预留空间,至于细节由ORACLE自己决定。

而SEGMENT是一个更大的概念,它包含一系列相同类型并属于同一逻辑对象的EXTENT的组合,当你创建一个表或者一个索引或者一个分区的新的分区的时候都会产生一个新的SEGMENT,也就是他是逻辑对象的标志,逻辑对象上有一个OBJECT_ID和DATA_OBJECT_ID的概念,在说到TRUNCATE的时候会提及。

--当有大量输出插入时,此时可以预先分配,然后就可以预先分配空间方便插入。

分区表对某一个分区手工分配EXTENTS:
分布区表为:alter table <table_name> modify partition <partition_name> allocate extent(size 20m);

SQL> alter table AAA allocate extent(size 10m);


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8
1          4         57          8
2          6       1057          8
3          6       1065          8
4          6       1073          8
5          6       1081          8
6          6       1089          8
7          6       1097          8
8          6       1105          8
9          6       1113          8
10          6       1121          8
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       1129          8
12          6       1137          8
13          6       1145          8
14          6       1153          8
15          6       1161          8
16          6       1289        128
17          6       1417        128
18          6       1545        128
19          6       1673        128
20          6       1801        128
21          6       1929        128
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
22          6       2057        128
23          6       2185        128
24          6       2313        128
25          6       2441        128
26          6       2569        128
27          6       2697        128
28          6       2825        128


回收EXTENT:

SQL> alter table aaa deallocate unused;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8
1          4         57          8
2          6       1057          8
3          6       1065          8
4          6       1073          8
5          6       1081          8
6          6       1089          8
7          6       1097          8
8          6       1105          8
9          6       1113          8
10          6       1121          8
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       1129          8
12          6       1137          8
13          6       1145          8
14          6       1153          8
15          6       1161          8
16          6       1289        128
17          6       1417        128
18          6       1545        128
19          6       1673        128
20          6       1801        128
SQL> DELETE FROM aaa;


分区表对某个分区的EXTENTS回收时:

alter table <table_name> modify partition <partition_name> deallocate unused keep 10m;
alter table <table_name> modify partition <partition_name> deallocate unused;
--前者为保存最小范围,即即使有更多的空间可以回收,但是要保证最小有10M的EXTENT存在
--后者为回收掉所有没有使用的EXTENT。
SQL> alter table aaa deallocate unused;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8
1          4         57          8
2          6       1057          8
3          6       1065          8
4          6       1073          8
5          6       1081          8
6          6       1089          8
7          6       1097          8
8          6       1105          8
9          6       1113          8
10          6       1121          8
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       1129          8
12          6       1137          8
13          6       1145          8
14          6       1153          8
15          6       1161          8
16          6       1289        128
17          6       1417        128
18          6       1545        128
19          6       1673        128
20          6       1801        128


发现用DELETE删除掉的数据,无法将EXTENT回收,因为deallocate是回收高水位线以上的内容,而不是回收高水位线一下的空块,下面会提及什么是高水位线,TRUNCATE、DROP、SHRINK SPACE的区别所在。

这里用SHRINK SPACE做一个操作,其余的TRUNCATE和DROP就不用多说了:

SQL> alter table aaa enable row movement;


表已更改。

SQL> alter table aaa shrink space;


表已更改。

SQL> alter table aaa disable row movement;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='AAA';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1049          8


通过SHRINK SPACE后,变成了8个块了。

5、高水位线介绍

1、全表扫描的终点    从第一个块到这个块
2、并行插入的起点  大量加载数据,海量数据加载,直接用新块来装,而不是去找空块。/*+append*/
高水位线插入的逻辑图形如下(为什么叫逻辑图形,是因为实际的情况下有还要分块是自动管理的还是人工管理的,在ORACLE 10G的第二个版本自己创建的表空间默认是自动管理的,在块部分会专门介绍):

说明:deallocate是回收高水位线以上的进行回收掉,从上一个试验已经可以查看到了,不过为了专门说明这个,来做一个新的实验:

SQL> create table t1 as select * from emp where 1=2;


表已创建。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1057          8
SQL> INSERT INTO t1 select * from emp;


已创建14行。

SQL> INSERT INTO t1 select * from t1;


已创建14行。

SQL> /


已创建28行。

SQL> /


已创建56行。

SQL> /


已创建112行。

SQL> /


已创建224行。

SQL> /


已创建448行。

SQL> /


已创建896行。

SQL> /


已创建1792行。

SQL> commit;


提交完成。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1057          8
1          4         57          8
2          6       1065          8
3          4        633          8
SQL> DELETE FROM T1;


已删除3584行。

SQL> commit;


提交完成。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1057          8
1          4         57          8
2          6       1065          8
3          4        633          8
SQL> alter table t1 deallocate unused;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1057          8
1          4         57          8
2          6       1065          8
3          4        633          8


要回收这部分空间该如何操作呢?压缩,将表的空块进行压缩:

SQL> alter table t1 enable row movement;


表已更改。

SQL> alter table t1 shrink space;


表已更改。

SQL> alter table t1 disable row movement;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1057          8


这使得我们对DELETE、TRUNCATE、DROP、SHRINK SPACE几个参数到底做了什么有很大的兴趣,至于deallocate已经知道是回收高水位线以上的信息,那么这几个呢下面接着说:

6、DELETE、TRUNCATE、DROP、SHRINK SPACE区别

其实这部分已经在前面有所引导,这里再总结一下,然后做个简单试验:

DELETE:


1、只是对数据库块删除,相当于打一个标记一样,不会回收表空间,但是如果指针指向这个块的时候,这部分空间是可以被使用的;
2、数据会在UNDO表空间中存储一段时间(这部分会在专门讲解SEGMENT的时候说明);
3、使用手工提交,一些常规退出时会自动提交。
4、在非归档模式下可以在一定程度上进行程度的回退,在归档模式下几可以完全回退。
5、可以进行闪回
6、因为不会回收表空间,也不就不会回收高水位。
7、会产生大量的日志信息(即要保存以前的,也要保存现在的,所以UPDATE语句是最慢的)。

TRUNCATE(默认自带 DROP STORAGE参数,即删除存储):


1、产生非常少的日志信息、UNDO信息
2、认为是DDL语句,所以执行完就没有COMMIT的动作,直接提交
3、不能回退与闪回。
4、回收掉高水位信息,并释放空间。
5、保留大小为TABLE初始化创建时的STORAGE(initial 128k)的大小,默认情况下这个是8个块的大小,即64k。
6、由于其数据块的EXNTENT只剩下初始化的保留块,所以对象的DATA_OBJECT_ID将会被改变,OBJECT_ID是不会变化的,因为保留块部分没有被改变;付:如果这个表没有任何一行数据,直接TRUNCATE,DATA_OBJECT_ID也是不会变化的。

DROP:


1、不带PURGE的DROP只是修改名字,相当于一个RENAME操作,修改系统表空间SYSTEM的相应数据字典而已。
2、不带PURGE操作的DROP操作,表空间不会被释放,这个能保存多久不好说,一般来说只要表空间够用,就一直可以通过FLASHBACK闪回,当表空间不够用的时候,这部分空间将会被其他的空间所占用了,而且一次性将整个一个表的空间全部释放。
2、带PURGE操作的DROP操作,是彻底清楚数据并释放表空间信息。

SHRINK SPACE:


1、前提是允许表进行迁移,即,ROW MOVEMENT是ENABLE的。
2、将数据进行集中处理。
3、将空块进行回收。
4、即使是表定义中的initial的大小,也可以被回收掉。

测试实验如下:

SQL> drop table t1 purge;


表已删除。

SQL> create table t1 storage(initial 20m) as select * from emp where 1=2;


表已创建。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1161        128
1          6       1289        128
2          6       1417        128
3          6       1545        128
4          6       1673        128
5          6       1801        128
6          6       1929        128
7          6       2057        128
8          6       2185        128
9          6       2313        128
10          6       2441        128
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       2569        128
12          6       2697        128
13          6       2825        128
14          6       2953        128
15          6       3081        128
16          6       3209        128
17          6       3337        128
18          6       3465        128
19          6       3593        128


已选择20行。

SQL> truncate table t1;


表被截断。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1161        128
1          6       1289        128
2          6       1417        128
3          6       1545        128
4          6       1673        128
5          6       1801        128
6          6       1929        128
7          6       2057        128
8          6       2185        128
9          6       2313        128
10          6       2441        128
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
11          6       2569        128
12          6       2697        128
13          6       2825        128
14          6       2953        128
15          6       3081        128
16          6       3209        128
17          6       3337        128
18          6       3465        128
19          6       3593        128


已选择20行。

SQL> alter table t1 enable row movement;


表已更改。

SQL> alter table t1 shrink space;


表已更改。

SQL> alter table t1 disable row movement;


表已更改。

SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2  FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='T1';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0          6       1161          8


7、BLOCK存储原理

说到块,首先要提及一个问题,就是TABLESPACE的对SEGMENT_SPACE的管理方式有两种,分别是:MANUAL(人工)、AUTO(自动),在ORACLE 10G的第二个版本开始,自己创建的表空间默认是采用AUTO自动方式,下面分两大板块来说明什么是MANUAL,什么AUTO方式。

首先定义BLOCK的存储方式:

然后开始看下MANUAL与AUTO:

SQL> SELECT TABLESPACE_NAME,SEGMENT_SPACE_MANAGEMENT FROM DBA_TABLESPACES;
TABLESPACE_NAME                SEGMEN
------------------------------ ------
SYSTEM                         MANUAL
UNDOTBS1                       MANUAL
SYSAUX                         AUTO
TEMP                           MANUAL
USERS                          AUTO
TABLESPACE_NAME                SEGMEN
------------------------------ ------
ORA10TEST                      AUTO


可以发现,自己创建的表空间都是AUTO的方式,而默认的几个表空间都是MANUAL,这个是在创建表空间的时候决定,我们来看下SYSTEM表空间的创建语句:

SQL> set long 10000
SQL> set pages 20
SQL> set lines 200
SQL> select dbms_metadata.get_ddl('TABLESPACE','SYSTEM') FROM DUAL;
DBMS_METADATA.GET_DDL('TABLESPACE','SYSTEM')
----------------------------------------------------------------------
CREATE TABLESPACE "SYSTEM" DATAFILE
'D:/ORACLE/ORADATA/ORCL102/SYSTEM01.DBF' SIZE 314572800
AUTOEXTEND ON NEXT 10485760 MAXSIZE 32767M,
'D:/ORACLE/ORADATA/ORCL102/SYSTEM02.DBF' SIZE 1073741824,
'D:/ORACLE/ORADATA/ORCL102/SYSTEM03.DBF' SIZE 104857600
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE SEGMENT SPACE MANAGEMENT MANUAL
ALTER DATABASE DATAFILE
'D:/ORACLE/ORADATA/ORCL102/SYSTEM01.DBF' RESIZE 503316480
ALTER DATABASE DATAFILE
'D:/ORACLE/ORADATA/ORCL102/SYSTEM03.DBF' RESIZE 134217728


再看下USER表空间的定义:

SQL> SELECT DBMS_METADATA.GET_DDL('TABLESPACE','USERS') FROM dual;
DBMS_METADATA.GET_DDL('TABLESPACE','USERS')
-----------------------------------------------------------------------
CREATE TABLESPACE "USERS" DATAFILE
'D:/ORACLE/ORADATA/ORCL102/USERS01.DBF' SIZE 5242880
AUTOEXTEND ON NEXT 1310720 MAXSIZE 32767M,
'D:/ORACLE/ORADATA/ORCL102/USERS02.DBF' SIZE 268435456
LOGGING ONLINE PERMANENT BLOCKSIZE 8192
EXTENT MANAGEMENT LOCAL AUTOALLOCATE SEGMENT SPACE MANAGEMENT AUTO


此时自己创建一个MANUAL的表空间来做测试:

SQL> create tablespace tbs_manual datafile 'D:/ORACLE/ORADATA/ORCL102/manual01.dd' size 10m SEGMENT SPACE MANAGEMENT MANUAL;


表空间已创建。

SQL> create table tt tablespace tbs_manual as select * from emp where 1=2;


表已创建。

SQL> select tablespace_name from tabs where table_name='TT';
TABLESPACE_NAME
------------------------------
TBS_MANUAL
SQL> SELECT extent_ID,FILE_ID,BLOCK_ID,BLOCKS
2   FROM dba_extents
3  WHERE owner='SCOTT'
4  AND SEGMENT_NAME='TT';
EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------
0         20          9          8


说明这个表的第一个块的编号是9,那么向后数八个块分别就是:

9 10 11 12 13 14 15 16 这8个块;那么我们看下数据块的头部是存放在那里的呢?

SQL> SELECT HEADER_BLOCK FROM DBA_SEGMENTS
2  WHERE OWNER='SCOTT' AND SEGMENT_NAME='TT';
HEADER_BLOCK
------------
9
SQL> analyze table tt compute statistics;


表已分析。

SQL> SELECT BLOCKS,EMPTY_BLOCKS,FREELISTS,NUM_FREELIST_BLOCKS,PCT_FREE,PCT_USED
2   FROM TABS WHERE TABLE_NAME='TT';
BLOCKS EMPTY_BLOCKS  FREELISTS NUM_FREELIST_BLOCKS   PCT_FREE   PCT_USED
---------- ------------ ---------- ------------------- ---------- ----------
0           7          1                   0         10         40


可以发现有7个空数据块(因为有一个头部块11号块),FREELIST只有一个,PCT_FREE为表定义时决定,即当数据块内部的数据空闲空间少于这个数据的时候,就不允许再继续存放数据了,这是一个百分比,这里指当空闲空间少于8K的10%的时候,就不允许继续想内部增加数据,这部分空间用于块内部的数据进行字段加长用,如果块内部的数据经常做UPDATE,这个值可以适当增大一点,如果这个数据几乎不会做UPDATE操作,如一些固定的配置表一般只会做INSERT操作,那么就将他改成0;PCT_USED是代表当数据块小于这个百分比的时候,该数据库可以继续插入数据,如果为自动管理的表空间这部分为空。

为了一窥他们的究竟,我们讲数据块导出来看看里面是存放什么东西,先来导出头部块:

先看下导出目录:

SQL> show parameter user_dump
NAME                                 TYPE        VALUE
------------------------------------ ----------- -----------------------------
user_dump_dest                       string      D:/ORACLE/ADMIN/ORCL102/UDUMP


删除掉目录下所有东西(LINUX下用RM):

SQL> host del D:/ORACLE/ADMIN/ORCL102/UDUMP/*.*


D:/ORACLE/ADMIN/ORCL102/UDUMP/*.*, 是否确认(Y/N)? Y

查看一下数据文件在一个文件中:

SQL> select file_id,block_id from dba_extents where segment_name='TT';
FILE_ID   BLOCK_ID
---------- ----------
20                                        9


我们导出第9块:

SQL> alter system dump datafile 20 block 9;


系统已更改。

此时发现刚才的目录(D:/ORACLE/ADMIN/ORCL102/UDUMP/)出现一个新的TRC文件,打开看下内容主要部分如下:

Dump file d:/oracle/admin/orcl102/udump/orcl102_ora_724.trc
Mon Aug 02 13:46:07 2010
ORACLE V10.2.0.1.0 - Production vsnsta=0
vsnsql=14 vsnxtr=3
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Windows XP Version V5.1 Service Pack 2
CPU                 : 2 - type 586
Process Affinity    : 0x00000000
Memory (Avail/Total): Ph:1810M/3036M, Ph+PgF:2149M/4921M, VA:847M/2047M
Instance name: orcl102
Redo thread mounted by this instance: 1
Oracle process number: 17
Windows thread id: 724, image: ORACLE.EXE (SHAD)
*** 2010-08-02 13:46:07.828
*** ACTION NAME:() 2010-08-02 13:46:07.812
*** MODULE NAME:(SQL*Plus) 2010-08-02 13:46:07.812
*** SERVICE NAME:(SYS$USERS) 2010-08-02 13:46:07.812
*** SESSION ID:(314.13) 2010-08-02 13:46:07.812
Start dump data blocks tsn: 18 file#: 20 minblk 9 maxblk 9
buffer tsn: 18 rdba: 0x05000009 (20/9)
scn: 0x0000.11cbd388 seq: 0x01 flg: 0x04 tail: 0xd3881001
frmt: 0x02 chkval: 0x113d type: 0x10=DATA SEGMENT HEADER - UNLIMITED
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x08732200 to 0x08734200
8732200 0000A210 05000009 11CBD388 04010000  [................]
8732210 0000113D 00000000 00000000 00000000  [=...............]
8732220 00000000 00000001 00000007 00001020  [............ ...]
8732230 00000000 00000000 00000007 0500000A  [................]
8732240 00000000 00000000 00000000 00000000  [................]
8732250 00000000 00000000 00000000 00000001  [................]
8732260 00000000 0000E3C9 40000000 0500000A  [...........@....]
8732270 00000007 00000000 00000000 00000000  [................]
8732280 00000000 00000000 00000000 00000000  [................]
Repeat 250 times
8733230 00000000 00010000 00010001 00000000  [................]
8733240 00000000 00000000 00000000 00000000  [................]
Repeat 250 times
87341F0 00000000 00000000 00000000 D3881001  [................]
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 7
last map  0x00000000  #maps: 0      offset: 4128
Highwater::  0x0500000a  ext#: 0      blk#: 0      ext size: 7
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk  0x00000000  offset: 0
Unlocked
Map Header:: next  0x00000000  #extents: 1    obj#: 58313  flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x0500000a  length: 7
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000
End dump data blocks tsn: 18 file#: 20 minblk 9 maxblk 9


其余部分暂时不用多看,前面是一些描述信息,中间是存放的些数据,人类几乎看不太懂,在说存放数据的时候再说,先看红色标注部分:

DATA SEGMENT HEADER:说明这是一个数据块头部。

0x0500000a:代表的是数据块的起始位置,BLOCK为9,那么数据块从10开始,而a正好是代表16进制的10。

length: 7 代表目前头部块管理的数据链表长度为7,和我们预想一致。

我们插入一条数据插入到哪里去了?我们用ROWID来找一找看下。

SQL> select rowid,dbms_rowid.rowid_block_number(rowid) file# from tt;
ROWID                   FILE#
------------------ ----------
AAAOPKAAUAAAAAKAAA         10


说明插入数据块10,是否是有顺序的呢?我们继续插入,用INSERT INTO TTSELECT * FROM TT自我复制,数据大概两百多行的时候再看:

SQL> select block#,count(1) from( select dbms_rowid.rowid_block_number(rowid) block# from tt) group by block#;
FILE#   COUNT(1)
---------- ----------
11        171
13         79
10        171
12        171


此时发现数据块变成了4个,而且使用了10、11、12、13,说明其使用的确是顺序的,那么开始说的PCT_USED当数据块少了的时候会有变化吗?我们把11块的数据全部删掉,再往里面放一些数据,看怎么样的:

SQL> DELETE FROM TT WHERE DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)=11;


已删除171行。

SQL> select file#,count(1) from( select dbms_rowid.rowid_block_number(rowid) file# from tt) group by file#;
FILE#   COUNT(1)
---------- ----------
13        79
10        171
12        171
SQL> commit;


提交完成。

SQL> insert into tt select * from tt;


已创建421行。

SQL> commit;


提交完成。

SQL> select file#,count(1) from( select dbms_rowid.rowid_block_number(rowid) file# from tt) group by file#;
FILE#   COUNT(1)
---------- ----------
11        171
13        171
14        158
10        171
12        171
SQL> analyze table tt compute statistics;


表已分析。

SQL> SELECT BLOCKS,EMPTY_BLOCKS,FREELISTS,NUM_FREELIST_BLOCKS,PCT_FREE,PCT_USED
2  FROM TABS WHERE TABLE_NAME='TT';
BLOCKS EMPTY_BLOCKS  FREELISTS NUM_FREELIST_BLOCKS   PCT_FREE   PCT_USED
---------- ------------ ---------- ------------------- ---------- ----------
5            2          1                   2         10         40


此时BLOCKS从0变成5个块,说明是被使用的块,EMPTY_BLOCK是2。

若某些表只会进行INSERT操作,没有UPDATE操作,PCT_FREE就可以设置为0,通过命令:

alter table tt pctfree 0;


即可修改,测试一下,开始一个块存放大概171行数据,是90%就跳过,那么预计修改是190条数据每个块就跳过:

SQL> select file#,count(1) from( select dbms_rowid.rowid_block_number(rowid) file# from tt) group by file# order by file#;
FILE#   COUNT(1)
---------- ----------
10        171
11        190
12        171
13        171
14        190
15        190
16        190
17         69


和我们预计的几乎一致,第17块尚未装满,所以为69条数据,以前的块既往不咎,那再改成一半试一试看:

SQL> alter table tt pctfree
2  50;


表已更改。

SQL> insert into tt select * from tt;


已创建1342行。

SQL> commit;


提交完成。

SQL> select file#,count(1) from( select dbms_rowid.rowid_block_number(rowid) file# from tt) group by file# order by file#;
FILE#   COUNT(1)
---------- ----------
10        171
11        190
12        171
13        171
14        190
15        190
16        190
17         94
18         95
19         94
20         94
21         94
22         95
23         94
24         95
25         94
26         95
FILE#   COUNT(1)
---------- ----------
27         95
28         95
29         94
30         95
31         88


看来的确是我们想要的理想效果,在适当的情况下选择适当的大小,可以该节约空间就节约空间,该节约提高时间就节约时间。

SQL> SELECT BLOCKS,EMPTY_BLOCKS,FREELISTS,NUM_FREELIST_BLOCKS,PCT_FREE,PCT_USED
2  FROM TABS WHERE TABLE_NAME='TT';
BLOCKS EMPTY_BLOCKS  FREELISTS NUM_FREELIST_BLOCKS   PCT_FREE   PCT_USED
---------- ------------ ---------- ------------------- ---------- ----------
23         0          1                   2         50         40


付:MANUAL管理方式在9i以前以及10g出来的第一个版本都是这样管理的,他是将块与块之间用链表相连接,指针指向当前操作的数据块,那个块有空间就向哪里蹦,如果数据块来回DELETE、UPDATE操作,会使得这个指针来回蹦,造成很大的性能问题,所以在ORACLE 10G的第二个版本,默认自己创建的表空间,使用自动管理方式,下面来看下自动管理和它的区别:

SEGMENT SPACE AUTO表空间的BLOCK:

先将开始该清理的东西清理掉:

SQL> drop tablespace tbs_manual including contents;


表空间已删除。

SQL> host del D:/oracle/oradata/orcl102/MANUAL01.DD
SQL> create tablespace tbs_manual datafile 'D:/oracle/oradata/orcl102/MANUAL01.DD' size 10m;


表空间已创建。

SQL> create table tt tablespace tbs_manual as select * from emp where 1=2;


表已创建。

SQL> SELECT TABLE_NAME,PCT_USED,PCT_FREE FROM TABS;
TABLE_NAME                       PCT_USED   PCT_FREE
------------------------------ ---------- ----------
DEPT                                              10
EMP                                               10
BONUS                                             10
SALGRADE                                          10
AAA                                               10
TT                                                10
TABLE_01                                          10
TABLE_02                                          10
PERSON                                            10
V_USER_OBJECTS                                    10
V_DBA_OBJECTS                                     10
TEST_OBJECTS                                      10
TEST                                              10
EMP_OTHER                                         10
TABLE_AJ_TEST                                     10
TEMPDBA                                40         10
T1                                                10


发现部行的PCT_USED字段有值,部分没有值,这里没有值就是自动管理的,有值的是手动管理的。

看下范围信息:

SQL>  SELECT BLOCK_ID,BLOCKS FROM DBA_EXTENTS
2  WHERE OWNER='SCOTT' AND SEGMENT_NAME='TT';
BLOCK_ID     BLOCKS
---------- ----------
9                                        8


发现和手工管理的这部分没有区别,再看下头部在那里?

SQL> SELECT HEADER_BLOCK FROM DBA_SEGMENTS
2  WHERE SEGMENT_NAME='TT';
HEADER_BLOCK
------------
11


为什么头部不是第9个块了呢?而是第11个,是随机的嘛?不是,肯定的,这里说明一下,自动管理的表的头部块在每个表创建的第一个EXTENTS的第三个块,而第一个块是一级位图,管理第一个EXNTENT内部的所有块信息,第二个块是二级位图,管理表扩展后其他EXTENT的头部块的信息,其余EXTENT有两个头部,根据EXTENT所管理块的数量一个分一半,当第二个快管理不过来的时候向头部块借位管理,如果两个块还管不过来,此时加二级树结构来管理头部节点(这个范围已经足够满足我们的要求),最多三层。

我们将这三个快导出来看下是什么东西:

分别是编号为9、10、11块:

SQL> select file_id,BLOCK_ID,BLOCKS FROM DBA_EXTENTS
2  WHERE OWNER='SCOTT' AND SEGMENT_NAME='TT';
FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ----------
20          9          8
SQL> alter system dump datafile 20 block 9;


系统已更改。

第9块关键信息:

Start dump data blocks tsn: 18 file#: 20 minblk 9 maxblk 9
buffer tsn: 18 rdba: 0x05000009 (20/9)
scn: 0x0000.11cbe288 seq: 0x01 flg: 0x04 tail: 0xe2882001
frmt: 0x02 chkval: 0x643b type: 0x20=FIRST LEVEL BITMAP BLOCK
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x080B2200 to 0x080B4200
80B2200 0000A220 05000009 11CBE288 04010000  [ ...............]
80B2210 0000643B 00000000 00000000 00000000  [;d..............]
80B2220 00000000 00000000 00000000 00000000  [................]
Repeat 1 times
80B2240 00000000 00000000 00000000 00000004  [................]
80B2250 FFFFFFFF 00000005 00000003 00000008  [................]
80B2260 00010001 00000000 00000000 00000000  [................]
80B2270 00000000 00000003 00000000 00000000  [................]
80B2280 00000000 00000000 00000000 00000000  [................]
80B2290 0500000A 00000000 00000000 00000003  [................]
80B22A0 00000008 0500000C 00000000 00000000  [................]
80B22B0 00000000 00000000 00000000 00000001  [................]
80B22C0 0000E3CC 00000000 00000000 05000009  [................]
80B22D0 00000008 00000000 00000000 00000000  [................]
80B22E0 00000000 00000000 00000000 00000000  [................]
Repeat 9 times
80B2380 00000000 00000000 00000000 00001011  [................]
80B2390 00000000 00000000 00000000 00000000  [................]
Repeat 485 times
80B41F0 00000000 00000000 00000000 E2882001  [............. ..]
Dump of First Level Bitmap Block
--------------------------------
nbits : 4 nranges: 1         parent dba:  0x0500000a   poffset: 0
unformatted: 5       total: 8         first useful block: 3
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 : 3
Bitmap block lock opcode 0
Locker xid:     :  0x0000.000.00000000
Inc #: 0 Objd: 58316
HWM Flag: HWM Set
Highwater::  0x0500000c  ext#: 0      blk#: 3      ext size: 8
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk  0x00000000  offset: 0
--------------------------------------------------------
DBA Ranges :
--------------------------------------------------------
0x05000009  Length: 8      Offset: 0
0:Metadata   1:Metadata   2:Metadata   3:unformatted
4:unformatted   5:unformatted   6:unformatted   7:unformatted
--------------------------------------------------------
End dump data blocks tsn: 18 file#: 20 minblk 9 maxblk 9


FIRST LEVEL BITMAP BLOCK:代表是一级位图

0x05000009  Length: 8:代表该快的二进制位数为9,长度为8的一个EXTENT归它管理。

Metadata:代表是保留信息,不可以被其他数据块占用的。

Unformatted:代表尚未格式化的信息。

parent dba:  0x0500000a:代表父级别管理头部位置a,代表10。

Highwater::  0x0500000c:代表高水位块的编号为c,代表12,所以此时要APPEND或者SQLLOADER就会从块编号13开始。

Scn:SCN号码是导出时这个数据块最新的SCN号码。

同理导出10:

SQL> alter system dump datafile 20 block 10;


系统已更改。

发现相应参数是:

SECOND LEVEL BITMAP BLOCK:代表是二级位图。

L1 Ranges : 下面列表代表它管理的所有管理EXNTET的一级位图,因为表默认有一个所以默认有一条数据。

导出11后,发现参数:

SQL> alter system dump datafile 20 block 11;


系统已更改。

PAGETABLE SEGMENT HEADER:代表是头部。

此时插入一条数据:

SQL> insert into tt select * from emp WHERE ROWNUM=1;


已创建14行。

SQL> select dbms_rowid.rowid_block_number(rowid) from tt;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------
14


按照道理,数据应该从第12块开始写入,这里不是,说明自动管理并不是按照顺序插入了,头部块在第三块,插入位置是剩余空块的随机找,找到一个写满一个再写下一个,因为一级位图保存了块的使用情况的目录结构,那么看下一级位图在插入后变成什么了?

SQL> alter system dump datafile 20 block 9;


系统已更改。

其余的没有变化,这部分变化了:

0:Metadata   1:Metadata   2:Metadata   3:75-100% free
4:75-100% free   5:75-100% free   6:75-100% free   7:75-100% free


从第四个块开始从unformated变成了free,而free基本全部是75~100%,为什么呢?我们再继续插入点数据看下有没有变化:

SQL> insert into tt select * from tt;


已创建14行。

SQL> /


已创建28行。

SQL> /


已创建56行。

SQL> commit;


提交完成。

SQL> alter system dump datafile 20 block 9;


系统已更改。

此时发现变样子了:

0:Metadata   1:Metadata   2:Metadata   3:75-100% free
4:75-100% free   5:25-50% free   6:75-100% free   7:75-100% free


我们再插入点数据看下:

0:Metadata   1:Metadata   2:Metadata   3:75-100% free
4:75-100% free   5:FULL   6:50-75% free   7:75-100% free


数据满了,在插入就要使用其他的块了,说明:

1、自动管理的数据块不在使用精确的百分比作为使用量,而是使用1/4的范围管理,这样来降低开销。

2、自动管理不在使用链表来串联,而是树结构来管理表。

那么二级位图来做下试验:

因为二级位图是管理多个EXTENT,所以我们就将表放大就可以了,也不用插入什么数据:

SQL> alter table tt allocate extent(size 5m);


表已更改。

SQL> alter system dump datafile 20 block 10;


系统已更改。

发现LIST Ranges变化为:

L1 Ranges :
--------------------------------------------------------
0x05000009  Free: 5 Inst: 1
0x05000089  Free: 5 Inst: 1
0x0500008a  Free: 5 Inst: 1
0x05000109  Free: 5 Inst: 1
0x0500010a  Free: 5 Inst: 1
0x05000189  Free: 5 Inst: 1
0x0500018a  Free: 5 Inst: 1
0x05000209  Free: 5 Inst: 1
0x0500020a  Free: 5 Inst: 1
0x05000289  Free: 5 Inst: 1
0x0500028a  Free: 5 Inst: 1


此时发现除第一个被管理的块(就是默认的哪个区,因为比较小,不需要两个块来管理),其余的都是成对出现,我们看下这个表所占用的区吧:

SQL> select EXTENT_ID,BLOCK_ID from dba_extents where segment_name='TT';
EXTENT_ID   BLOCK_ID
---------- ----------
0          9
1        137
2        265
3        393
4        521
5        649


这里第一个EXTENT不用多说,第二个为137,换算为16进制数据就是89,89+1=8a。以此类推,可见除第一个EXNTENT以外,每个EXTENT前面都有位图块,这些位图块被第一个EXTENT的二级位图管理,他只能保存一千个左右,当超过这个数据,就会请求头部帮忙,再帮不过来,就建立一个父亲节点,建立树结构来存储。

由于篇幅所限,这里不能再写了,其余的可以继续做相关实验推敲,即可搞明白,对于逻辑架构中最关键和最复杂的SGEMENT以及一些常用的表空间容量的管理知识其实本文已经测试中用过一些,不过在下一次一起总结。

1、BLOCK是逻辑的,绝大部分情况下操作系统块的整数倍。

2、创建表空间时决定其大小,若不指定,采用系统的DB_BLOCK_SIZE为默认大小,而创建数据库默认参数大小为8K,OLTP系统可以降低一点,OLAP系统中可以增大一点,后面再说明块的内核结构的时候,会说明为什么。

3、块内部也有头部(和一个表的头部不要混淆,对于一个表的头部,会在SEGMENT专门说明),头部存放的是块内部的目录、SCN号码、TX修改事务、TYPE类型,即那一块存放在那里,因为ROWID其实也是逻辑的,在块内部是随机存放的,所以需要记录实际的物理位置,而由于其目录规则的要求、以及内存存放结构,在一个8K数据块中最多只能存储740条左右的数据;而其目录存放规则是从上向下码放。

4、数据部分是从下向上码放,和头部夹杂部分为空闲区域,后面详细说明。

5、这里说的块都是堆表的,所谓堆表就是插入到数据块那个位置是随机的,我们是通过ROWID来找到位置的。

一行数据的存储规则为:

1、行的头部,每一行有一个头部代表是一行的开始。

2、列宽度+列值。

3、跨块目标ROWID,数据块存放不下的时候,就会形成跨块,这种在结构设计上是很忌讳的。

4、数据仓库中,大量读取操作,一行内部存储的数据较多,所以将块设置大一些,可以存放更多的数据,否则块就会非常多,造成过多的IO;而OLTP系统中更多的是频繁的修改数据,即对块的征用,而要求对块的利用率要求较高,此时块可以适当多一些来达到这种效果。




赞(0)    操作        顶端 
联动大白
注册用户
等级:列兵
经验:91
发帖:0
精华:0
注册:2015-5-27
状态:离线
发送短消息息给联动大白 加好友    发送短消息息给联动大白 发消息
发表于: IP:您无权察看 2019-10-27 0:30:00 | [全部帖] [楼主帖] 2  楼

为了方便大家阅读,我对文章中错误号来解释一下吧!

Error Id: ORA-32771

Title: cannot add file to bigfile tablespace

Description:

cannot add file to bigfile tablespace

Action:

Do not use this command with bigfile tablespace.

Cause:

An attempt was made to add the second file to a bigfile tablespace.


Error Id: ORA-03263

Title: cannot drop the first file of tablespace string

Description:

cannot drop the first file of tablespace string

Action:

Cannot drop the first datafile with which ts is created

Cause:

Trying to drop the first datafile with which ts is created


也许你已明白,但对一个人有用也是我存在的理由!^_^ By:持之以恒的大白

-- 来自: 北京联动北方科技有限公司



赞(0)    操作        顶端 
总帖数
2
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论