前一天晚上作大表刪除操做測試,分段刪除,沒刪除100000條commit一次,因爲存儲過程打印了執行時間中途斷網,沒法看到執行時間
因而直接kill了任務
結果早上登陸測試數據庫發現空間爆滿
而後一時糊塗去弄了表的shrink跟dbms_stats.gather_table_stats想着收縮表釋放空間
弄到一半忽然想起,表的收縮最可能是釋放表空間的空閒空間,並不是系統空間
後來想一想,大量刪除反覆操做過程引起了undo的擴展,後來檢查表空間後確實如此
最後在線更換undo tablespace後刪除原tablespace後恢復
附上存儲過程sql
create or replace procedure delete_table as i number(15); l_start number default dbms_utility.get_time; begin dbms_output.put_line('begin time:'||to_char(SYSTIMESTAMP,'HH24:MI:SS:FF2')); i:=0; for x in (select log_id from user_log where user_log_id<46380000) loop delete from user_log where user_log_id = x.user_log_id; i:=i+1; if (i>10000) then begin --dbms_output.put_line('delete ok.'||i); commit; i:=0; end; end if; end loop; commit; dbms_output.put_line('ok.end time:'||to_char(SYSTIMESTAMP,'HH24:MI:SS:FF2')); exception when others then rollback; end; /
另外調試時記得 set serveroutput on數據庫
遇到的報錯提示
centos
[oracle@centos5 osa]$ dba SQL*Plus: Release 10.2.0.4.0 - Production on Fri Jun 21 09:23:18 2013 Copyright (c) 1982, 2007, Oracle. All Rights Reserved. ERROR: ORA-09817: Write to audit file failed. Linux-x86_64 Error: 28: No space left on device ORA-01075: you are currently logged on Enter user-name: ERROR: ORA-01017: invalid username/password; logon denied Enter user-name: ERROR: ORA-01017: invalid username/password; logon denied SP2-0157: unable to CONNECT to ORACLE after 3 attempts, exiting SQL*Plus
檢查磁盤空間,爆滿oracle
[oracle@centos5 osa]$ df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 93G 89G 0 100% / /dev/sda1 99M 12M 82M 13% /boot tmpfs 1006M 0 1006M 0% /dev/shm
想着收縮下大表就有空間了,,,糊里糊塗開始shrink
ide
[oracle@centos5 osa]$ sqlplus test/test SQL*Plus: Release 10.2.0.4.0 - Production on Fri Jun 21 09:23:26 2013 Copyright (c) 1982, 2007, Oracle. All Rights Reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> select table_name,BLOCKS,EMPTY_BLOCKS,NUM_ROWS from user_tables where table_name = upper('user_log'); TABLE_NAME BLOCKS EMPTY_BLOCKS NUM_ROWS ------------------------------ ---------- ------------ ---------- user_log 2606643 0 176544060 SQL> alter table user_log enable row movement; Table altered. SQL> alter table user_log shrink space cascade; --索引也能縮小 Table altered. SQL> select table_name,BLOCKS,EMPTY_BLOCKS,NUM_ROWS from user_tables where table_name = upper('user_log'); TABLE_NAME BLOCKS EMPTY_BLOCKS NUM_ROWS ------------------------------ ---------- ------------ ---------- user_log 2606643 0 176544060 SQL>
shrink後還須要從新收集統計信息,可是當空間爆滿時一樣沒法進行統計信息收集oop
SQL> exec dbms_stats.gather_table_stats('TEST','user_log'); BEGIN dbms_stats.gather_table_stats('TEST','user_log'); END; * ERROR at line 1: ORA-01114: IO error writing block to file %s (block # %s)
想一想其實收縮、整理,只是釋放表空間的已用空間到空閒空間,並不會回收實際的磁盤測試
先刪除了一些自己在在根目錄下的oracle安裝文件才能夠作undo表空間的重建工做,不然沒空間仍是沒法工做
因爲大量操做致使了undo的自動擴展,佔用了大量空間,準備收縮undospa
[root@centos5 ~]# su - oracle cd [oracle@centos5 ~]$ sqlplus test/test SQL*Plus: Release 10.2.0.4.0 - Production on Fri Jun 21 11:39:40 2013 Copyright (c) 1982, 2007, Oracle. All Rights Reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> @space.sql TABLESPACE_NAME TOTAL USED RATIO FREE MAX_BYTES --------------- ---------- ---------- ---------- ---------- ---------- SYSTEM 490 486.69 99.32 3.31 2.94 SYSAUX 380 377 99.21 3 .81 TEST 40960 20072.19 49.00 20887.81 3968 TS_OA 50 5.06 10.12 44.94 39.94 USERS 5 .44 8.80 4.56 4.56 TS_URP 200 5.37 2.69 194.63 190.81 UNDOTBS1 9195 134.31 1.46 9060.69 2965 OSA_TEST 500 7.31 1.46 492.69 485.94 TS_IMPTEST 50 .06 0.12 49.94 49.94 9 rows selected. SQL> select file_name,bytes/1024/1024 from dba_data_files where tablespace_name like 'UNDOTBS1'; FILE_NAME BYTES/1024/1024 ----------------------------------- ---------------- /home/oracle/oradata/osa/undotbs01.dbf 9195
undo表空間的重建工做3d
--一、創建一個全新的undostb2 SQL> create undo tablespace undotbs2 datafile '/home/oracle/oradata/osa/undotbs2.dbf' size 200M; Tablespace created. --二、修改系統的undo_tablespace爲undotbs2 SQL> alter system set undo_tablespace=undotbs2 scope=both; System altered. --三、刪除原有undo tablespace SQL> drop tablespace undotbs1 including contents; Tablespace dropped. --四、刪除數據文件釋放空間 rm -rf /home/oracle/oradata/osa/undotbs01.dbf
再來看看空間調試
SQL> @space.sql TABLESPACE_NAME TOTAL USED RATIO FREE MAX_BYTES --------------- ---------- ---------- ---------- ---------- ---------- SYSAUX 380 377.94 99.46 2.06 .63 SYSTEM 490 486.69 99.32 3.31 2.94 TEST 40960 20072.19 49.00 20887.81 3968 TS_OA 50 5.06 10.12 44.94 39.94 USERS 5 .44 8.80 4.56 4.56 TS_URP 200 5.37 2.69 194.63 190.81 OSA_TEST 500 7.31 1.46 492.69 485.94 UNDOTBS2 200 1.31 0.66 198.69 198.69 TS_IMPTEST 50 .06 0.12 49.94 49.94
再來收集統計信息查看下最高水位
SQL> select table_name,BLOCKS,EMPTY_BLOCKS,NUM_ROWS from user_tables where table_name = upper('user_log'); TABLE_NAME BLOCKS EMPTY_BLOCKS NUM_ROWS ------------------------------ ---------- ------------ ---------- user_log 2606643 0 176544060 SQL> exec dbms_stats.gather_table_stats('TEST','user_log'); PL/SQL procedure successfully completed. SQL> select table_name,BLOCKS,EMPTY_BLOCKS,NUM_ROWS from user_tables where table_name = upper('user_log'); TABLE_NAME BLOCKS EMPTY_BLOCKS NUM_ROWS ------------------------------ ---------- ------------ ---------- user_log 1719906 0 117470482 --shrink後統計信息更新了
若是是生產系統那會很慘,平常監控要很是注意數據庫空間、系統空間