一、性能优化策略
1. 批量处理优化
-
批量大小选择:
- 小批量(1,000-10,000行):减少UNDO生成,但需要更多提交次数
- 中批量(10,000-100,000行):平衡性能与资源消耗
- 大批量(100,000+行):适合高配置环境,但需监控资源使用
-
批量删除示例:
sql
BEGIN
FOR i IN 1..100 LOOP
EXECUTE IMMEDIATE 'DELETE /*+ PARALLEL(4) */ FROM 大表
WHERE ROWNUM <= 100000
AND 条件 AND MOD(id,100)=:i' USING i;
COMMIT;
DBMS_LOCK.SLEEP(0.1); -- 控制速度
END LOOP;
END;
2. 并行处理优化
-
并行查询设置:
sqlALTER SESSION ENABLE PARALLEL DML; ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
-
并行删除示例:
sqlDELETE /*+ PARALLEL(大表 8) */ FROM 大表 WHERE 创建时间 < ADD_MONTHS(SYSDATE, -36) AND ROWNUM <= 1000000;
3. 资源控制优化
-
UNDO表空间管理:
- 增大UNDO表空间:
ALTER TABLESPACE undo_ts ADD DATAFILE size 10G
- 设置UNDO保留期:
ALTER SYSTEM SET UNDO_RETENTION=900
(秒)
- 增大UNDO表空间:
-
临时表空间优化:
sql-- 检查临时表空间使用 SELECT tablespace_name, file_name, bytes/1024/1024 MB FROM dba_temp_files; -- 添加临时文件 ALTER TABLESPACE temp ADD TEMPFILE '/path/to/temp02.dbf' SIZE 20G;
4. 索引优化策略
-
删除前禁用索引:
sql-- 查询表索引 SELECT index_name FROM user_indexes WHERE table_name='大表'; -- 禁用索引 ALTER INDEX idx_name UNUSABLE; -- 删除后重建索引 ALTER INDEX idx_name REBUILD TABLESPACE index_ts;
-
选择性重建索引:
sql-- 只重建碎片化严重的索引 SELECT index_name, blevel, leaf_blocks, (leaf_blocks*8)/1024/1024 "Size(GB)", (select count(*) from 大表) "Table_Rows" FROM user_indexes WHERE table_name='大表' ORDER BY (leaf_blocks*8)/1024/1024 DESC;
二、空间回收策略
1. 段空间回收
-
SHRINK SPACE操作:
sql-- 启用行移动 ALTER TABLE 大表 ENABLE ROW MOVEMENT; -- 收缩表空间 ALTER TABLE 大表 SHRINK SPACE CASCADE; -- 禁用行移动 ALTER TABLE 大表 DISABLE ROW MOVEMENT;
-
MOVE操作:
sql-- 移动表到新表空间 ALTER TABLE 大表 MOVE TABLESPACE new_ts; -- 移动后重建索引 SELECT 'ALTER INDEX '||index_name||' REBUILD;' FROM user_indexes WHERE table_name='大表';
2. 表空间重组
-
表空间导出/导入重组 :
sql-- 1. 导出表空间 expdp system/password tablespaces=users directory=DATA_PUMP_DIR dumpfile=users_ts.dmp logfile=exp_users.log -- 2. 删除表空间文件 -- 3. 重建表空间 CREATE TABLESPACE users DATAFILE '/path/to/users01.dbf' SIZE 50G; -- 4. 导入数据 impdp system/password tablespaces=users directory=DATA_PUMP_DIR dumpfile=users_ts.dmp logfile=imp_users.log
3. ASM空间回收
-
ASM磁盘组空间释放 :
sql-- 检查ASM空间使用 SELECT name, total_mb, free_mb FROM v$asm_diskgroup; -- 手动释放空间(需要ASM权限) ALTER DISKGROUP dg_name REBALANCE POWER 10 WAIT;
三、日志与事务管理
1. 重做日志优化
-
调整日志大小和数量 :
sql-- 检查当前日志配置 SELECT group#, bytes/1024/1024 MB, members, status FROM v$log; -- 添加新的大日志组 ALTER DATABASE ADD LOGFILE GROUP 4 ('/path/to/redo04a.log','/path/to/redo04b.log') SIZE 2G; -- 切换日志 ALTER SYSTEM SWITCH LOGFILE; -- 删除旧日志组(确认不再使用后) ALTER DATABASE DROP LOGFILE GROUP 1;
2. NOLOGGING模式使用
-
设置表为NOLOGGING :
sqlALTER TABLE 大表 NOLOGGING; -- 重要操作后恢复LOGGING模式 ALTER TABLE 大表 LOGGING; -- 对分区表设置 ALTER TABLE 大表 MODIFY PARTITION part_name NOLOGGING;
3. 事务控制策略
-
分批提交控制 :
sql-- 每10,000行提交一次 DECLARE v_counter NUMBER := 0; BEGIN FOR rec IN (SELECT * FROM 大表 WHERE 条件 FOR UPDATE) LOOP DELETE FROM 大表 WHERE id = rec.id; v_counter := v_counter + 1; IF MOD(v_counter, 10000) = 0 THEN COMMIT; DBMS_LOCK.SLEEP(0.05); -- 控制速度 END IF; END LOOP; COMMIT; END;
四、备份与恢复策略
1. 清理前备份方案
-
RMAN备份策略:
sql-- 备份整个表空间 RMAN> BACKUP TABLESPACE users FORMAT '/backup/users_%U.bkp'; -- 备份特定表(11g+) RMAN> BACKUP DATAFILE 5 TAG='TABLE_BACKUP' SECTION SIZE 1G;
-
数据泵备份:
sql-- 创建目录对象 CREATE DIRECTORY backup_dir AS '/backup'; GRANT READ, WRITE ON DIRECTORY backup_dir TO username; -- 导出表数据 expdp username/password tables=大表 directory=backup_dir dumpfile=large_table.dmp logfile=exp_large.log
2. 闪回技术使用
-
闪回表恢复:
sql-- 启用行移动 ALTER TABLE 大表 ENABLE ROW MOVEMENT; -- 闪回表到时间点 FLASHBACK TABLE 大表 TO TIMESTAMP TO_TIMESTAMP('2023-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'); -- 或闪回到SCN FLASHBACK TABLE 大表 TO SCN 123456789;
-
闪回查询验证:
sql-- 查询历史数据 SELECT COUNT(*) FROM 大表 AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '1' HOUR WHERE 条件;
五、监控与验证
1. 实时监控脚本
-
监控删除进度 :
sql-- 监控会话的等待事件 SELECT s.sid, s.serial#, s.username, s.status, s.machine, s.program, se.wait_class, se.event FROM v$session s, v$session_wait se WHERE s.sid = se.sid AND s.username = 'YOUR_USERNAME' AND s.status = 'ACTIVE'; -- 监控表空间使用 SELECT df.tablespace_name "表空间", df.bytes/1024/1024 "总大小(MB)", (df.bytes-fs.bytes)/1024/1024 "已使用(MB)", fs.bytes/1024/1024 "空闲(MB)", ROUND(100*(1-fs.bytes/df.bytes)) "使用率(%)" FROM (SELECT tablespace_name, SUM(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) df, (SELECT tablespace_name, SUM(bytes) bytes FROM dba_free_space GROUP BY tablespace_name) fs WHERE df.tablespace_name = fs.tablespace_name;
2. 验证清理结果
-
数据完整性检查 :
sql-- 检查记录数 SELECT 'Before' AS status, COUNT(*) FROM 大表@source_db UNION ALL SELECT 'After' AS status, COUNT(*) FROM 大表; -- 检查关键业务数据 SELECT COUNT(*) FROM 大表 WHERE 关键字段 IS NULL; -- 检查分区数据分布 SELECT partition_name, num_rows FROM user_tab_partitions WHERE table_name='大表' ORDER BY partition_position;
六、异常处理方案
1. 常见错误处理
-
空间不足错误(ORA-01653/ORA-01654):
sql-- 解决方案: -- 1. 添加数据文件 ALTER TABLESPACE users ADD DATAFILE '/path/to/users05.dbf' SIZE 10G AUTOEXTEND ON; -- 2. 扩展现有数据文件 ALTER DATABASE DATAFILE '/path/to/users01.dbf' RESIZE 20G;
-
锁等待超时(ORA-30006):
sql-- 检查阻塞会话 SELECT blocking_session, sid, serial#, wait_class, seconds_in_wait FROM v$session WHERE blocking_session IS NOT NULL; -- 终止阻塞会话(谨慎使用) ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
2. 回滚策略
-
创建恢复点:
sql-- 创建保证恢复点 CREATE RESTORE POINT before_cleanup GUARANTEE FLASHBACK DATABASE; -- 执行清理操作... -- 出现问题时回滚 FLASHBACK DATABASE TO RESTORE POINT before_cleanup; -- 删除恢复点 DROP RESTORE POINT before_cleanup;
-
基于时间点的恢复:
sql-- 1. 关闭数据库 SHUTDOWN IMMEDIATE; -- 2. 启动到mount状态 STARTUP MOUNT; -- 3. 执行不完全恢复 RECOVER DATABASE UNTIL TIME '2023-11-01:12:00:00'; -- 4. 打开数据库 ALTER DATABASE OPEN RESETLOGS;
七、最佳实践总结
-
测试环境验证:在生产环境执行前,务必在测试环境验证清理脚本
-
分阶段实施:
- 第一阶段:小批量测试(1-10万行)
- 第二阶段:中等批量(10-100万行)
- 第三阶段:全量清理
-
资源监控:
- 监控CPU、内存、I/O使用率
- 监控UNDO和临时表空间使用
- 监控等待事件和会话状态
-
文档记录:
- 记录清理前的数据量
- 记录清理条件和范围
- 记录执行时间和资源消耗
- 记录验证结果和异常处理
-
自动化监控:
- 设置告警阈值(如表空间使用率>85%)
- 配置自动扩展策略
- 实现自动清理任务调度
通过以上优化策略和注意事项,可以确保Oracle大表清理过程高效、安全且可恢复,最大限度地减少对生产环境的影响。