1)ora-01653錯誤截圖:
可以看到有兩張表的insert受到了影響,都是在USERS表空間里。用以下SQL查看表空間使用情況:
SELECT a.tablespace_name "表空間名",a.bytes / 1024 / 1024 "表空間大小(M)",(a.bytes - b.bytes) / 1024 / 1024 "已使用空間(M)", b.bytes / 1024 / 1024 "空閑空間(M)",round(((a.bytes - b.bytes) / a.bytes) * 100, 2) "使用比" FROM (SELECT tablespace_name, sum(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) a, ( SELECT tablespace_name, sum(bytes) bytes, max(bytes) largest FROM dba_free_space GROUP BY tablespace_name ) b WHERE a.tablespace_name = b.tablespace_name ORDER BY ((a.bytes - b.bytes) / a.bytes) DESC;
可以看到USERS表空間已經使用了99.99%!馬上就100%,再也沒有地方存儲數據了!正式環境啊!情況危急!
2)解決辦法
--獲取數據文件dbf路徑 select tablespace_name, file_id,file_name, round(bytes/(1024*1024),0) total_space from dba_data_files order by tablespace_name;
以下兩種方案都需要獲取/home目錄下實際物理大小,我登錄到linux數據庫服務器后,使用du -sh命令查看了/home目錄大小為250GB。
第一種解決方案:
可以看到USERS表空間總共有3個dbf(此時我已經增加了04.dbf),復制其中一個dbf路徑 /home/oracle/oradata/users01.dbf,覆蓋下面的datafile參數:
--新增加一個dbf文件,指定該dbf文件大小為32GB左右,並使其每次自動擴展1GB,並且沒有最大限制 alter tablespace users add datafile '/home/oracle/oradata/users04.dbf' size 32760m autoextend on next 1024m maxsize unlimited; --segment space management auto extent management local; 據說可以連接上一句一起執行(把上一句分號去掉即可),沒執行,不知道執行效果,謹慎期間,慎用。
第二種解決方案:
--把原有的dbf數據文件大小調整(擴大) alter database datafile '/home/oracle/oradata/users01.dbf' resize 61440M; --沒試過,不知道效果
我用的是第一種解決方案,第二種沒試過,不知道效果如何。
3)解決后效果
我用的第一種解決方案,增加了04.dbf,再次使用SQL查看表空間使用情況:
SELECT a.tablespace_name "表空間名",a.bytes / 1024 / 1024 "表空間大小(M)",(a.bytes - b.bytes) / 1024 / 1024 "已使用空間(M)", b.bytes / 1024 / 1024 "空閑空間(M)",round(((a.bytes - b.bytes) / a.bytes) * 100, 2) "使用比" FROM (SELECT tablespace_name, sum(bytes) bytes FROM dba_data_files GROUP BY tablespace_name) a, ( SELECT tablespace_name, sum(bytes) bytes, max(bytes) largest FROM dba_free_space GROUP BY tablespace_name ) b WHERE a.tablespace_name = b.tablespace_name ORDER BY ((a.bytes - b.bytes) / a.bytes) DESC;
使用比已經從99.99%降低到69.42%,說明效果明顯,方案可用。
再去查看/home,使用du -sh命令查看了/home目錄大小為282GB。原來增加一個dbf文件會使得/home目錄實際也增加32GB大小。
4)注意事項及所有用到的SQL
在上面的第一種解決方案里,32760m 約等於 32GB,根據最大塊來算的,塊計算SQL:
SELECT UPPER(F.TABLESPACE_NAME) "表空間名",D.TOT_GROOTTE_MB "表空間大小(M)",D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空間(M)", TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),'990.99') || '%' "使用比", F.TOTAL_BYTES "空閑空間(M)",F.MAX_BYTES "最大塊(M)" FROM (SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / (1024 * 1024), 2) TOTAL_BYTES, ROUND(MAX(BYTES) / (1024 * 1024), 2) MAX_BYTES FROM SYS.DBA_FREE_SPACE GROUP BY TABLESPACE_NAME) F, (SELECT DD.TABLESPACE_NAME, ROUND(SUM(DD.BYTES) / (1024 * 1024), 2) TOT_GROOTTE_MB FROM SYS.DBA_DATA_FILES DD GROUP BY DD.TABLESPACE_NAME) D WHERE D.TABLESPACE_NAME = F.TABLESPACE_NAME ORDER BY 1;
其它SQL語句完整貼上來如下:
---查詢數據文件以及數據文件大小 select tablespace_name, file_id, file_name,round(bytes/(1024*1024),0) total_space from dba_data_files order by tablespace_name; select username, default_tablespace, temporary_tablespace from dba_users;
--獲取數據文件路徑 select tablespace_name, file_id,file_name, round(bytes/(1024*1024),0) total_space from dba_data_files order by tablespace_name; --讓數據文件自動擴展 alter tablespace users add datafile '/home/oracle/oradata/users04.dbf' size 32760m autoextend on next 1024m maxsize unlimited; --segment space management auto extent management local; 據說可以連接上一句一起執行(把上一句分號去掉即可),沒執行,不知道執行效果,謹慎期間,慎用。 --把數據文件大小調整 alter database datafile '/home/oracle/oradata/users01.dbf' resize 61440M; --沒試過,不知道效果
大SQL, 表本身大小,表的索引大小,表的LOB字段大小:
1 --大SQL,表本身大小。 2 --比如,索引有3個,然后匯總100M,然后表本身20M,最后的總數就是120,索引100M 3 select OWNER FD_OWNER,COLUMN_NAME FD_COLUMN_NAME,TABLE_NAME FD_TABLE_NAME, 4 case segment_name||'-' when '-' then table_name else segment_name end as FD_SEGMENT_NAME , 5 SEGMENT_TYPE FD_SEGMENT_TYPE,FD_BYTES,FD_MAX_SIZE, 6 ROUND(FD_BYTES / 1024 / 1024) FD_MB, 7 ROUND(sum(FD_BYTES) over(partition by segment_type) / 1024 / 1024) FD_SEGTYPE_TOTAL_MB, 8 ROUND(sum(FD_BYTES) over(partition by table_name ) / 1024 / 1024) FD_TOTAL_MB 9 from ( 10 --第一部分,表本身大小 11 select b.owner, null column_name,b.segment_name as table_name,b.partition_name as segment_name, 12 b.segment_type,sum(b.BYTES) FD_BYTES,sum(b.MAX_SIZE) FD_MAX_SIZE 13 from dba_segments b 14 where b.owner = 'COGLINK' 15 group by b.owner, b.segment_name, partition_name, b.segment_type 16 UNION ALL 17 --第二部分,表的索引大小 18 select a.owner, null column_name,a.table_name, b.segment_name,b.segment_type,sum(b.BYTES) FD_BYTES,sum(b.MAX_SIZE) FD_MAX_SIZE 19 from dba_indexes a, dba_segments b 20 where a.OWNER = b.owner and a.OWNER = 'COGLINK' 21 and a.index_name = b.segment_name group by a.owner, a.table_name, b.segment_name, b.segment_type 22 UNION ALL 23 --第三部分,如果表有LOB類型,LOB是單獨存放的,包括數據和索引都分開 24 select a.owner,a.column_name,a.table_name,b.segment_name,b.segment_type,b.BYTES FD_BYTES,b.MAX_SIZE FD_MAX_SIZE 25 from dba_lobs a, dba_segments b 26 where a.segment_name = b.segment_name 27 and a.owner = 'COGLINK' 28 UNION ALL 29 select a.owner,a.column_name,a.table_name,b.segment_name,b.segment_type,b.BYTES FD_BYTES,b.MAX_SIZE FD_MAX_SIZE 30 from dba_lobs a, dba_segments b 31 where a.index_name = b.segment_name 32 and a.owner = 'COGLINK' 33 ) f order by segment_type, FD_BYTES desc 34