Oracle 表空间详解(tablespace)

1 概述

以实体-关系图的形式绘制 Oracle 存储模型,逻辑结构在左,物理结构在右。
在这里插入图片描述

  • 有一个关系使用虚线绘制,表示段和数据文件的多对多关系。之所以使用虚线表示关系,是因为这种关系不应该存在。出色的关系工程师不应该允许多对多关系的存在。
  • 表空间实体消除了段与数据文件之间的多对多关系。一个表空间可以包含多个段,而且可以由多个数据文件组成。

小提示:

在创建 tableindex 时,都要带上 属主(对应用户的表空间)

2 语法

2.1 创建

  • 表空间创建者必须拥有 create tablespace 系统权限
  • 创建表空间时,默认/可选 的子句很多,我们只要知晓最常用的即可。
  • 非常完整的请参考: Oracle 12.2 官方文档 - create tablespace

常用语法:其中 [ ] 表示该参数可选

create [temporary | undo] tablespace "tbs"
datafile 'D:\oracle\tbs_01.dbf'
size 100m
[loggin | nologgin] -- 默认 loggin
[autoextend off] | [autoextend on next n1 maxsize m] -- 自动扩展, 默认 off, n1 默认 , m 默认 unlimited <= size n
[extent management local [uniform size n]] -- 默认 local, n = 64K;
[segment space management auto] -- 默认 auto, 且不建议被修改

-- 创建新用户,使用该表空间,方便测试
create user ODSDATA identified by 12345 default tablespace tbs
temporary tablespace temp quota unlimited on odstbs;
grant create session to ODSDATA;
grant resource to ODSDATA;

语法解析:

1. create tablespace tbs 创建一个名为 "tbs" 的表空间(最常用)
	(1) temporary: 临时表空间,用于临时数据的存放
	(2) undo: 撤销表空间,用于重做日志文件的存放

2. datafile 'D:\oracle\tbs_01.dbf' size 5m 指定数据文件的位置和大小
	(1) 数据文件位置: "D:\oracle\tbs_01.dbf" -- 推荐使用绝对路径
	(2) 数据文件大小: 5m
	(3) 如果有多个文件,可以用逗号 , 隔开. 但是每个每个文件都要指明大小
		
3. loggin | nologgin 默认是 loggin,一般不写,但你要知道
	(1) loggin: 创建表空间时,同时生成重做日志文件(数据丢失时,可以恢复)
	(2) nologgin: 与 loggin 相反,但表创建速度快

4. autoextend 表空间是否自动扩展
	(1) off: 不自动扩展,默认值
	(2) autoextend on next 10m maxsize 100m
		自动扩展,增量是 10m,最大大小是 100m
		
5. extent management local | dictionary 区管理
	(1) local 本地管理,强烈推荐,从 Oracle 9i 开始,只能用 local,效率高
	(2) dictionary 数据字典管理,以前的管理方式。
		将数据文件中的每一个存储单元做为一条记录,在大量数据管理时,会产生大量的 insertupdate 操作,严重影响性能。
		同时,长时间对表数据的操作,会产生很多磁盘碎片,这就是为什么要做磁盘整理的原因。

6. uniform size n: 指定 extent 的固定大小
    (1) size 8m: 固定为 8m
    (2) 若不填,extent 默认 64k (参考: dba_tablespaces 中的 initial_extent)

7. segment space management auto | manual
	(1) auto: 段空间由系统自动管理,只能使用在本地管理的表空间中(lob 字段的表除外)
	(2) manual: 段空间手动管理,目前已不用,主要是为了向后兼容

当我们创建完后,也可通过数据字典查询上述设置的参数:

SELECT ddf.file_id,
       ddf.file_name, -- 数据文件名称 datefile 'fileName'
       dt.tablespace_name, -- 表空间名称 tablespace tbs
       ddf.bytes / 1024 / 1024 || 'm' size_n, -- 初始数据文件大小,也就是 size n
       dt.logging, -- 日志属性 loggin
       ddf.autoextensible, -- 自动扩展
       dt.extent_management, -- extent management local | dictionary
       dt.allocation_type, -- system 长度自适应 | uniform 长度固定
       dt.segment_space_management, -- segment space management auto | manual
       dt.next_extent / 1024 / 1024 || 'm' next_n -- 数据文件增量大小,也就是 next n (当 allocata_type = 'uniform' 时,才有值)
  FROM dba_tablespaces dt, -- tablespace_name
       dba_data_files  ddf -- file_name, file_id, tablespace_name 
 WHERE ddf.tablespace_name = dt.tablespace_name
   AND dt.tablespace_name IN ('');

