首页 > 其他 > 详细

影响RESIZE数据文件的因素

时间:2015-01-29 02:18:00      阅读:252      评论:0      收藏:0      [点我收藏+]
       Oracle从7.2版本开提供ALTER DATABASE DATAFILE ‘<full path and name of the file>‘ RESIZE [K|M|G]操作,既可以加大数据文件的大小,也可以减小数据文件的大小,增加数据文件大小很简单,只要不要超过Oracle支持的最大数据文件大小即可,但是resize缺会经常遭遇ORA-03297报错。下面对减小数据文件的操作进行讨论。
       要想减小datafile的大小,必须在datafile的末尾有连续的free空间,这个可以通过DBA_FREE_SPACE视图查看,移除的空间不能被数据库对象使用。

  1. select owner ownr, segment_name name, segment_type type, extent_id exid, file_id fiid, block_id blid, blocks blks
  2. from dba_extents
  3. where file_id = &file_id
  4. order by block_id;
       datafile能够resize到多大,需要统计数据文件中所有的extents的大小,resize后的大小应该大于所有extents的大小。

  1. SELECT SUM(BYTES) FROM DBA_EXTENTS WHERE FILE_ID =&file_id;
      另外,数据文件能够resize到多大,可以用下面的脚本进行检测,如果输出中提示要move某些对象,表示resize不能成功:

  1. SET SERVEROUTPUT ON

  2. DECLARE
  3.      V_FILE_ID NUMBER;
  4.      V_BLOCK_SIZE NUMBER;
  5.      V_RESIZE_SIZE NUMBER;
  6. BEGIN
  7.      V_FILE_ID := &FILE_ID;
  8.      V_RESIZE_SIZE := &RESIZE_FILE_TO;

  9.      SELECT BLOCK_SIZE INTO V_BLOCK_SIZE FROM V$DATAFILE WHERE FILE# = V_FILE_ID;

  10.      DBMS_OUTPUT.PUT_LINE(‘.‘);
  11.      DBMS_OUTPUT.PUT_LINE(‘.‘);
  12.      DBMS_OUTPUT.PUT_LINE(‘.‘);
  13.      DBMS_OUTPUT.PUT_LINE(‘OBJECTS IN FILE ‘||V_FILE_ID||‘ THAT MUST MOVE IN ORDER TO RESIZE THE FILE TO ‘||V_RESIZE_SIZE||‘ BYTES‘);
  14.      DBMS_OUTPUT.PUT_LINE(‘===================================================================‘);
  15.      DBMS_OUTPUT.PUT_LINE(‘NON-PARTITIONED OBJECTS‘);
  16.      DBMS_OUTPUT.PUT_LINE(‘===================================================================‘);

  17.      for my_record in (
  18.           SELECT DISTINCT(OWNER||‘.‘||SEGMENT_NAME||‘ - OBJECT TYPE = ‘||SEGMENT_TYPE) ONAME
  19.           FROM DBA_EXTENTS
  20.           WHERE (block_id + blocks-1)*V_BLOCK_SIZE > V_RESIZE_SIZE
  21.           AND FILE_ID = V_FILE_ID
  22.           AND SEGMENT_TYPE NOT LIKE ‘%PARTITION%‘
  23.           ORDER BY 1) LOOP
  24.                DBMS_OUTPUT.PUT_LINE(my_record.ONAME);
  25.      END LOOP;

  26.      DBMS_OUTPUT.PUT_LINE(‘===================================================================‘);
  27.      DBMS_OUTPUT.PUT_LINE(‘PARTITIONED OBJECTS‘);
  28.      DBMS_OUTPUT.PUT_LINE(‘===================================================================‘);

  29.      for my_record in (
  30.           SELECT DISTINCT(OWNER||‘.‘||SEGMENT_NAME||‘ - PARTITION = ‘||PARTITION_NAME||‘ - OBJECT TYPE = ‘||SEGMENT_TYPE) ONAME
  31.           FROM DBA_EXTENTS
  32.           WHERE (block_id + blocks-1)*V_BLOCK_SIZE > V_RESIZE_SIZE
  33.           AND FILE_ID = V_FILE_ID
  34.           AND SEGMENT_TYPE LIKE ‘%PARTITION%‘
  35.           ORDER BY 1) LOOP
  36.                DBMS_OUTPUT.PUT_LINE(my_record.ONAME);
  37.      END LOOP;

  38. END;
  39. /
        一般如果上面的脚本提示可以resize时,resize就可以成功,但是有例外的情况,下面进行试验:

  1. --建立测试环境
  2. sqlplus / as sysdba

  3. alter system set recyclebin=on;

  4. SQL> create tablespace darren datafile ‘/oradata/gyl/darren.dbf‘ size 100m extent management local uniform size 1m;

  5. Tablespace created.

  6. SQL> select bytes from v$datafile where file# = 7;

  7.      BYTES
  8. ----------
  9.  104857600

  10. SQL> !ls -trl /oradata/gyl/darren.dbf
  11. -rw-r----- 1 oracle oinstall 104865792 Jan 27 20:23 /oradata/gyl/darren.dbf

  12. SQL> create user test identified by test;

  13. User created.

  14. SQL> grant dba to test;

  15. Grant succeeded.

  16. SQL> alter user test default tablespace darren;

  17. User altered.

  18. SQL> conn test/test
  19. Connected.

  20. BEGIN
  21.    for i in 1..10 LOOP
  22.       execute immediate ‘create table ‘ || ‘TEST‘||i ||‘ as select * from dba_objects‘;
  23.    end loop;
  24. end;
  25. /
 
 --此时的free空间为9437184
  1. SQL> select sum(bytes) from dba_free_space where file_id=7;

  2. SUM(BYTES)
  3. ----------
  4.    9437184
 
 --查看此时的extent情况,发现此时的block都是连续的
  1. select owner ownr, segment_name name, segment_type type, extent_id exid, file_id fiid, block_id blid, blocks blks
  2. from dba_extents
  3. where file_id = &file_id
  4. order by block_id
  5. /
  6.  Owner         Segment Name         Type     Extent# File# Block# Blocks
  7. -------- ------------------------------ -------- ------- ----- ------ --------
  8. TEST     TEST1                TABLE     0 7     128     128
  9. TEST     TEST1                TABLE     1 7     256     128
  10. TEST     TEST1                TABLE     2 7     384     128
  11. TEST     TEST1                TABLE     3 7     512     128
  12. TEST     TEST1                TABLE     4 7     640     128
  13. TEST     TEST1                TABLE     5 7     768     128
  14. TEST     TEST1                TABLE     6 7     896     128
  15. TEST     TEST1                TABLE     7 7     1024     128
  16. TEST     TEST1                TABLE     8 7     1152     128
  17. TEST     TEST2                TABLE     0 7     1280     128
  18. TEST     TEST2                TABLE     1 7     1408     128
  19. ...
  20. TEST     TEST10             TABLE     5 7    11136     128
  21. TEST     TEST10             TABLE     6 7    11264     128
  22. TEST     TEST10             TABLE     7 7    11392     128
  23. TEST     TEST10             TABLE     8 7    11520     128

 --删除第2到第8个表,还有第10个表,让块不连续,在第9个表前后都有free块
  1. BEGIN
  2.    for i in 2..8 LOOP
  3.       execute immediate ‘DROP table ‘ || ‘TEST‘||i;
  4.    end loop;
  5.    execute immediate ‘DROP TABLE TEST10‘;
  6. end;
  7. /
 --观察extent的情况,现在块不连续了
  1. Owner         Segment Name         Type     Extent# File# Block# Blocks
  2. -------- ------------------------------ -------- ------- ----- ------ --------
  3. TEST     TEST1                TABLE     0 7     128     128
  4. TEST     TEST1                TABLE     1 7     256     128
  5. TEST     TEST1                TABLE     2 7     384     128
  6. TEST     TEST1                TABLE     3 7     512     128
  7. TEST     TEST1                TABLE     4 7     640     128
  8. TEST     TEST1                TABLE     5 7     768     128
  9. TEST     TEST1                TABLE     6 7     896     128
  10. TEST     TEST1                TABLE     7 7     1024     128
  11. TEST     TEST1                TABLE     8 7     1152     128
  12. TEST     TEST9                TABLE     0 7     9344     128
  13. TEST     TEST9                TABLE     1 7     9472     128
  14. TEST     TEST9                TABLE     2 7     9600     128
  15. TEST     TEST9                TABLE     3 7     9728     128
  16. TEST     TEST9                TABLE     4 7     9856     128
  17. TEST     TEST9                TABLE     5 7     9984     128
  18. TEST     TEST9                TABLE     6 7    10112     128
  19. TEST     TEST9                TABLE     7 7    10240     128
  20. TEST     TEST9                TABLE     8 7    10368     128

  21. --删除表后,表使用的空间减小到了18874368
  22. SQL> SELECT SUM(BYTES) FROM DBA_EXTENTS WHERE FILE_ID =7;

  23. SUM(BYTES)
  24. ----------
  25.   18874368
  26.  
  27. --使用上面的测试脚本观察resize是否能成功
  28. Enter value for file_id: 7
  29. old 6: V_FILE_ID := &FILE_ID;
  30. new 6: V_FILE_ID := 7;
  31. Enter value for resize_file_to: 18874380       --这里稍微比extents的总大小大,保证能放下所有的对象
  32. old 7: V_RESIZE_SIZE := &RESIZE_FILE_TO;
  33. new 7: V_RESIZE_SIZE := 18874380;
  34. .
  35. .
  36. .
  37. OBJECTS IN FILE 7 THAT MUST MOVE IN ORDER TO RESIZE THE FILE TO 18874380 BYTES
  38. ===================================================================
  39. NON-PARTITIONED OBJECTS
  40. ===================================================================
  41. TEST.TEST9 - OBJECT TYPE = TABLE                                       --这里提示需要move掉test9,这与之前的理论对应,resize只能移除datafile末尾连续的free空间
  42. ===================================================================
  43. PARTITIONED OBJECTS
  44. ===================================================================

  45. PL/SQL procedure successfully completed.

  --不move掉test9是resize不成功的
  1. SQL> ALTER DATABASE DATAFILE \‘/oradata/gyl/darren.dbf\‘ RESIZE 18874380
  2. ALTER DATABASE DATAFILE \‘/oradata/gyl/darren.dbf\‘ RESIZE 18874380
  3. *
  4. ERROR at line 1:
  5. ORA-03297: file contains used data beyond requested RESIZE value

  6. --move走test9
  7. SQL> alter table test9 move tablespace users;

  8. Table altered.
 --再次进行检测,这次检测通过
  1. Enter value for file_id: 7
  2. old 6: V_FILE_ID := &FILE_ID;
  3. new 6: V_FILE_ID := 7;
  4. Enter value for resize_file_to: 18874380
  5. old 7: V_RESIZE_SIZE := &RESIZE_FILE_TO;
  6. new 7: V_RESIZE_SIZE := 18874380;
  7. .
  8. .
  9. .
  10. OBJECTS IN FILE 7 THAT MUST MOVE IN ORDER TO RESIZE THE FILE TO 18874380 BYTES
  11. ===================================================================
  12. NON-PARTITIONED OBJECTS
  13. ===================================================================
  14. ===================================================================
  15. PARTITIONED OBJECTS
  16. ===================================================================

  17. PL/SQL procedure successfully completed.

  18. --进行resize操作,还是失败
  19. SQL> ALTER DATABASE DATAFILE \‘/oradata/gyl/darren.dbf\‘ RESIZE 18874380;
  20. ALTER DATABASE DATAFILE \‘/oradata/gyl/darren.dbf\‘ RESIZE 18874380
  21. *
  22. ERROR at line 1:
  23. ORA-03297: file contains used data beyond requested RESIZE value

  24. --查看DARREN表空间中被删除的对象
  25. SQL> SELECT ORIGINAL_NAME FROM DBA_RECYCLEBIN WHERE TS_NAME = \‘DARREN\‘;

  26. ORIGINAL_NAME
  27. --------------------------------
  28. TEST10
  29. TEST8
  30. TEST7
  31. TEST6
  32. TEST5
  33. TEST4
  34. TEST3
  35. TEST2
  
 --上面resize失败是由于部分显示free的空间,实际上被recylebin对象占用,清除recyclebin对象后,resize成功执行
  1. SQL> purge tablespace darren;

  2. Tablespace purged.

  3. SQL> ALTER DATABASE DATAFILE \‘/oradata/gyl/darren.dbf\‘ RESIZE 18874380;

  4. Database altered.
  5. SQL> !ls -trl /oradata/gyl/darren.dbf
    -rw-r----- 1 oracle oinstall 18890752 Jan 27 21:02 /oradata/gyl/darren.dbf

         综上所述,resize是否能成功,有两个很重要的因素:1、free空间是否在datafile,且空间是连续的;
                                                                                   2、连续的剩余空间是否被回收站对象占用。




影响RESIZE数据文件的因素

原文:http://blog.itpub.net/29821678/viewspace-1417458/

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!