• OCP读书笔记(18)


    OLTP 表压缩

    压缩始终是非常占用CPU的过程,并且需要花费一定时间,通常,如果压缩数据,则数据必须解压缩后才能使用。虽然此要求在数据仓库环境中是可以接受的但在OLTP环境中可能无法接受

    现在,在Oracle数据库11g中,可以执行以下命令:

    create table my_compressed_table (
      col1 number(20),
      col2 varchar2(300),
      ...
    )
    compress for all operations

    “compress for all operations”子句在所有DML活动(如 INSERT、UPDATE等)上执行压缩,压缩在所有DML活动上发生,而不像oracle11g之前的版本那样,只在直接路径加载上发生

    OLTP table compress的原理

    当我们对一个表使用alter table <<table_name>> compress for oltp语句时,对已有的数据不受影响。但是他对一个块中新insert或update的行最开始也不受影响,直到这个数据块达到PCTFREE时才触发压缩,于是,现在新的压缩其实就是从老的方法:对每条新增的行做compress,变成了对一个block中的所有行批量处理,这样就让大部分的insert/update语句没有性能上的损失,只对insert/update导致某个块刚好达到PCTFREE的语句有一些负载

    当一个块由于触发压缩,而导致块的数据又低于PCTFREE的临界点后,这个块又可以接受更多的数据,会又一次达到PCTFREE,就会又一次压缩

    由于压缩作为触发事件发生,而不是在插入行时发生,因此在正常的DML进程中压缩对性能没有任何影响。压缩被触发后,对CPU的需求肯定会变得很高,但在其他任何时间CPU影响都为零,因此压缩也适用于OLTP应用程序

    OLTP compressed table和传统老的compressed table的空间利用情况的比较

    conn /as sysdba
    grant select on dba_objects to scott;
    
    conn scott/tiger
    create table newcomp compress for oltp as select * from dba_objects;
    create table oldcomp compress as select * from dba_objects;
    create table notcomp as select * from dba_objects;
    
    select table_name, compress_for from user_Tables where table_name in ('NEWCOMP','OLDCOMP','NOTCOMP');
    
    select segment_name, sum(bytes)/1024 KB from user_extents where segment_name in ('NEWCOMP','OLDCOMP','NOTCOMP') group by segment_name;

    两种压缩方式在最开始的时候差不多大

    update newcomp set object_name = object_name||'abc';
    update oldcomp set object_name = object_name||'abc';
    update notcomp set object_name = object_name||'abc';
    commit;
    
    select segment_name, sum(bytes)/1024 KB from user_extents where segment_name in ('NEWCOMP','OLDCOMP','NOTCOMP') group by segment_name;

    在大量更新后,我们发现,传统的表压缩逐渐丢失了自己压缩的特性,而OLTP compressed table却依然保持良好的压缩性能

    drop table OLDCOMP purge;
    drop table NEWCOMP purge;
    drop table NOTCOMP purge;

    收缩段

    SQL> grant select on dba_objects to scott;
    
    SQL> conn scott/tiger
    SQL> create table t as select * from dba_objects;
    SQL> create index ind_t on t(object_id);
    
    SQL> exec dbms_stats.gather_table_stats('scott', 't', cascade=>true);
    SQL> select num_rows, blocks from user_tables where table_name='T';
    SQL> delete t where rownum<=30000;
    SQL> commit;
    
    
    SQL> exec dbms_stats.gather_table_stats('scott', 't', cascade=>true);
    SQL> select num_rows, blocks from user_tables where table_name='T';
    
    SQL> alter table t enable row movement;
    SQL> alter table t shrink space compact;
    SQL> exec dbms_stats.gather_table_stats('scott', 't', cascade=>true);
    SQL> select num_rows, blocks from user_tables where table_name='T';
    
    SQL> alter table t shrink space;
    SQL> exec dbms_stats.gather_table_stats('scott', 't', cascade=>true);
    SQL> select num_rows, blocks from user_tables where table_name='T';
    
    
    SQL> select status from user_indexes where table_name='T' --段收缩之后索引仍然有效(valid);
    SQL> delete t;
    SQL> commit;
    
    SQL> alter table t shrink space;----默认执行两步
    SQL> exec dbms_stats.gather_table_stats('scott', 't', cascade=>true);
    SQL> select num_rows, blocks from user_tables where table_name='T';

    处理挂起的事务
    暂停失败的事物,不要回退,处理故障后继续运行源语句(9i的新特性)
    当事务缺少某些资源不能运行的时候数据库会有两种处理方法:
    一:自动的回退,当我们运行大的事物时,回退是很大的工作量
    二:数据库可以将事物挂起,等待新的资源到来,继续进行处理没有完成的事物,我们可以设置等待的时间,可以检测等待的资源

    SQL> drop tablespace t2m including contents and datafiles;
    SQL> create tablespace t2m datafile '/u01/app/oracle/oradata/orcl/t2m.dbf' size 1m autoextend off;
    
    SQL> conn scott/tiger
    SQL> drop table e purge;
    SQL> create table e tablespace t2m as select * from emp;
    SQL> insert into e select * from e;
    
    SQL> /
    insert into e select * from e
    ORA-01653: 表 SCOTT.E 无法通过 8 (在表空间 T2M 中) 扩展

    只回退当前的语句,其他插入还在,等待我们结束事务。

    conn /as sysdba
    SQL> grant execute on dbms_resumable to scott;
    SQL> grant resumable to scott;
    
    conn scott/tiger
    SQL> alter session enable resumable timeout 3600;

    启用挂起的特性

    conn /as sysdba
    grant select on v_$mystat to scott;
    SQL> select sid from v$mystat where rownum=1;
    --查看当前的会话
    SQL> select dbms_resumable.get_session_timeout(151) from dual;
    SQL> insert into e select * from e;
    --现在挂起不动了,等待资源,我们新开一个会话
    SQL> conn system/a
    SQL> select event from v$session_wait where sid=151;
    --看151会话在等待什么
    SQL> select error_msg from dba_resumable;
    
    SQL> select file_id from dba_data_files where tablespace_name='T2M';
    SQL> alter database datafile 7 resize 3m;
    
    --再回到第一个会话,我们看到
    14336 rows inserted
    SQL> commit;
  • 相关阅读:
    方法
    属性
    Cocoapods完整使用篇
    这样好用的ReactiveCocoa,根本停不下来【转载】
    OS开发之旅之App的生命周期【转载】
    ios 推送证书没有密钥 解决方案【转载】
    移动应用开发测试工具Bugtags集成和使用教程【转载】
    MagicalRecord使用教程【转载】
    GIT客户端的使用【原创】
    iOS开发系列--让你的应用“动”起来【转载】
  • 原文地址:https://www.cnblogs.com/thlzhf/p/3385683.html
Copyright © 2020-2023  润新知