2.2 修改

  • 系统内置的表空间是不允许修改的,如:system、sysaux、temp、undo、users
  • 表空间名称修改之后相应的数据文件、位置、大小没有变化
  • 处于脱机状态的表空间不能修改其名称
1. 调整数据文件的大小
alter database datafile 'D:\oracle\tbs01_1.dbf' resize 10m;

2. 调整数据文件为自动扩展
alter database datafile 'D:\oracle\tbs01_1.dbf' autoextend on next 20m maxsize 1g; -- 增量 20m, 最大长度 1g

3. 新增数据文件
alter database datafile 'D:\oracle\tbs02_1.dbf' size 2000m; -- 不自动扩展
alter database datafile 'D:\oracle\tbs02_1.dbf' autoextend on next 20m maxsize 1g; -- 自动扩展

2.3 删除

  • Oracle 数据库的任何表空间都可以删除(除了 system、sysaux、temp、undo、users
  • 表空间一旦删除就不能恢复,所以删除表空间前最好备份
  • 不能删除含任何活动段的表空间,应该使表空间在被删除前脱机(很简单,不脱机或者说不关闭运行的 PL/SQL, 删除表空间会报错的)
  • 删除表空间的用户必须要拥有 drop tablespace 权限
1. 删除空的表空间(数据文件还在)
drop tablespace tbs;

2. 删除表空间 和 数据文件
drop tablespace tbs including contents and datafiles;

3. 仅从数据字典中删除表空间信息,但数据文件仍然存在,但已经失去作用
drop tablespace tbs including contents;

2.4 查询

查询表空间信息:(若有多个数据文件,需分组求和)

SELECT ddf.file_id 文件id,
       ddf.file_name 文件名,
       dt.tablespace_name 表空间名,
       dfs.block_id 块id,
       dt.contents 表空间类型,
       dt.extent_management 表空间管理模式,
       dt.segment_space_management 块空间管理模式,
       dt.allocation_type 分配类型, -- "system 系统随机" or "uniform 固定"
       dt.logging 日志模式,
       dt.force_logging 是否强制日志, -- 优先级 > 日志模式
       ddf.autoextensible 是否自动扩展,
       ddf.bytes / 1024 / 1024 "表空间初始大小(M)", -- 单位由 字节 -> MB
       ddf.maxbytes / 1024 / 1024 "表空间最大扩展到多少(M)", -- 0 表示自动扩展: off
       ddf.bytes / 1024 / 1024 "总大小(M)",
       dfs.bytes / 1024 / 1024 "剩余大小(M)",
       (1 - dfs.bytes / ddf.bytes) * 100 "使用率%"
  FROM dba_tablespaces dt, -- tablespace_name 
       dba_data_files  ddf, -- file_name, file_id, tablespace_name 
       dba_free_space  dfs -- tablespace_name, file_id, block_id 
 WHERE ddf.tablespace_name = dt.tablespace_name
   AND dfs.tablespace_name = ddf.tablespace_name
   AND dfs.file_id = ddf.file_id
   AND ddf.tablespace_name IN ('表空间名');

3 示例

3.1 创建自动扩展表空间

创建一个 100M 大小的数据库文件 student.dbf 的永久表空间 tbs_student, 每 10M 自动扩展,最大值为 500M

CREATE TABLESPACE tbs_student 
DATAFILE 'D:\table_space\student.dbf'
SIZE 100m
AUTOEXTEND ON NEXT 10M MAXSIZE 500M -- 自动扩展, 每次扩展 10M, 最大扩展到 500M
PERMANENT -- 永久表空间,默认
EXTENT MANAGEMENT LOCAL;

通过数据字典对表空间进行查询:

SELECT dt.tablespace_name 表空间名,
       dt.contents 表空间类型,
       dt.extent_management 表空间管理模式, -- "LOCAL 默认,本地" or "DICTIONARY 数据字典"
       dt.segment_space_management 段空间管理模式, -- "AUTO 默认,自动管理" or "MANUAL 手动管理"
       dt.logging 默认日志属性, -- "LOGGING 默认" OR "NOLOGGING"
       dt.allocation_type 分配类型, -- "SYSTEM 系统自动分配" or "UNIFORM 统一分配"
       dt.next_extent 默认增量, -- next, 当 allocation_type = UNIFORM 时,才有值
       ddf.file_id 文件id,
       ddf.file_name 文件名,
       ddf.autoextensible 是否自动扩展,
       ddf.bytes / 1024 / 1024 "表空间初始大小 M", --,单位
       ddf.maxbytes / 1024 / 1024 "表空间最大扩展到多少 M"
  FROM dba_tablespaces dt, -- tablespace_name
       dba_data_files  ddf -- file_id  
 WHERE ddf.tablespace_name = dt.tablespace_name
   AND ddf.tablespace_name = 'TBS_STUDENT';

查询结果:
在这里插入图片描述

3.2 表无法在表空间中扩展

原因:

  • 表空间满了!
    • 未设置表空间自动扩展
    • 或设置了表空间自动扩展,但超过了 MAXSIZE

测试用户准备

-- 表空间创建语句
CREATE TABLESPACE "TESTTBS_02" DATAFILE 
'D:\TABLE_SPACE\TESTTBS_02.DBF' SIZE 1m
AUTOEXTEND ON NEXT 1m MAXSIZE 2m
EXTENT MANAGEMENT LOCAL 
SEGMENT SPACE MANAGEMENT AUTO;

-- 测试用户
CREATE USER test_tablespace IDENTIFIED BY 12345 DEFAULT TABLESPACE TESTTBS_02;
GRANT CREATE SESSION TO test_tablespace; -- 允许登录
GRANT RESOURCE TO test_tablespace; -- 不对用户表空间进行限制

测试语句:

CREATE TABLE test_tablespace.stu_info (
  ID   NUMBER(10),
  NAME VARCHAR2(30)
);
DECLARE
   v_sql_insert VARCHAR2(500);
BEGIN
   -- 模拟插入语句
   v_sql_insert := 'INSERT INTO test_tablespace.stu_info (id, NAME) VALUES (:b1, :b2)';

   FOR i IN 1 .. 100000 LOOP
      EXECUTE IMMEDIATE v_sql_insert
         USING i, 'a' || i;
   END LOOP;
END;

错误截图:
在这里插入图片描述

4 扩展

参考语句:

1. 修改表空间名
ALTER TABLESPACE old_name RENAME TO new_name;

2. 设置数据库的默认表空间
ALTER DATABASE DEFAULT TABLESPACE mytbs;

3. 设置数据库的默认临时表空间
ALTER DATABASE TEMPORARY TABLESPACE temptbs;

4. 查询数据库的默认表空间
SELECT t.username, t.default_tablespace, t.temporary_tablespace FROM dba_users t;

5. 允许数据文件自动扩展
ALTER DATABASE DATAFILE 'D:\oracle\tbs01_1.dbf' AUTOEXTEND ON NEXT 10m MAXSIZE 100m;

6. 使用表空间脱机/联机 (有效/无效)
ALTER TABLESPACE tbs01 ONLINE; -- 联机、有效
ALTER TABLESPACE tbs01 OFFLINE; -- 脱机、无效

7. 使表空间只读(仍可执行 drop 删除对象操作)
ALTER TABLESPACE tbs01 READ ONLY;

8. 使表空间可读写(脱机状态的表空间不能修改为读写状态)
ALTER TABLESPACE tbs01 READ WRITE;

4.1 常见疑问

1. 是自动扩展,为什么还会提示空间不足?

AUTOEXTEND ON NEXT 1m MAXSIZE 2m

2.autoextend on 默认的 next 值是多少?

  • allocation_type = SYSTEM 时,next 值由系统统一分配,不固定
  • allocation_type = UNIFORM 时,next 值固定,如下
extent management local uniform size 8m -- next = 8m

4.2 相关知识点

猜你喜欢

转载自blog.csdn.net/qq_34745941/article/details/91039626
今日推荐