一、当表空间告急时会发生什么

想象一下,你正在愉快地使用DM数据库处理业务数据,突然系统弹出一个红色警告:"表空间不足"。这时候查询开始变慢,批量插入直接报错,甚至某些关键业务功能直接瘫痪。这就像开车时油表突然亮红灯,必须立刻处理,否则后果很严重。

DM数据库的表空间就像仓库的货架,数据就是货物。当货架塞满时,新货物就无处可放。比如我们有个订单表:

-- DM数据库示例:创建订单表
CREATE TABLE orders (
    order_id NUMBER PRIMARY KEY,
    customer_id NUMBER,
    order_date DATE,
    amount NUMBER(10,2)
) TABLESPACE users;  -- 指定存放在users表空间

当这个表空间剩余不足1%时,任何INSERT操作都会报"ORA-01653: unable to extend table"错误。这时候DBA的微信就会开始疯狂弹出告警消息。

二、紧急扩容的三种救命方案

2.1 直接扩大数据文件

这是最快速的止血方法,就像给仓库临时加装一排货架。DM数据库可以通过以下命令实现:

-- 查看当前数据文件情况
SELECT file_name, bytes/1024/1024 "Size(MB)", autoextensible 
FROM dba_data_files 
WHERE tablespace_name = 'USERS';

-- 扩容现有数据文件(示例扩大到2GB)
ALTER DATABASE DATAFILE '/dmdata/users01.dbf' RESIZE 2048M;

-- 设置自动扩展参数(每次扩展50MB,最大到5GB)
ALTER DATABASE DATAFILE '/dmdata/users01.dbf' 
AUTOEXTEND ON NEXT 50M MAXSIZE 5120M;

注意事项

  1. 需要确保磁盘有足够空间
  2. 大文件扩容可能导致服务短暂卡顿
  3. 建议在业务低峰期操作

2.2 新增数据文件

当原文件所在磁盘已满时,可以在其他磁盘新增文件:

-- 在挂载点/dmdata2下新增数据文件
ALTER TABLESPACE users 
ADD DATAFILE '/dmdata2/users02.dbf' SIZE 1024M 
AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

这就像在仓库隔壁又租了间库房,特别适合TB级大表的情况。

2.3 临时使用应急表空间

当半夜三点出现告警时,可以先用临时方案顶住:

-- 创建临时表空间组
CREATE TEMPORARY TABLESPACE temp_demo 
TEMPFILE '/dmdata/temp_demo.dbf' SIZE 500M;

-- 将用户临时表空间切换过去
ALTER USER app_user TEMPORARY TABLESPACE temp_demo;

三、治本优化:空间精细化管理

3.1 找出空间大胃王

先用SQL定位占用大户:

-- 查询表空间使用TOP10
SELECT segment_name, segment_type, bytes/1024/1024 MB 
FROM dba_segments 
WHERE tablespace_name = 'USERS'
ORDER BY bytes DESC
FETCH FIRST 10 ROWS ONLY;

曾经发现某个日志表占了800GB,实际只需要保留最近3个月数据。

3.2 数据归档实战

对于历史数据,可以这样处理:

-- 创建归档表(使用压缩存储)
CREATE TABLE orders_archive COMPRESS BASIC 
AS SELECT * FROM orders 
WHERE order_date < ADD_MONTHS(SYSDATE, -12);

-- 确认数据后删除原数据
DELETE FROM orders 
WHERE order_date < ADD_MONTHS(SYSDATE, -12);

-- 重建索引回收空间
ALTER INDEX orders_pk REBUILD;

3.3 分区表改造

对于持续增长的表,改用分区设计:

-- 改造为按月分区表
CREATE TABLE orders_part (
    order_id NUMBER,
    customer_id NUMBER,
    order_date DATE,
    amount NUMBER(10,2)
) PARTITION BY RANGE (order_date) (
    PARTITION p_202301 VALUES LESS THAN (TO_DATE('2023-02-01','YYYY-MM-DD')),
    PARTITION p_202302 VALUES LESS THAN (TO_DATE('2023-03-01','YYYY-MM-DD')),
    PARTITION pmax VALUES LESS THAN (MAXVALUE)
);

-- 数据迁移
INSERT /*+ APPEND */ INTO orders_part SELECT * FROM orders;

四、预防为主的运维体系

4.1 智能监控脚本

用Shell脚本实现自动预警:

#!/bin/bash
# DM表空间监控脚本
WARNING=90  # 预警阈值
CRITICAL=95 # 紧急阈值

space_used=$(sqlplus -s /nolog <<EOF
connect sys/password as sysdba
set heading off
select round(used_percent) 
from dba_tablespace_usage_metrics 
where tablespace_name='USERS';
exit;
EOF
)

if [ $space_used -ge $CRITICAL ]; then
    echo "CRITICAL: 表空间使用率 ${space_used}%"
    # 发送短信告警
    send_alert "空间紧急告警"
elif [ $space_used -ge $WARNING ]; then
    echo "WARNING: 表空间使用率 ${space_used}%"
fi

4.2 自动化扩容方案

结合Ansible实现自动扩容:

# ansible-playbook dm_expand.yml
- hosts: db_servers
  tasks:
    - name: 检查表空间
      dm_sql:
        sql: SELECT round(used_percent) FROM dba_tablespace_usage_metrics WHERE tablespace_name='USERS'
      register: space_used

    - name: 自动扩容
      when: space_used.stdout|int >= 90
      dm_sql:
        sql: ALTER DATABASE DATAFILE '/dmdata/users01.dbf' RESIZE {{ current_size|int + 1024 }}M

4.3 定期维护日历

建议的维护周期:

  • 每日:检查空间增长率
  • 每周:分析碎片情况
  • 每月:执行统计信息收集
  • 每季:评估分区策略

五、技术方案选型建议

应用场景对比

  1. 紧急处理:首选数据文件扩容
  2. 长期方案:分区表+归档策略
  3. 海量数据:考虑分布式改造

技术优缺点

  • 直接扩容:简单快速,但治标不治本
  • 数据归档:需要应用配合改造
  • 分区表:前期设计复杂,后期维护轻松

特别注意事项

  1. 扩容前务必检查磁盘inode是否足够
  2. 归档操作要在业务低峰期进行
  3. 分区表可能影响现有SQL性能

通过这套组合拳,我们去年成功将某金融系统的表空间告警从每月20+次降到全年0次。记住,好的DBA不是救火队员,而是防患于未然的系统建筑师。