如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!
诗檀软件专业数据库修复团队
服务热线 : 13764045638 QQ号:47079569 邮箱:[email protected]
Oracle中可能的碎片化汇总
何处碎片化了? | 发生原因 | 性能影响 | 容量影响 | 解決方案 |
block 数据块 | 1行的大小>1block时发生(行链接 chained rows) | 全面影响块的访问 | 因为碎片化所以所需容量增加 | 扩大block size |
block 数据块 | 更新一个更大的值(行迁移 migrated rows) | 全面影响块的访问 | 同上 | 重建表 or 更大的pctfree? |
Table 表 | 插入值后,发生大量删除(HWM上升后不会因为delete而下降) | 全扫描性能恶化 | 同上 | 重建表、SHRINK |
index 索引 | Index key值的更新以及删除 | Index扫描性能恶化 | 同上 | 重建索引?coalesce? |
extent 盘区 | 表以及index的追加或者删除 | 使用LOCAL extent Management 后几乎没有 | 同上 | UNIFORM EXTENT SIZE |
碎片化的结构以及种类
行链接 chained rows
1行的尺寸很大,无法收纳在一个块中时,就会将一行分割,收纳在多个块中。重建表治标不治本。
行迁移 migrated rows
在UPDATE等数据急剧增加,现有的块中无法容纳的情况下,就会只留下指针,转而储存到其他的块中。重建表可以暂时解决。
HWM的上升与碎片化
- 会被影响的处理是全扫描
索引的碎片化
表的碎片化确认SQL
注意 这里的碎片化 仅仅是指高水位与实际数据量不符而已,你可以选择什么都不做。
教条的说当 表的使用率(used_size/allocated size)小于70%以下时就需要维护了,这是教条的 和不合时宜的。
※请在统计信息是最新的状态下执行 col owner for a20 col table_name for a40 col line 1000 col pagesize 1000 #确认表碎片化的SQL SELECT b.owner "owner", b.table_name "table_naeme", ROUND(a.seg_bytes /1024/1024,1) "allocated_size(MB)", ROUND(b.tab_bytes /1024/1024,1) "used_size(MB)", ROUND((a.seg_bytes - b.tab_bytes)/1024/1024,1) "free(MB)" FROM (SELECT owner, segment_name, SUM(bytes) seg_bytes FROM dba_segments GROUP BY owner, segment_name ) a, (SELECT owner, table_name, SUM(num_rows*avg_row_len) tab_bytes FROM dba_tables GROUP BY owner, table_name ) b WHERE a.segment_name = b.table_name AND b.owner NOT IN('SYS','SYSTEM') ORDER BY 5 DESC;
碎片化解决方案
维护方法 | 所需时间 | 储存使用量 | 可否运行时进行搜索 | 可否运行时进行更新 | 解除已经上升的HWM | 解除行移行 | 使用实例 | 操作难度 | 对索引的影响 |
Export/Import(DataPump) | △ | × | ×(不可) | ×(不可) | ○(可) | ○(可) | ○ | ○ | ○(×) |
抽取以及载入比较耗时间 | 需要在数据库之外有存放空间 | 非常多 | 有非常多的资料 | 在direct时重建 | |||||
SHRINK方式 | △ | △ | ○(可) | ○(可) | ○(可) | ×(不可) | △ | ○(易) | ○(没有) |
Segment中分散很多时,比较花时间 | 虽然不需要另外追加容量,但UNDO可能增加 | 严格来说是不行的,但根据时机,也会有可行的时候。 | 基本无法解除行移行 | 有一些实际使用的例子 | 可以用1个SQL来执行 | ||||
重新定义在线表 | ○ | × | ○(可) | ○(可) | ○(可) | ○(可) | △ | △(中) | ○(没有) |
DB内部中的copy+差分同期+替换的时间 | 偶尔会需要两倍的尺寸 | 严格来说是不行的,但根据时机,也会有可行的时候。 | 关键数据库中有实际使用的例子 | 设定中需要多个index |
- FBDA的情况下、执行DISASSOCIATE_FBA,就可以执行碎片化解决方案。
- 在碎片化解决方案之中,执行内部复制的 项目的OBJECT_ID 会产生变换,所以避免执行的历史管理表就会分裂。
EXEC DBMS_FLASHBACK_ARCHIVE.DISASSOCIATE_FBA(‘[schema名]’,‘[表名]'); TRUNCATE TABLE [表名]; !expdp ・・・ content=data_only !impdp ・・・ content=data_only EXEC DBMS_FLASHBACK_ARCHIVE.REASSOCIATE_FBA (‘[schema名]’,‘[表名]');
确认索引的碎片化的SQL
※请保证在统计信息的状态是最新的状态下执行
select owner,index_name,blevel “height” from dba_indexes where blevel >3
- 阶层的高度: 4层以上( HEIGHT => 4 )
- 被删除的行队列所占的比例:从20到超过30%的情况( DEL_LF_ROW/LF_ROWS > 0.2 )
analyze index test_ind validate structure;
select NAME, HEIGHT, LF_ROWS, DEL_LF_ROWS from INDEX_STATS;
另外、INDEX_STATS视图的内容,会在切断session时被清理。
维护方法 | 所需时间 | 储存使用率 | 运行中可否使用索引 | 运行中可否使用更新 | 维护后数据的聚集 |
DROP INDEX→
CREATE INDEX |
× | ○ | △(可) | ×(不可) | ○ |
在建索引时需要进行全表扫描 | 不需要另外追加DB容量 | 可以搜索,但是全扫描 | 直到完成制成索引为止,都不能更新 | 再次编辑数据 | |
REBUILD方法 | ○ | △ | △(可) | ×(不可) | ○ |
利用现有的索引重建 | 需要与现有的索引的尺寸是相同的 | 虽然可以搜索索引,但执行时间过长的查询有失败的风险 | 直到完成再次构成索引为止,都不能更新 | 再次编辑数据 | |
REBUILD ONLINE方法 | × | × | △(可) | ○(可) | ○ |
在建索引时需要进行全表扫描 | 需要大于等于现有的索引的尺寸(种类表) | 虽然可以搜索索引,但执行时间过长的查询有失败的风险 | 再次编辑数据 |
取得停止时机的情况下
- 表:Export Import
- 可以活用现有的技术,从实际成绩较多的观点开始考虑。
- 索引:REBUILD方法
- 从维护速度的观点开始考虑
- 在用export Import完成时不需要
没有取得停止时机的情况下
- 表:重新定义在线表
- 可以对付行移行以及HWM两种情况,从作业时间较少的观点开始考虑
- 索引:REBUILD ONLINE
- 考虑维护中可以进行更新的办法
HWM位置的确认方法:
set serveroutput on; declare v_total_blocks number; --分配到segment中的所有块数 v_total_bytes number; --表示total_blocks的字节 v_unused_blocks number; --被分配的块中,还没有被使用过一次的块数。 v_unused_bytes number; --表示unused_blocks 的字节 v_last_used_extent_file_id number; --拥有HWM的extent所储存的数据文件的ID v_last_used_extent_block_id number; --拥有HWM的extent的第一块ID v_last_used_block number; --拥有HWM的extent中的块编号 begin dbms_space.unused_space(upper('&uname'), upper('&sename'), '&stype', v_total_blocks, v_total_bytes, v_unused_blocks, v_unused_bytes, v_last_used_extent_file_id, v_last_used_extent_block_id, v_last_used_block); dbms_output.put_line('有HWM的extent的数据文件的ID:' || to_char(v_last_used_extent_file_id, '9,999,990')); dbms_output.put_line('有HWM的extent的起始块ID:' || to_char(v_last_used_extent_block_id, '9,999,990')); dbms_output.put_line('有HWM的块的位置:' || to_char(v_last_used_block, '9,999,990')); end; /
Leave a Reply