>转一份oracle资料
>
我们从一个用户请求开始讲,ORACLE的完整的工作机制是怎样的,首先一个用户进程发出一个连接请求,如果使用的是主机命名或者是本地服务命中的主机名使用的是机器名(非IP地址),那么这个请求都会通过DNS服务器或HOST文件的服务名解析然后传送到ORACLE监听进程,监听进程接收到用户请求后会采取两种方式来处理这个用户请求,下面我们分专用服务器和共享服务器分别采用这两种方式时的情况来讲:
专用服务器模式下:一种方式是监听进程接收到用户进程请求后,产生一个新的专用服务器进程,并且将对用户进程的所有控制信息传给此服务器进程,也就是说新建的服务器进程继承了监听进程的信息,然后服务器进程给用户进程发一个RESEND包,通知用户进程可以开始给它发信息了,用户进程给这个新建的服务器进程发一个CONNECT包,服务器进程再以ACCEPT包回应用户进程,致此,用户进程正式与服务器进程确定连接。我们把这种连接叫做HAND-OFF连接,也叫转换连接。另一种方式是监听进程接收到用户进程的请求后产生一个新的专用服务器进程,这个服务器进程选用一个TCP/IP端口来控制与用户进程的交互,然后将此信息回传给监听进程,监听进程再将此信息传给用户进程,用户进程使用这个端口给服务器进程发送一个CONNECT包,服务器进程再给用户进程发送一个ACCEPT包,致此,用户进程可以正式向服务器进程发送信息了。这种方式我们叫做重定向连接。HAND-OFF连接需要系统平台具有进程继承的能力,为了使WINDOWS NT/2000支持HAND-OFF必须在HKEY_LOCAL_MACHINE>SOFTWARE>ORACLE>HOMEX中设置USE_SHARED_SOCKET。
共享服务器模式下:只有重定向连接的方式,工作方式是监听进程接收到用户进程的请求后产生一个新的调度进程,这个调度进程选用一个TCP/IP端口来控制与用户进程的交互,然后将此信息回传给监听进程,监听进程再将此信息传给用户进程,用户进程使用这个端口给调度进程发送一个CONNECT包,调度进程再给用户进程发送一个ACCEPT包,致此,用户进程可以正式向调度进程发送信息了。可以通过设置MAX_DISPIATCHERS这个参数来确定调度进程的最大数目,如果调度进程的个数已经达到了最大,或者已有的调度进程不是满负荷,监听进程将不再创建新的调度进程,而是让其中一个调度进程选用一个TCP/IP端口来与此用户进程交互。调度进程每接收一个用户进程请求都会在监听进程处作一个登记,以便监听进程能够均衡每个调度进程的负荷,所有的用户进程请求将分别在有限的调度进程中排队,所有调度进程再顺序的把各自队列中的部分用户进程请求放入同一个请求队列,等候多个ORACLE的共享服务器进程进行处理(可以通过SHARED_SERVERS参数设置共享服务器进程的个数),也就是说所有的调度进程共享同一个请求队列,共享服务器模式下一个实例只有一个请求队列,共享服务器进程处理完用户进程的请求后将根据用户进程请求取自不同的调度进程将返回结果放入不同的响应队列,也就是说有多少调度进程就有多少响应队列,然后各个调度进程从各自的响应队列中将结果取出再返回给用户进程。
以上我们讲完了用户与ORACLE的连接方式,下面我们要讲ORACLE服务器进程如可处理用户进程的请求,当一个用户进程发出了一条SQL语名:UPDATE TABBLEA SET SALARY=SALARY*2;首先,服务器进程把这条语句的字符转换成ASCII等效数字码,接着这个ASCII码被传递给一个HASH函数,并返回一个HASH值,服务器进程将到SHARED POOL 的共享PL/SQL区去查找是否存在同样的HASH值,如果存在,服务器进程将使用这条语句已高速缓存在SHARED POOL中的已分析过的版本来执行,如果不存在,服务器进程将对该语句进行语法分析,首先检查该语句的语法的正确性,接着对语句中涉及的表、索引、视图等对象进行解析,并对照数据字典检查这些对象的名称以及相关结构,并根据ORACLE选用的优化模式以及数据字典中是否存在相应对象的统计数据和是否使用了存储大纲来生成一个执行计划或从存储大纲中选用一个执行计划,然后再用数据字典核对此用户对相应对象的执行权限,最后生成一个编译代码。ORACLE将这条语名的本身实际文本、HASH值、编译代码、与此语名相关联的任何统计数据和该语句的执行计划缓存在SHARED POOL的共享PL/SQL区。服务器进程通过SHARED POOL 锁存器来申请可以向哪些共享PL/SQL区中缓存这此内容,也就是说被SHARED POOL锁存器锁定的PL/SQL区中的块不可被覆盖,因为这些块可能被其它进程所使用。在SQL分析阶段将用到LIBRARY CACHE,从数据字典中核对表、视图等结构的时候,需要将数据字典从磁盘读入LIBRARY CACHE,因此,在读入之前也要使用LIBRARY CACHE锁存器来申请用于缓存数据字典。
生成编译代码之后,接着下一步服务器进程要准备开始更新数据,服务器进程将到DB BUFFER中查找是否有相关对象的缓存数据,下面分两个可能进行解释:
如果没有,服务器进程将在表头部请求一些行锁,如果成功加锁,服务器进程将从数据文件中读这些行所在的数据块放入DB BUFFER中空闲的区域或者覆盖已被挤出LRU列表的非脏数据块缓冲区,并且排列在LRU列表的头部,如果这些非脏数据缓冲区写完也不能满足新数据的请求时,会立即触发DBWN进程将脏数据列表中指向的缓冲块写入数据文件,并且清洗掉这些缓冲区,来腾出空间缓冲新读入的数据,也就是在放入DB BUFFER之前也是要先申请DB BUFFER中的锁存器,成功锁定后,再写入DB BUFFER,然后服务器程将该语句影响的被读入DB BUFFER块中的这些行的ROWID及将要更新的原值和新值及SCN等信息逐条的写入REDO LOG BUFFER,在写入REDO LOG BUFFER之前也是先请求REDO LOG BUFFER块的锁存器,成功锁定之后才开始写入,当写入达到REDO LOG BUFFER大小的三分之一或写入量达到1M或超过三秒后或发生检查点时或者DBWN之前发生,LGWR将把REDO LOG BUFFER中的数据写入磁盘上的重做日志文件,已被写入重做日志文件的REDO LOG BUFFER中的块上的锁存器被释放,并可被后来写入的信息所覆盖,REDO LOG BUFFER以循环的方式工作。当一个重做日志文件写满后,LGWR将切换到下一个重做日志文件,如果是归档模式,归档进程还将前一个写满的重做日志进程写入归档日志文件,重做日志文件也是循环工作方式。写完所有的REDO LOG BUFFER之后,服务器进程开始改写这个DB BUFFER块头部的事务列表并写入SCN,然后COPY包含这个块的头部事务列表及SCN信息的数据副本放入回滚段中,我们将回滚段中的副本称为数据块的“前映像”。(回滚段可以存储在专门的回滚表空间中,这个表空间由一个或多个物理文件组成,并专用于回滚表空间,回滚段也可在其它表空间中的数据文件中开辟。)然后改写这个DB BUFFER块的数据,并在其头部写入对应的回滚段地址,如果对一行数据多次UPDATE而不COMMIT则在回滚段中将会有多个“前映像”,除第一个“前映像”含有SCN信息外,其它的每个“前映像”的头部还含有SCN信息和“前前映像”的回滚段地址。一次UPDATE操作只对应一个SCN。然后服务器进程在脏数据列表中建立一条指向此缓冲块的指针。接着服务器进程会从数据文件读入第二个块重复以上读
>Oracle字符集差异导致的问题
>
两个Oracle数据库通过dblink导数据,实用create table ttttt as select * from ttttt@a.oracle.com,发现char(1)在新创建的表中变成了char(3),还好发现的及时,没有导致大的错误。
把char(3)改成varchar2(3),然后批量更新数据。
经检查是字符集导致的问题,字符类型的(char和varchar2)在utf8的数据库上会自动变成gbk的3倍。
教训:不同数据库间导数据需要特别注意字符集差异。
最重要的是,应用应该尽量避免实用char这个数据类型。
>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);
>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,将列打乱变为行。
>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;
>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.系统分区
系统在插入数据时,自动指定数据的分区
>河南周口发生4.8级地震
>
据中国地震台网测定,北京时间2010-10-24 16:58 在河南省周口市太康县、扶沟县、西华县交界(北纬34.0,东经114.6) 发生4.7级地震。
打电话回去,纷纷表示情绪稳定,没有感觉,不影响打牌打麻将~~
>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
>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自己的相关文档,要是找个地方打印装订下也不错。