Archive for October, 2010

>Shrinking Database Segments Online 在线收缩数据库段

>

Shrinking Database Segments Online 在线收缩数据库段
两个前提条件:
1.需要收缩的表必须enable row movement;
2.所在表空间必须是assm自动分段空间管理;
具体操作步骤如下:
1.select * from dba_tablespaces 确认表空间是否为assm;
2.alter table TD_EMAILQUEUE enable row movement
该步骤会导致引用此表的对象编译无效,需要重新编译相关代码;
3.ALTER TABLE TD_EMAILQUEUE SHRINK SPACE COMPACT
该步骤实际上是delete和insert的过程,产生Row-X (SX)锁,会造成rowid发生变化,需
要停掉基于rowid的触发器;
这时空间已经回收,但是高水位线并没有改变,这是为了尽可能减低对应用的影响;
4.ALTER TABLE TD_EMAILQUEUE SHRINK SPACE
该步骤修改表的高水位线,在业务不忙的时候执行;
第3和第4可以通过ALTER TABLE TD_EMAILQUEUE SHRINK SPACE一条命令实现

补充:
Shrink a table and all of its dependent segments (including LOB segments):
ALTER TABLE employees SHRINK SPACE CASCADE;

Shrink a LOB segment only:
ALTER TABLE employees MODIFY LOB (perf_review) (SHRINK SPACE);

Comments

>Oracle11g新特性_Pivot 和Unpivot

>

我从Oracle 数据库 11g: 面向 DBA 和开发人员的重要新特性
http://www.oracle.com/technology/global/cn/pub/articles/oracle-database-11g-top-features/index.html
测试了一些个人觉得对日常工作有用的特性进行测试。
需要详细信息请猛击上方链接或者查阅相关文档。

3.Pivot为SQL语言增添了一个非常重要且实用的功能。

  可以使用pivot函数针对任何关系表创建一个交叉表报表,

  而不必编写包含大量decode函数的令人费解的、不直观的代码。

  同样,您可以使用unpivot操作转换任何交叉表报表,以常规关系表的形式对其进行存储。

CREATE TABLE CUSTOMER

(

CUST_ID              NUMBER(10),

CUST_NAME            VARCHAR2(20),

STATE_CODE           VARCHAR2(20),

TIMES_PURCHASED      NUMBER(3)

) nologging

