一、性能優化策略
1. 批量處理優化
-
批量大小選擇:
- 小批量(1,000-10,000行):減少UNDO生成,但需要更多提交次數
- 中批量(10,000-100,000行):平衡性能與資源消耗
- 大批量(100,000+行):適合高配置環境,但需監控資源使用
-
批量刪除示例:
BEGINFOR i IN 1..100 LOOPEXECUTE 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. 并行處理優化
-
并行查詢設置:
ALTER SESSION ENABLE PARALLEL DML; ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
-
并行刪除示例:
DELETE /*+ 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表空間:
-
臨時表空間優化:
-- 檢查臨時表空間使用 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. 索引優化策略
-
刪除前禁用索引:
-- 查詢表索引 SELECT index_name FROM user_indexes WHERE table_name='大表';-- 禁用索引 ALTER INDEX idx_name UNUSABLE;-- 刪除后重建索引 ALTER INDEX idx_name REBUILD TABLESPACE index_ts;
-
選擇性重建索引:
-- 只重建碎片化嚴重的索引 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操作:
-- 啟用行移動 ALTER TABLE 大表 ENABLE ROW MOVEMENT;-- 收縮表空間 ALTER TABLE 大表 SHRINK SPACE CASCADE;-- 禁用行移動 ALTER TABLE 大表 DISABLE ROW MOVEMENT;
-
MOVE操作:
-- 移動表到新表空間 ALTER TABLE 大表 MOVE TABLESPACE new_ts;-- 移動后重建索引 SELECT 'ALTER INDEX '||index_name||' REBUILD;' FROM user_indexes WHERE table_name='大表';
2. 表空間重組
- 表空間導出/導入重組:
-- 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磁盤組空間釋放:
-- 檢查ASM空間使用 SELECT name, total_mb, free_mb FROM v$asm_diskgroup;-- 手動釋放空間(需要ASM權限) ALTER DISKGROUP dg_name REBALANCE POWER 10 WAIT;
三、日志與事務管理
1. 重做日志優化
- 調整日志大小和數量:
-- 檢查當前日志配置 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:
ALTER TABLE 大表 NOLOGGING;-- 重要操作后恢復LOGGING模式 ALTER TABLE 大表 LOGGING;-- 對分區表設置 ALTER TABLE 大表 MODIFY PARTITION part_name NOLOGGING;
3. 事務控制策略
- 分批提交控制:
-- 每10,000行提交一次 DECLAREv_counter NUMBER := 0; BEGINFOR rec IN (SELECT * FROM 大表 WHERE 條件 FOR UPDATE) LOOPDELETE FROM 大表 WHERE id = rec.id;v_counter := v_counter + 1;IF MOD(v_counter, 10000) = 0 THENCOMMIT;DBMS_LOCK.SLEEP(0.05); -- 控制速度END IF;END LOOP;COMMIT; END;
四、備份與恢復策略
1. 清理前備份方案
-
RMAN備份策略:
-- 備份整個表空間 RMAN> BACKUP TABLESPACE users FORMAT '/backup/users_%U.bkp';-- 備份特定表(11g+) RMAN> BACKUP DATAFILE 5 TAG='TABLE_BACKUP' SECTION SIZE 1G;
-
數據泵備份:
-- 創建目錄對象 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. 閃回技術使用
-
閃回表恢復:
-- 啟用行移動 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;
-
閃回查詢驗證:
-- 查詢歷史數據 SELECT COUNT(*) FROM 大表 AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '1' HOUR WHERE 條件;
五、監控與驗證
1. 實時監控腳本
- 監控刪除進度:
-- 監控會話的等待事件 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. 驗證清理結果
- 數據完整性檢查:
-- 檢查記錄數 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):
-- 解決方案: -- 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):
-- 檢查阻塞會話 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. 回滾策略
-
創建恢復點:
-- 創建保證恢復點 CREATE RESTORE POINT before_cleanup GUARANTEE FLASHBACK DATABASE;-- 執行清理操作...-- 出現問題時回滾 FLASHBACK DATABASE TO RESTORE POINT before_cleanup;-- 刪除恢復點 DROP RESTORE POINT before_cleanup;
-
基于時間點的恢復:
-- 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大表清理過程高效、安全且可恢復,最大限度地減少對生產環境的影響。