1.数据库有序的逻辑体系
2.逻辑体系从老余养殖细细说起
推出的逻辑结构是:表空间(tablespace)、段(segment)、区(extent)、块(block)。Oracle server正是有条理地通过表空间以及段、区、块控制磁盘空间的合理高效的使用的
数据库(database)由若干表空间组成,表空间由若干段组成,段由若干区组成,区又是由Oracle的最小单元块组成的。
其中表空间又包含系统表空间、回滚段表空间、临时表空间、用户表空间。除了用户表空间外,其他三种表空间有各自特定的用途,不可随意更改和破坏,尤其是系统表空间更是需要被小心谨慎地保护
一系列连续的block组成了extent,一个或多个extent组成了segment,一个或多个segment组成了tablespace,而一个或多个tablespace组成了database(一个database要想存在,至少需要有SYSTEM及undo表空间
虽然block是Oracle中的最小逻辑数据单位,但是所有数据在文件系统层面最小物理存储单位是字节,操作系统中也有一个类似Oracle的块容量的参数(block size),但是Oracle总是访问整个Oracle block,而不是按照操作系统的block size来访问的。
设置为8KB,除此之外也有系统将其设置为2KB、4KB、16KB、32KB、64KB等其他大小。但是数据库的block一般要设置为操作系统块容量的整数倍,这样可以减少IO操作,这个大家说说为什么?
假如IO的大小设置为512字节(0.5KB),本来如果数据库的block设置为1KB正好是其两倍,但是设置为0.8KB,这时由于操作系统的单个块大小为0.5KB,需要两个操作系统块才可容纳下,于是就动用了两个操作系统块去容纳,相当于占用了1KB大小的空间,浪费了0.2KB。
数据库的组成分为数据块头(包括标准内容和可变内容)(common and variable header)、表目录区(table directory)、行目录区(row directory)、可用空间区(free space)、行数据区(row data)这5个部分
1.数据块头(header)中包含了此数据块的概要信息,例如块地址(block address)及此数据块所属的段的类型(比如到底是表还是索引)。
2.表目录区中存放了什么呢?只要有一行数据插入到数据块中,那该行数据所在的表的信息将被存储在这个区域。
3.行目录区中存放什么呢?其实就是存放你插入的行的地址。
4.可用空间区说来就简单了,就是块中的空余空间,为什么要有空余呢?后面我们会慢慢道来。这个空余的多少由Oracle的PCTFREE参数设置,如果是10,表示该块将会空余10%左右的空间。此外,如果是表或者索引块,该区域还会存储事务条目,大致有23字节左右的开销。
5 .而行数据区就更简单了,存储的是具体的行的信息或者索引的信息,这部分占用了数据块绝大部分的空间。
这里数据块头、表目录区、行目录区被统称为管理开销(overhead),其中有些开销的容量是固定的,而有些开销的总容量是可变的。数据块中固定及可变管理开销的容量平均在84字节到107字节之间。
区是Oracle数据库分配空间的最小单位,请注意分配这两个字
在Oracle数据库中,只要segment创建成功,数据库就一定为其分配了包含若干数据块的初始数据扩展(initial extent)
每个段的定义中都包含了数据扩展的存储参数(storage parameter)。存储参数适用于各种类型的段。这个参数控制着Oracle如何为段分配可用空间.
试验顺序是这样的:先建表空间(数据表空间、临时表空间和回滚段表空间),然后建指定用户,该用户登录后,在指定的表空间建表和建索引。
查看Oracle块的大小
SQL>
SQL> show user;
USER is "SYS"
SQL>
SQL> show parameter db_block_size
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
db_block_size integer 8192
SQL> ---也可以通过观察表空间视图dba_tablespaces的block_size值获取
SQL> select block_size
2 from dba_tablespaces
3 where tablespace_name='SYSTEM';
BLOCK_SIZE
----------
8192
SQL>
逻辑结构之tablespace
查看Oracle的数据表空间、临时表空间、回滚表空间、系统表空间的情况
SQL>
SQL> show user;
USER is "SYS"
SQL>
SQL> create tablespace TBS_MAXWELL
2 datafile '/u02/oradata/CDB1/pdb1/TBS_MAXWELL_01.dbf' size 100M
3 extent management local
4 segment space management auto;
Tablespace created.
SQL> col file_name format a50
SQL> set linesize 366
SQL> select file_name,tablespace_name,autoextensible,bytes
2 from dba_data_files
3 where tablespace_name = 'TBS_MAXWELL'
4 order by substr(file_name,-12);
FILE_NAME TABLESPACE_NAME AUTOEXTEN BYTES
-------------------------------------------------- ------------------------------------------------------------------------------------------ --------- ----------
/u02/oradata/CDB1/pdb1/TBS_MAXWELL_01.dbf TBS_MAXWELL NO 104857600
SQL>
SQL>
SQL> --临时表空间,有TEMPORARY及TEMPFILE关键字
SQL>
SQL> create temporary tablespace temp_maxwell
2 tempfile '/u02/oradata/CDB1/pdb1/TMP_MAXWELL.dbf' size 100M;
Tablespace created.
SQL>
SQL> select file_name,bytes,autoextensible from dba_temp_files where tablespace_name='TEMP_MAXWELL';
FILE_NAME BYTES AUTOEXTEN
-------------------------------------------------- ---------- ---------
/u02/oradata/CDB1/pdb1/TMP_MAXWELL.dbf 104857600 NO
SQL>
SQL>
SQL> ---回滚表空间(语法有些特别,有undo关键字)
SQL> create undo tablespace undotbs2 datafile '/u02/oradata/CDB1/pdb1/undotbs02.dbf' size 100M;
Tablespace created.
SQL> select file_name,
2 tablespace_name,
3 autoextensible,
4 bytes/1024/1024
5 from dba_data_files
6 where tablespace_name='UNDOTBS2'
7 order by substr(file_name,-12);
FILE_NAME TABLESPACE_NAME AUTOEXTEN BYTES/1024/1024
-------------------------------------------------- ------------------------------------------------------------------------------------------ --------- ---------------
/u02/oradata/CDB1/pdb1/undotbs02.dbf UNDOTBS2 NO 100
SQL> ---系统表空间和用户表空间都属于永久保留内容的表空间
SQL> select tablespace_name, contents
2 from dba_tablespaces
3 where tablespace_name in
4 ('TBS_MAXWELL', 'TEMP_MAXWELL', 'UNDOTBS2', 'SYSTEM', 'SYSAUX');
TABLESPACE_NAME CONTENTS
------------------------------------------------------------------------------------------ ---------------------------------------------------------------
SYSTEM PERMANENT
SYSAUX PERMANENT
TBS_MAXWELL PERMANENT
TEMP_MAXWELL TEMPORARY
UNDOTBS2 UNDO
SQL>
逻辑结构之user
如果你希望指定用户的默认表空间是某指定表空间,那么必须先建立该表空间,现在我们参与测试的表空间已经建好了,用户可以指定默认表空间了,请大家记得试验的先后顺序。
Oracle建用户和授权简单体验
SQL>
SQL> ---sysdba用户登录,假如maxwellpan用户存在,先删除
SQL> show user;
USER is "SYS"
SQL> drop user maxwellpan cascade;
drop user maxwellpan cascade
*
ERROR at line 1:
ORA-01918: user 'MAXWELLPAN' does not exist
SQL> --建用户,并将先前建的表空间tbs_maxwell和临时表空间temp_maxwell作为maxwellpan用户的默认使用空间。
SQL> create user maxwellpan identified by maxwellpan default tablespace tbs_maxwell temporary tablespace temp_maxwell;
User created.
SQL> --授权,暂且将最大权限给maxwellpan用户(切记仅用于非生产环境实验使用)
SQL> grant dba to maxwellpan;
Grant succeeded.
SQL> --可以登录maxwellpan用户了。
SQL> connect maxwellpan/maxwellpan@PDB1;
Connected.
SQL> show user;
USER is "MAXWELLPAN"
SQL>
逻辑结构之extent
Oracle的最小逻辑单位是块,而最小的扩展单位是区extent,这两个‘最小’请务必牢记.
SQL> --可以登录maxwellpan用户了。
SQL> connect maxwellpan/maxwellpan@PDB1;
Connected.
SQL> show user;
USER is "MAXWELLPAN"
SQL> --构造t(如果没有指明表空间,就是用户maxwellpan的默认表空间)
SQL> drop table t purge;
drop table t purge
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create table t(id int) tablespace tbs_maxwell;
Table created.
SQL> ---查询数据字典获取extent的相关信息。
SQL> select segment_name,extent_id,tablespace_name,bytes/1024/1024,blocks from user_extents where segment_name='T';
no rows selected
SQL> ---插入数据后继续观察,发现由原来的0个区增加为17个区
SQL> insert into t select rownum from dual connect by level<=100000;
100000 rows created.
SQL> commit;
Commit complete.
SQL> select segment_name,extent_id,tablespace_name,bytes/1024/1024,blocks from user_extents where segment_name='T';
SEGMENT_NAME
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
EXTENT_ID TABLESPACE_NAME BYTES/1024/1024 BLOCKS
---------- ------------------------------------------------------------------------------------------ --------------- ----------
T
0 TBS_MAXWELL .0625 8
T
1 TBS_MAXWELL .0625 8
T
2 TBS_MAXWELL .0625 8
T
3 TBS_MAXWELL .0625 8
T
4 TBS_MAXWELL .0625 8
T
5 TBS_MAXWELL .0625 8
T
6 TBS_MAXWELL .0625 8
T
7 TBS_MAXWELL .0625 8
T
8 TBS_MAXWELL .0625 8
T
9 TBS_MAXWELL .0625 8
T
10 TBS_MAXWELL .0625 8
T
11 TBS_MAXWELL .0625 8
T
12 TBS_MAXWELL .0625 8
T
13 TBS_MAXWELL .0625 8
T
14 TBS_MAXWELL .0625 8
T
15 TBS_MAXWELL .0625 8
T
16 TBS_MAXWELL 1 128
17 rows selected.
SQL>
逻辑结构之segment
SQL>
SQL> show user;
USER is "MAXWELLPAN"
SQL> drop table t purge;
Table dropped.
SQL> create table t(id int) tablespace tbs_maxwell;
Table created.
SQL> --查询数据字典获取segment相关信息
SQL> select segment_name,segment_type,tablespace_name,blocks,extents,bytes/1024/1024 from user_segments where segment_name='T';
no rows selected
SQL> ---插入数据后继续观察
SQL> insert into t select rownum from dual connect by level<=100000;
100000 rows created.
SQL> commit;
Commit complete.
SQL> select segment_name,segment_type,tablespace_name,blocks,extents,bytes/1024/1024 from user_segments where segment_name='T';
SEGMENT_NAME
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SEGMENT_TYPE TABLESPACE_NAME BLOCKS EXTENTS BYTES/1024/1024
------------------------------------------------------ ------------------------------------------------------------------------------------------ ---------- ---------- ---------------
T
TABLE TBS_MAXWELL 256 17 2
SQL> --插入大量记录后,发现确实有变化,块和区都增加了,区从0个增加为17个,块由0个增加为256个,段的大小由0M增长为2MB.
SQL> --观察索引段(其中idx_id这个段的segment_type为INDEX)
SQL> create index idx_id on t(id);
Index created.
SQL> select segment_name,segment_type,tablespace_name,blocks,extents,bytes/1024/1024 from user_segments where segment_name='IDX_ID';
SEGMENT_NAME
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SEGMENT_TYPE TABLESPACE_NAME BLOCKS EXTENTS BYTES/1024/1024
------------------------------------------------------ ------------------------------------------------------------------------------------------ ---------- ---------- ---------------
IDX_ID
INDEX TBS_MAXWELL 256 17 2
SQL> select count(*) from user_extents where segment_name='IDX_ID';
COUNT(*)
----------
17
SQL>
逻辑结构之二次体会
块的大小与调整
一般来说,Oracle默认的数据块大小就是8KB,是你在创建数据库时决定的,所以如果想改变块的大小,就必须在建库时指定。
在Oracle 9i以后的版本中,Oracle支持用户在新建用户表空间时指定块的大小,这意味着你的数据库有多个表空间,它们各自的块大小有可能各不相同。
切记只是新建自己的用户表空间,我们不可能更改原有的已经建好的表空间,更不可能更改或调整系统表空间。
Oracle可启用不同大小的块
SQL>
SQL>
SQL> show parameter cache_size
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
client_result_cache_size big integer 0
data_transfer_cache_size big integer 0
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0
db_flash_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
SQL>
你可以设置2KB、4KB、8KB、16KB、32KB的块大小,当你把db_16k_ cache_size设置为100MB时,意味着SGA中的Data Buffer数据缓存区中将会有100MB的大小让内存块可以以16KB大小进行访问,同时也意味着16KB大小的设置从此生效了。
启动block_size为16KB的块
[oracle@oracle-db-19c ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Tue Jan 3 17:51:40 2023
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> set pagesize 200
SQL> set linesize 200
SQL> show parameter cache_size
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
client_result_cache_size big integer 0
data_transfer_cache_size big integer 0
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 0
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0
db_flash_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
SQL> alter system set db_16k_cache_size=100M;
System altered.
SQL> show parameter 16k
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
db_16k_cache_size big integer 100M
SQL> --创建表空间,切记加上“blocksize 16K”关键字
SQL>
SQL> create tablespace TBS_MAXWELL_16k
2 blocksize 16K
3 datafile '/u02/oradata/CDB1/pdb1/TBS_MAXWELL_16k_01.dbf' size 100M
4 autoextend on
5 extent management local
6 segment space management auto;
Tablespace created.
SQL> ---观察发现,TBS_MAXWELL_16k这个表空间果然不同于原来的TBS_MAXWELL表空间,块的大小果然为16KB
SQL> select tablespace_name,
2 block_size
3 from dba_tablespaces
4 where tablespace_name in ('TBS_MAXWELL','TBS_MAXWELL_16k');
no rows selected
逻辑结构之三次体会
已用与未用表空间的情况
观察表空间的剩余情况
SQL> select sum(bytes)/1024/1024
2 from dba_free_space
3 where tablespace_name='TBS_MAXWELL';
SUM(BYTES)/1024/1024
--------------------
SQL>
观察表空间的总体分配情况
SQL> select sum(bytes)/1024/1024
2 from dba_data_files
3 where tablespace_name='TBS_MAXWELL';
SUM(BYTES)/1024/1024
--------------------
SQL>
查看数据库当前在用回滚表空间回滚段
SQL> show user;
USER is "SYS"
SQL> show parameter undo;
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
temp_undo_enabled boolean FALSE
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
SQL>
查看数据库有几个回滚段
SQL>
SQL> select tablespace_name,status from dba_tablespaces where contents='UNDO';
TABLESPACE_NAME STATUS
------------------------------------------------------------------------------------------ ---------------------------
UNDOTBS1 ONLINE
SQL>
查看数据库有几个回滚段,并查出它们的大小
SQL>
SQL> select tablespace_name,
2 sum(bytes)/1024/1024
3 from dba_data_files
4 where tablespace_name in ('UNDOTBS1','UNDOTBS2')
5 group by tablespace_name;
TABLESPACE_NAME SUM(BYTES)/1024/1024
------------------------------------------------------------------------------------------ --------------------
UNDOTBS1 290
SQL>
查看临时表空间
SQL>
SQL> select tablespace_name,
2 sum(bytes)/1024/1024
3 from dba_temp_files
4 group by tablespace_name;
TABLESPACE_NAME SUM(BYTES)/1024/1024
------------------------------------------------------------------------------------------ --------------------
TEMP02 5
TEMP 130
SQL>