;

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(1,’sfsf’,'beijing’,1);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(2,’test’,'beijing’,3);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(3,’ayyt’,'beijing’,1);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(4,’bird’,'tianjin’,1);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(5,’call’,'shanghai’,1);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(6,’dogr’,'shanghai’,4);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(7,’elly’,'chongqing’,1);

insert into customer(cust_id,cust_name,state_code,times_purchased) values

(8,’febr’,'chongqing’,1);

commit;

想得到如下结果:

. TIMES_PURCHASED  ‘beijing’  ‘tianjin’  ‘shanghai’  ‘chongqing’

—————    ———- ———- ———-  ———-

              1      2           1          1          2    

              3      1           0          0          0    

              4      0           0          1          0

在11g之前的sql写法为:

SELECT t.times_purchased,

       SUM(decode(t.state_code,

                  ‘beijing’,

                  1,

                  ’0′)) AS beijing,

       SUM(decode(t.state_code,

                  ‘tianjin’,

                  1,

                  ’0′)) AS beijing,

       SUM(decode(t.state_code,

                  ‘shanghai’,

                  1,

                  ’0′)) AS beijing,

       SUM(decode(t.state_code,

                  ‘chongqing’,

                  1,

                  ’0′)) AS beijing

  FROM customer t

GROUP BY t.times_purchased

ORDER BY t.times_purchased;

在11g中,可以用如下sql:

SELECT *

  FROM (SELECT times_purchased,

               state_code

          FROM customer t) pivot(COUNT(state_code) FOR state_code IN(‘beijing’,

                                                                     ‘tianjin’,

                                                                     ‘shanghai’,

                                                                     ‘chongqing’))

ORDER BY times_purchased

pivot 的反向操作 UNPIVOT,将列打乱变为行。

Comments

>Oracle11g新特性_并行DBMS_PARALLEL_EXECUTE

>

我从Oracle 数据库 11g: 面向 DBA 和开发人员的重要新特性
http://www.oracle.com/technology/global/cn/pub/articles/oracle-database-11g-top-features/index.html
测试了一些个人觉得对日常工作有用的特性进行测试。
需要详细信息请猛击上方链接或者查阅相关文档。

2.并行DBMS_PARALLEL_EXECUTE

  这个新特性引入一个Package:DBMS_PARALLEL_EXECUTE,

  通过这个包可以将一个任务调度为并行,而此前我们需要手工来编写程序,

  通过rowid或者主键还分割,用11gR2,这个工作能简化很多。

  根据测试,oracle是提交job来实现并行,和咱们实现的方式一样。

  官方文档推荐这种做法用作大数据量的更新。

  create table TEMP_ZHJ_20101022 nologging as

    select * from user_objects;

  insert into temp_zhj_20101022 select * from user_objects;

  commit;

  DECLARE

    l_sql_stmt VARCHAR2(1000);

    l_try      NUMBER;

    l_status   NUMBER;

  BEGIN

    — Create the TASK

    dbms_parallel_execute.create_task(‘mytask’);

    — Chunk the table by ROWID

    dbms_parallel_execute.create_chunks_by_rowid(‘mytask’,

                                                 ‘SYS’,

                                                 ‘TEMP_ZHJ_20101022′,

                                                 TRUE,

                                                 100);

    — Execute the DML in parallel

    l_sql_stmt := ‘update /*+ ROWID (dda) */ TEMP_ZHJ_20101022 e

  SET e.EDITION_NAME = ”ORACLE11G”

  WHERE rowid BETWEEN :start_id AND :end_id’;

    dbms_parallel_execute.run_task(‘mytask’,

                                   l_sql_stmt,

                                   dbms_sql.native,

                                   parallel_level => 10);

    — If there is an error, RESUME it for at most 2 times.

    l_try    := 0;

    l_status := dbms_parallel_execute.task_status(‘mytask’);

    WHILE (l_try < 2 AND l_status != dbms_parallel_execute.finished)

    LOOP

      l_try := l_try + 1;

      dbms_parallel_execute.resume_task(‘mytask’);

      l_status := dbms_parallel_execute.task_status(‘mytask’);

    END LOOP;

    — Done with processing; drop the task

    dbms_parallel_execute.drop_task(‘mytask’);

  END;

Comments

>Oracle11g新特性_分区表

>

我从Oracle 数据库 11g: 面向 DBA 和开发人员的重要新特性

http://www.oracle.com/technology/global/cn/pub/articles/oracle-database-11g-top-features/index.html

测试了一些个人觉得对日常工作有用的特性进行测试。

需要详细信息请猛击上方链接或者查阅相关文档。

1.分区表

a.间隔分区表

  创建的时候指定一个基本分区和间隔,插入数据时会自动生成其他的分区;

  这个感觉比较有用,咱们有很多按照天进行分区的表,用这个功能的话可以减少分区的

  维护工作量;

create table sales6

(

   sales_id    number,

   sales_dt    date

)

partition by range (sales_dt)

interval (numtoyminterval(1,’MONTH’))

(

   partition p0701 values less than (to_date(’2007-02-01′,’yyyy-mm-dd’))

);

注意子句:interval 后面跟着时间间隔。您在此处指示 Oracle 为每个月份创建一个时间间隔。您已经为 2007 年 1 月的数据创建了名为 p0701 的初始分区。现在,假设您插入了一条包括 2007 年 6 月数据的记录:

SQL> insert into sales6 values (1,’01-jun-07′);

1 row created.

Oracle 不会返回错误,而是成功执行该语句。那么这条记录将转向何处?p0701 分区不能包括该记录,我们没有为 2007 年 6 月定义分区。但此时,如果您检查该表的分区:

SQL> select partition_name, high_value

  2  from user_tab_partitions

  3  where table_name = ‘SALES6′;

PARTITION_NAME  HIGH_VALUE

————— —————————————————————-

P0701           TO_DATE(‘ 2007-02-01 00:00:00′, ‘SYYYY-MM-DD HH24:MI:SS’, ‘NLS_C

                ALENDAR=GREGORIA

SYS_P41         TO_DATE(‘ 2007-07-01 00:00:00′, ‘SYYYY-MM-DD HH24:MI:SS’, ‘NLS_C

                ALENDAR=GREGORIA

注意名为 SYS_P1、高值为 2007 年 7 月 1 日的分区,它最多可以容纳到 6 月底的数据。该分区是由 Oracle 动态创建的,并具有一个系统生成的名称。

现在,假设您输入一个小于最高值的值,如 2007 年 5 月 1 日。理想情况下,它应该具有自己的分区,因为您的分区时间间隔是一个月。

b.REF分区

  这个分区方案假设关联表能从相同的分区策略中受益,子表通过

  PK-FK(主键-外键)关系继承主表的策略,它不需要分区键存储在子表中,

  通过PARTITION BY REFERENCE关键字指定,子表继承主表的分区策略。

c.混合分区

  可用的混合分区类型:

  范围-哈希,范围-列表,范围-范围,列表-范围,列表-列表,列表-哈希

d.系统分区

  系统在插入数据时,自动指定数据的分区

Comments

>河南周口发生4.8级地震

>

据中国地震台网测定,北京时间2010-10-24 16:58 在河南省周口市太康县、扶沟县、西华县交界(北纬34.0,东经114.6) 发生4.7级地震。

打电话回去,纷纷表示情绪稳定,没有感觉,不影响打牌打麻将~~

Comments

>merge over dblink含有sysdate时报错

>

日常经常会通过dblink进行数据库的远程merge,发现在类似
MERGE INTO table_a@adb.oracle.com a
USING table_b b
ON (a.id = b.id)
WHEN MATCHED THEN
   UPDATE
      SET a.cou = b.cou,
          a.dd  = sysdate
WHEN NOT MATCHED THEN
   INSERT
     (a.id,
      a.cou,
      a.dd)
   VALUES
     (b.id,
      b.cou,
      sysdate);
会出现
ORA-01008: not all variables bound
ORA-02063: preceding line from adb.oracle.com
经尝试,凡是出现sysdate就会报错,去掉就正常。
在这段代码前把sysdate赋予一个变量,在merge时使用变量即可。
问题解决。
数据库版本:10.2.0.4.0 – 64bit

Comments

>oracle相关书籍整理

>

http://www.amazon.cn/mn/detailApp/ref=sr_1_4?_encoding=UTF8&s=books&qid=1286874233&asin=B003NVLR3C&sr=1-4

Oracle Database 11g完全参考手册

http://www.amazon.cn/mn/detailApp/ref=sr_1_2?_encoding=UTF8&s=books&qid=1286878864&asin=B001P81JKG&sr=8-2

Oracle Database 11g DBA手册 (平装)

http://www.amazon.cn/mn/detailApp/ref=sr_1_2?_encoding=UTF8&s=books&qid=1286874233&asin=B001LNP23K&sr=1-2

Oracle Database 11g SQL开发指南 (平装)

http://www.amazon.cn/mn/detailApp/ref=sr_1_1?_encoding=UTF8&s=books&qid=1286877225&asin=B0027A9O4E&sr=1-1

OracleDatabase11gPL/SQL程序设计 (平装)

以上四本都是oracle出版社的,不知道翻译的咋样。

英文原版可以在amazon.com上根据原作者姓名查询到,可以在线看一部分内容。

http://www.amazon.cn/mn/detailApp/ref=sr_1_2?_encoding=UTF8&s=books&qid=1286878757&asin=B0016LWC9O&sr=1-2

Oracle Database 10g RMAN备份与恢复 (平装)

http://www.amazon.cn/mn/detailApp/ref=sr_1_10?_encoding=UTF8&s=books&qid=1286879192&asin=B001O9AMKE&sr=1-10

Oracle Database 10g 性能调整与优化 (平装)

Oracle OCP官方培训教材和oracle自己的相关文档,要是找个地方打印装订下也不错。

Comments

>The Optimal Flexible Architecture (OFA) standard

>OFA总体结构分两层,一层是software-oracle software,一层是Files(database)
software目录结构
oracle_base/————————————–起名oracle最多
/product————————————很多安装省略
/release_number——————–这个一般作为Oracle_home
/bin
/dbs——————————–9i spfile默认位置,8i一般同时链接到/admin/pfile
/rdbms
/sqlplus
/admin
/inst_name—————–不同的实例这个目录可以多个
/pfile
/dump….

Files目录结构
oradata/
db01/————————————database db01
system01.dbf
confrol01.ctl
redo0101.log
db02/————————————database db02

OFA只是oracle公司推荐的一种在服务器上安装oracle数据库系统的目录规划,以便于做维护。要点就是,整个数据库系统可以分为软件产品、每个实例的管理配置文件、数据库文件三部分,分别放在不同的目录下。

OFA的方法包括以下三条原则:
一:创建一个有续的操作系统目录结构,在此目录下存储文件可以存储在任何一个磁盘里.
命名可能存放oracle的所有设备,在以设备为单位来指定设备的时候可以用同配符或者类似的方法.
在每个设备的同一级目录下明确的创建一个用于存储oracle数据的目录.
二:根据不同的用途和特征,把段(数据对象)分成组分三到不同的表空间中.
根据碎块特征,把不同组的数据对象分散到不同表空间中(例如,不要将数据段和回滚段放在一起).
根据对磁盘资源的竞争使用状态,把不同组的段分散到不同的表空间中(例如,不要把数据和索引放在一起).
根据所代表对象的不同行为特征,把不同组的段分散到不同的表空间中 (例如,不要把需要每日备份一次的表和需要每年备份依次的表放在同一个表空间中).
三 把数据库足见分散到不同的磁盘空间中,使数据库的可靠性和运行效率最大化.注意在RAID环境下不要考虑把数据文件分散到在多个控制器组中.
数据库控制文件至少要在三个不容物理磁盘阵列中分别有三个可用的副本.
把那些存储了抢夺磁盘资源的数据的表空间分散在不同的物理磁盘上(还应该考虑到磁盘控制器的使用情况).

Comments