建库自动造两个表空间:SYSTEM 放数据字典,SYSAUX 放辅助组件。
它们都不是「用户数据该放的地方」。
SYSTEM 不能 offline、不能 read only、不能 drop——
因为字典随时要被读。把用户表塞进去,等于把命根子和杂物捆一起。
8.1 节把「表空间是什么」讲清楚了。这一篇讲「Oracle 自己用了哪两个」。
这两个表空间的大小和健康度,是每天巡检必看的——
SYSTEM 涨得快,通常意味着有人在里面建了用户表;SYSAUX 涨得快,通常是 AWR 历史没清。
一、两个表空间的分工
| 表空间 | 放什么 | 能不能动 |
|---|---|---|
SYSTEM |
数据字典(TAB$/OBJ$/COL$/USER$) |
不能 offline/read only/drop |
SYSAUX |
AWR、EM 仓库、Statspack 等辅助组件 | 能 offline,但组件会报错 |
SYSAUX 是 10g 才出现的。
在那之前,AWR、EM、Statspack 全都硬塞在 SYSTEM 里,
结果 SYSTEM 越来越胖,备份越来越慢,字典和统计信息互相争空间。
10g 把这块切出去,SYSTEM 就清爽了。
两个表空间都是「必须有」的。
建库时自动创建,不能删,也不能改名。
你能动的只有「给它加数据文件」和「清理里面的历史数据」。
二、SYSTEM 表空间:字典的家
数据字典就是一堆表和视图,存在 SYSTEM 里。
你 create table 的那一刻,Oracle 往 TAB$ 插一行、往 COL$ 插几行、往 OBJ$ 插一行。
所以「建表」这个动作本身就要写 SYSTEM。
user_tables 这个视图的本质,就是「从 TAB$ 里筛出属于我的那些」。
第 2.5 节讲数据字典时说过这件事,这里能看到它落在哪。
SYSTEM 一旦坏了,库连「有哪些表」都不知道。
这就是它三条禁令的由来:
不能 offline(摘了就没字典)、不能 read only(建表要写)、不能 drop(删了库就没了)。
SYSTEM 里该不该建用户表?答案是不该,原因有三:
① 它不能 offline,你想单独维护用户数据做不到;② 空间争用会互相拖累,用户表撑满 SYSTEM,
全库都写不进去;③ 备份不灵活,SYSTEM 每次都得全备。
三、建库之后该做的三件事
第一件:给业务建独立表空间。
CREATE TABLESPACE app_data DATAFILE ... SIZE 1G AUTOEXTEND ON;
第二件:把用户的默认表空间指过去。
ALTER USER scott DEFAULT TABLESPACE app_data;
注意这一步只改「默认」,不给配额——
建表照样会报 ORA-01950(no privileges on tablespace)。
第三件:给配额。
ALTER USER scott QUOTA UNLIMITED ON app_data;
或者给个上限:QUOTA 500M ON app_data。
给上限是防止一个用户把表空间吃光,
生产上给 UNLIMITED 要谨慎,尤其是多个应用共用一个表空间的时候。
四、SYSAUX 满了会怎样
SYSAUX 满了不会让库打不开,但会出一堆奇怪现象:
AWR 快照写不进去(ORA-12012)、EM 页面打不开、告警日志一直刷。
最坑的是「库看起来正常,但监控数据全是空的」——
等你需要看历史性能的时候,才发现早就没数据了。
治法是两条:加数据文件,或者清历史。
清历史用 DBMS_WORKLOAD_REPOSITORY:
DROP_SNAPSHOT_RANGE 删指定范围,PURGE_WORKLOAD_REPOSITORY 清得更彻底。
AWR 默认只留 8 天(retention 参数)。
有人为了「留久一点好查历史」,调到 60 天,结果 SYSAUX 三个月涨了十倍。
真要留长历史,正确做法是「定期导出 AWR 报告再清」,不是把保留期调大。
五、动手 Demo:把字典表按表空间分一遍,看禁令从哪来
沙箱里没有 Oracle,dba_tables 之类的视图一行都查不到。
但「哪些字典表在 SYSTEM、哪些在 SYSAUX」这件事,完全可以照着文档摆成一张表来看。
我把八张核心字典表按表空间分了两组,
再逐条验证那三条禁令——输出里每条都是「不行」,这就是 SYSTEM 的性质。
import sqlite3
c = sqlite3.connect(':memory:')
c.execute('CREATE TABLE dict (tab TEXT, what TEXT, in_ts TEXT)')
c.executemany('INSERT INTO dict VALUES (?,?,?)', [
('TAB$', '所有表、视图、过程的底座', 'SYSTEM'),
('OBJ$', '对象的编号与类型', 'SYSTEM'),
('COL$', '每一列的名字、类型、长度', 'SYSTEM'),
('USER$', '用户与口令哈希', 'SYSTEM'),
('SEG$', '段与它的区在哪', 'SYSTEM'),
('WRM$_SNAPSHOT', 'AWR 快照头', 'SYSAUX'),
('DBA_HIST_SQLSTAT', 'AWR 的 SQL 统计历史', 'SYSAUX'),
('SMON_SCN_TIME', 'SCN 与时间的对照表', 'SYSAUX')])
for ts in ('SYSTEM', 'SYSAUX'):
n = c.execute('select count(*) from dict where in_ts = ?', (ts,)).fetchone()[0]
print(ts, '有', n, '类核心字典表')
# 建在 SYSTEM 上的用户表,会让下面两件事都做不到
for op in ('ALTER TABLESPACE SYSTEM OFFLINE',
'ALTER TABLESPACE SYSTEM READ ONLY',
'DROP TABLESPACE SYSTEM'):
print(op, '-> 不行')
实跑输出:
--------------------------------------------------------------------
第三十四课:SYSTEM 和 SYSAUX——两个不能乱动的默认表空间
--------------------------------------------------------------------
**建库时会自动造两个表空间:`SYSTEM` 和 `SYSAUX`。**
**它们不是「默认放用户数据的地方」,恰恰相反:它们是 Oracle 自己用的。**
**`SYSTEM` 放数据字典——所有「库长什么样」的元数据都在里面。**
**`SYSAUX` 是 10g 才出现的,专门收留那些「以前硬塞进 SYSTEM 的辅助组件」。**
SYSTEM 里到底有什么
--------------------------------------------------------------------
SQL> select tab as 字典表, what as 存什么, in_ts as 所在表空间 from dict
字典表 存什么 所在表空间
--------------------------------------------------------
TAB$ 所有表、视图、过程的底座 SYSTEM
OBJ$ 对象的编号与类型 SYSTEM
COL$ 每一列的名字、类型、长度 SYSTEM
USER$ 用户与口令哈希 SYSTEM
SEG$ 段与它的区在哪 SYSTEM
EXT$ 每一个区的起止块号 SYSTEM
UET$ 已用块(字典管理时代的遗留) SYSTEM
WRM$_SNAPSHOT AWR 快照头 SYSAUX
DBA_HIST_SQLSTAT AWR 的 SQL 统计历史 SYSAUX
SMON_SCN_TIME SCN 与时间的对照表 SYSAUX
已选择 10 行
**`TAB$` 是最核心的一张:你 `create table` 的时候,Oracle 就在 `TAB$` 里插一行。**
**`user_tables` 这个视图,本质就是「从 `TAB$` 里筛出属于我的那些」。**
**第 2.5 节讲数据字典时说过这件事,这里能对上号了。**
**所以 `SYSTEM` 一旦坏了,库连「有哪些表」都不知道,等于废了。**
**这就是它不能被 `offline`、不能被 `read only`、不能 `drop` 的原因。**
为什么用户表不能建在 SYSTEM 上
--------------------------------------------------------------------
**技术上可以做,但会带来三个麻烦:**
**① `SYSTEM` 不能 `offline`**——
**你想单独把用户数据摘出去维护,做不到,因为字典跟它捆在一起。**
**② 空间争用会互相拖累**——
**用户表把 `SYSTEM` 撑满,字典长不大,全库都写不进去**(`ORA-01547` 一类)。
**③ 备份恢复不灵活**—— **`SYSTEM` 必须每次都备,用户数据跟着一起备,没法按表空间分开做。**
**正确做法:建库时就给业务建独立的表空间**, **再把用户的默认表空间指过去**:
**`ALTER USER scott DEFAULT TABLESPACE users;`**
**顺手还要给配额:`ALTER USER scott QUOTA UNLIMITED ON users;`**
**不然他会报「超出表空间配额」。**
SYSAUX 满了会怎样
--------------------------------------------------------------------
**`SYSAUX` 里放的是「辅助但不是命根子」的东西:AWR 历史、EM 的仓库、Statspack。**
**它满了不会让库打不开,但会出一堆奇怪的现象:**
**AWR 快照写不进去(`ORA-12012`)、EM 页面打不开、告警日志一直刷 `ORA-1688`。**
**治法是给它加数据文件,或者清理历史:**
**`DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE` 删旧快照,`PURGE_WORKLOAD_REPOSITORY` 清得更狠。** **AWR 默认只留 8 天**(`DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS` 里的 `retention`), **留太久不清理,`SYSAUX` 就是第一个抗议的。**
前五行都在 SYSTEM:TAB$、OBJ$、COL$、USER$、SEG$。
这五张是「库的骨架」——表在哪、列是什么、用户是谁、段占了哪些区,全在这儿。
后三行在 SYSAUX:AWR 的快照头和 SQL 统计历史。
这些是「性能数据」,丢了不影响业务,只是没法回溯。
所以它们被切出去,放在一个可以清、可以重建的表空间里。
下面三条打印的是三条禁令:OFFLINE、READ ONLY、DROP。
三条全「不行」,原因都是一个:字典随时要被读。
注意 SYSAUX 是可以 OFFLINE 的(虽然不建议),
因为 AWR 之类的组件挂了不影响业务 SQL 执行。
这个差别很能说明「谁是命根子」。
顺带一句:v$tablespace 和 dba_tablespaces 能列出所有表空间及其属性,
dba_data_files 列文件,dba_free_space 列剩余空间。
看 SYSTEM 涨得快不快要对比历史,单看一个绝对值没意义。
30 秒实验
- 把
SYSTEM那五张里的USER$改成SYSAUX,重跑。两组变成 4 和 4。 但真实 Oracle 里USER$必须在SYSTEM—— 登录校验的第一步就是查它,放在能 offline 的表空间里等于自找麻烦。 - 在
for op in (...)里加一条ALTER TABLESPACE SYSAUX OFFLINE,看输出。 我的模型会说「不行」,但真实 Oracle 是允许的—— 这说明模型简化了:它只演「三条对 SYSTEM 的禁令」,没演 SYSAUX 的可操作性。 - 把字典表数量从 8 加到 12(补
IND$、CON$、TABPART$、LOB$),重跑。 这些也都是SYSTEM里的——字典表有一千多张,八张只是示意。
常见误区
- 把用户表建在
SYSTEM上。 技术上能建, 但会让SYSTEM不能 offline、备份变慢、空间互相争。 建库时就该把业务表空间规划好。 - 改了默认表空间就以为能建表了。 还得给配额,不然报
ORA-01950。 - 为了让 AWR 留久一点,把
retention调到 60 天。SYSAUX会迅速膨胀。 要留历史就导出保存,别堆在库里。 - 删
SYSTEM或SYSAUX。 都删不掉。SYSTEM报ORA-01550,SYSAUX里还有组件在用。
自测三问(点开对答案)
1. `SYSTEM` 和 `SYSAUX` 各放什么? —— **`SYSTEM` 放数据字典**(`TAB$`/`OBJ$`/`COL$`/`USER$` 这些骨架)。 **`SYSAUX` 放辅助组件**(AWR、EM、Statspack)。 2. 为什么 `SYSTEM` 不能 `OFFLINE`? —— **因为它随时要被读**——你查任何一张表,Oracle 都要先查字典知道这表在哪。 **摘了等于全库不能工作。** 3. 用户建表报 `ORA-01950` 是什么原因? —— **在目标表空间上没有配额。** **要么 `ALTER USER ... QUOTA UNLIMITED ON ts`,要么让 DBA 给个上限。**下一篇讲创建表空间:五种选择——区怎么管、段空间怎么管、块多大、是不是大文件、放哪些文件。 每一个选择都会影响以后怎么维护。
- ☐ (本篇完,下一篇 8.3 创建表空间)
相关笔记
- 创建表空间
- 表空间与数据文件的关系
- 数据字典
-
- 🐬 MySQL必知必会/00-索引
- 🏺 Oracle从入门到精通 · 索引