文章目录
- 前言
- 一、环境信息
- 二、问题现象
- 三、环境确认
-
- [3.1 确认路径、实例、用户](#3.1 确认路径、实例、用户)
- [3.2 检查表空间状态和目标文件是否存在](#3.2 检查表空间状态和目标文件是否存在)
- [3.3 检查 db_files 参数](#3.3 检查 db_files 参数)
- [3.4 查看 USERS 现有数据文件](#3.4 查看 USERS 现有数据文件)
- [3.5 检查 Windows 磁盘剩余空间](#3.5 检查 Windows 磁盘剩余空间)
- 四、执行在线扩容
- 五、扩容后检查
-
- [5.1 确认新增文件已加入数据库](#5.1 确认新增文件已加入数据库)
- [5.2 再次检查 USERS 表空间使用率](#5.2 再次检查 USERS 表空间使用率)
- [5.3 检查 datafile 状态和文件头状态](#5.3 检查 datafile 状态和文件头状态)
- 六、结果汇总
- 七、经验总结
- 附录:常用检查命令
前言
今天巡检的时候发现一套库的 USERS 表空间已经快顶满了,使用率到了 99.91%,剩余空间只有一百多 MB。
这种情况如果继续放着不管,后面业务写入、索引扩展、临时数据增长都有可能直接报错。数据库是生产库,所以本次处理思路很明确:不停库、不重启,在线给 USERS 表空间新增一个 datafile。(实际上autoextend自动扩展开启了)
一、环境信息
| 项目 | 内容 |
|---|---|
| 数据库版本 | Oracle Database 10g Enterprise Edition 10.2.0.4.0 64-bit |
| 操作系统 | Windows Server |
| 数据库名 / 实例 | ***EMR / ***emr |
| 目标表空间 | USERS |
| 处理方式 | 在线新增 datafile,不停库、不重启 |
| 新增文件 | D:\ORACLE\PRODUCT\10.2.0\ORADATA\***EMR\USERS14.DBF |
| 扩容结果 | USERS 使用率由 99.91% 降至 88.42% |
二、问题现象
巡检时发现数据库服务器 192.168.x.x 上的 Oracle USERS 表空间使用率接近 100%,剩余空间仅约 105MB。

从查询结果可以看到:
USERS表空间总量为117264MB- 剩余空间约
105.81MB - 使用率已经达到
99.91%
三、环境确认
3.1 确认路径、实例、用户
生产库操作最怕的不是命令难,而是连错库、找错实例、改错路径。
所以正式扩容前,先确认当前连接的数据库、实例、主机和登录用户。
sql
select name, open_mode, log_mode from v$database;
select instance_name, host_name, status from v$instance;
show user;

这里可以确认:
- 数据库处于
READ WRITE - 实例状态为
OPEN - 当前操作用户为
SYS - 数据库为
NOARCHIVELOG
这里要注意一下:该库处于
NOARCHIVELOG模式。表空间扩容本身是在线操作,但非归档模式下更要确认最近一次可靠备份,扩容完成后也要保证备份策略能覆盖新增的数据文件。
3.2 检查表空间状态和目标文件是否存在
继续确认 USERS 表空间状态,同时检查准备新增的 USERS14.DBF 是否已经被数据库登记,操作系统目录中是否已经存在同名文件。
sql
select tablespace_name, status, contents, extent_management
from dba_tablespaces
where tablespace_name='USERS';
select file_id, file_name
from dba_data_files
where upper(file_name) like '%USERS14.DBF%';
host dir D:\ORACLE\PRODUCT\10.2.0\ORADATA\***EMR\USERS14.DBF

确认结果:
USERS表空间状态为ONLINE- 数据库字典中没有
USERS14.DBF - Windows 目录中也不存在
USERS14.DBF
这一步很关键,避免新增 datafile 时文件名冲突或者误用已有文件。
3.3 检查 db_files 参数
Oracle 数据库中 datafile 数量不是无限加的,还需要看 db_files 参数是否够用。
sql
select value as db_files from v$parameter where name='db_files';
select count(*) as current_datafiles from v$datafile;

本次环境中:
db_files = 200- 当前 datafile 数量为
16
新增一个 datafile 后也不会触碰上限,所以这里没有风险。
3.4 查看 USERS 现有数据文件
接着看一下 USERS 表空间当前有哪些数据文件,以及这些文件的大小和自动扩展情况。
sql
select
file_id,
tablespace_name,
file_name,
round(bytes/1024/1024/1024,2) size_gb,
autoextensible,
round(maxbytes/1024/1024/1024,2) max_gb
from dba_data_files
where tablespace_name='USERS'
order by file_id;


可以看到当前已经有 USERS01.DBF 到 USERS13.DBF。
其中 USERS01.DBF 已接近 32G,上限空间不多,部分 5G 文件未开启自动扩展,后面的几个文件虽然开启了自动扩展,但从表空间总体剩余来看,已经不足以支撑后续业务增长。
所以这次不继续折腾已有文件,直接新增一个 datafile 更清晰。
3.5 检查 Windows 磁盘剩余空间
datafile 最终还是要落到操作系统磁盘上,所以扩容前必须看磁盘空间。
原数据文件路径在 D 盘,本次根据现场管理要求继续沿用 D 盘路径。

也可以用 wmic 查一下各盘符空间:
sql
host wmic logicaldisk get caption,freespace,size

扩容前 D 盘可用空间约 34.2G。虽然 E 盘空间更充足,但本次没有调整数据文件目录,仍然沿用原来的 D 盘路径。
这里就有一个容量策略问题:D 盘剩余不足 35G,不建议一次性新增 30G。最后采用初始分配 15G,自动扩展到最大 20G 的方案。
这样既能把 USERS 表空间告警降下来,又能给 D 盘保留一部分安全空间。
四、执行在线扩容
本次采用在线新增 datafile 的方式扩容 USERS 表空间。
执行命令如下:
sql
alter tablespace USERS
add datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\***EMR\USERS14.DBF'
size 15360M
autoextend on
next 512M
maxsize 20480M;
参数说明:
size 15360M:初始分配 15Gautoextend on:开启自动扩展next 512M:每次自动扩展 512Mmaxsize 20480M:最大扩展到 20G

返回 Tablespace altered.,说明命令执行成功。
五、扩容后检查
执行完成后,先看 D 盘剩余空间是否符合预期。

扩容前 D 盘剩余约 34.2G,扩容后剩余约 19.1G,空间变化基本符合新增 15G datafile 的预期。
5.1 确认新增文件已加入数据库
接着确认 USERS14.DBF 已被数据库识别,并且操作系统目录中可以看到该文件。
sql
select file_id, file_name
from dba_data_files
where upper(file_name) like '%USERS14.DBF%';
host dir D:\ORACLE\PRODUCT\10.2.0\ORADATA\***EMR\USERS14.DBF

Windows 资源管理器中也能看到新增文件:

这里可以确认:
- 新增文件名为
USERS14.DBF FILE_ID = 17- 初始文件大小约 15G
5.2 再次检查 USERS 表空间使用率
再次查询 USERS 表空间容量和使用率:
sql
select
df.tablespace_name,
round(df.total_mb,2) total_mb,
round(nvl(fs.free_mb,0),2) free_mb,
round((df.total_mb-nvl(fs.free_mb,0))/df.total_mb*100,2) used_pct
from
(select tablespace_name, sum(bytes)/1024/1024 total_mb
from dba_data_files
group by tablespace_name) df
left join
(select tablespace_name, sum(bytes)/1024/1024 free_mb
from dba_free_space
group by tablespace_name) fs
on df.tablespace_name = fs.tablespace_name
where df.tablespace_name='USERS';

扩容后:
USERS表空间总量增加到133224MB- 剩余空间约
15429.75MB - 使用率降至
88.42%
告警风险已经明显下降。
5.3 检查 datafile 状态和文件头状态
最后再看新增 datafile 的自动扩展参数、数据库状态以及文件头状态。
sql
select
file_id,
tablespace_name,
file_name,
round(bytes/1024/1024,2) size_mb,
autoextensible,
round(maxbytes/1024/1024,2) max_mb
from dba_data_files
where file_id=17;
select file#, name, status
from v$datafile
where name like '%USERS14.DBF%';
select file#, status, error
from v$datafile_header
where file#=17;

检查结果正常:
USERS14.DBF大小为15360MAUTOEXTENSIBLE = YESMAX_MB = 20480- datafile 状态为
ONLINE v$datafile_header中ERROR为空
到这里,数据库层面的扩容验证基本完成。
六、结果汇总
| 检查项 | 扩容前 | 扩容后 |
|---|---|---|
| USERS 表空间总量 | 117264 MB | 133224 MB |
| USERS 表空间剩余 | 约 105.81 MB | 约 15429.75 MB |
| USERS 表空间使用率 | 99.91% | 88.42% |
| D 盘剩余空间 | 约 34.2 GB | 约 19.1 GB |
| 新增数据文件 | 无 | USERS14.DBF,FILE_ID=17 |
| 新增文件大小 | 无 | 15G,最大自动扩展至 20G |
| 数据库状态 | READ WRITE / OPEN | 正常 |
| 业务影响 | 存在空间不足风险 | 在线扩容完成,业务正常 |
七、经验总结
这次扩容本身不复杂,核心就是在线新增 datafile,但生产环境里还是要把检查做完整。
几个需要注意的点:
- 生产环境扩容前一定要确认连接对象,至少核对数据库名、实例名、主机名、
OPEN_MODE和当前登录用户。 - 表空间开启自动扩展不等于安全,自动扩展最终还是会吃底层磁盘空间,所以要同时看表空间剩余和磁盘剩余。
- Oracle 10g 小文件表空间场景下,不建议无脑把单个数据文件一直扩到很大,新增 datafile 更便于控制和维护。
- 新增 datafile 前要确认文件名没有被数据库登记,磁盘目录中也不存在同名文件,避免重名或者误覆盖。
- 如果数据库是
NOARCHIVELOG,变更前后一定要确认可靠备份,新增 datafile 后备份策略也要覆盖这个新文件。 - 正式执行时建议开启
spool保存操作日志,执行后保留截图,包括扩容命令、表空间使用率、数据文件状态和磁盘空间。
附录:常用检查命令
sql
-- 数据库与实例确认
select name, open_mode, log_mode from v$database;
select instance_name, host_name, status from v$instance;
show user;
-- 表空间使用率
select
df.tablespace_name,
round(df.total_mb,2) total_mb,
round(nvl(fs.free_mb,0),2) free_mb,
round((df.total_mb-nvl(fs.free_mb,0))/df.total_mb*100,2) used_pct
from
(select tablespace_name, sum(bytes)/1024/1024 total_mb
from dba_data_files
group by tablespace_name) df
left join
(select tablespace_name, sum(bytes)/1024/1024 free_mb
from dba_free_space
group by tablespace_name) fs
on df.tablespace_name = fs.tablespace_name
where df.tablespace_name='USERS';
-- 数据文件明细
select
file_id,
tablespace_name,
file_name,
round(bytes/1024/1024/1024,2) size_gb,
autoextensible,
round(maxbytes/1024/1024/1024,2) max_gb
from dba_data_files
where tablespace_name='USERS'
order by file_id;
-- Windows 磁盘空间
host wmic logicaldisk get caption,freespace,size;
-- 告警日志路径
show parameter background_dump_dest;