Oracle 体系架构

ORACLE数据库的组成:数据库服务器+数据库软件+数据库实例+数据库文件

数据服务器:PC SERVER 或AIX/HP UNIX 等真实的硬件设备。
数据库软件:安装在$ORACLE_HOME 下的一堆文件。

数据库实例:内存结构+进程结构
    内存结构:SGA+PGA
    进程结构:前台进程(server process)+ 后台进程(smon、pmon、dbwr、lgwr、ckpt等)

数据库文件(存储结构):参数文件+控制文件+数据文件+日志文件+归档文件+备份文件+密码文件


oracle 体系结构:重点记住:三大内存池(shared pool/buffer cache/log buffer),五大后台进程(pmon/smon/dbwr/lgwr/ckpt)
show parameter sga
show parameter pga

什么是oracle数据库软件,oracle数据库实例、oracle数据库

查看后台进程 查看后台进程

 select * from v$bgprocess where paddr !='00'

Buffer Cache:是SGA的一部分,Oracle利用Buffer Cache来管理data block,Buffer Cache的最终目的就是尽可能的减少磁盘I/O。Buffer Cache中主要有3大结构用来管理Buffer Cache。

Hash Bucket & Hash Chain List :Hash Bucket与Hash Chain List用来实现data block的快速定位。

LRU List :挂载有指向具体的free buffer, pinned buffer以及还没有被移动到 write list的dirty buffer 等信息。所谓的free buffer就是指没有包含任何数据的buffer,所谓的pinned buffer,就是指当前正在被访问的buffer。

Write(Dirty)List :挂载有指向具体的 dirty block的信息。所谓的dirty block,就是指在 buffer cache中被修改过但是还没有被写入到磁盘的block。

以Oracle块为单位做读写,比如此数据库以8k为一个块,则读写到database  buffer cache中;
 

show parameter db_block_size 

 database buffer chache内存空间管理原则:LRU算法(最近最少使用),即解决如何释放内存的问题;

SQL> select * from v$sgainfo where name='Granule Size';

每个buffer在x$BH中都存在一条记录。
X$BH中有一个重要字段TCH   ,TCH为touch的缩写,表示一个buffer的访问次数,buffer被访问的次数越多,说明该buffer越抢手,也就是可能存在热点块竞争的问题。

查询当前数据库最繁忙的buffer

Select * From (select addr,ts#,file#,dbarfil,dbablk,tch From x$bh Order by tch desc) Where rownum<11;

结合dba_extents中的信息,可以查询到这些热点buffer都来自那些对象。

Select e.owner,e.segment_name,e.segment_type From dba_extents e,
(Select * From (select addr,ts#,file#,dbarfil,dbablk,tch From x$bh Order by tch desc) Where rownum<11)b
Where  e.relative_fno=b.dbarfil
       And e.block_id<=b.dbablk
       And e.block_id+e.blocks>dbablk;

Shared pool描述:

Shared pool 用来存放共享的SQL和PL/SQL。主要作用是在session 间对 cache 的游标进行共享。
shared pool 主要是用来 cache metadata 的,而 buffer cache 主要是用来 cache 数据的。 

1、了解什么是硬解析和软件析

当客户端进程,将SQL语句通过监听器发送到Oracle时, 会触发一个Server process生成,来对该客户进程服务。Server process得到SQL语句之后,对SQL语句进行Hash运算,然后根据Hash值到library cache中查找,如果存在,则直接将library cache中的缓存的执行计划拿来执行,最后将执行结果返回该客户端,这种SQL解析叫做软解析;如果不存在,则会对该SQL进行解析parse,然后执行,返回结果,这种SQL解析叫做硬解析。

硬解析的步骤:
 
1)对SQL语句进行语法检查,看是否有语法错误;
2)通过数据字典(row cache),检查SQL语句中涉及的对象和列是否存在。
3)检查SQL语句的用户是否对涉及的对象是否有权限。
4)通过优化器创建一个最优的执行计划。这个过程会根据数据字典中的对象的统计信息,来计算多个执行计划的cost,从而得到一个最优的执行计划。这一步涉及到大量的数据运算,从而会消耗大量的CPU资源;(library cache最主要的目的就是通过软解析来减少这个步骤);
5)将该游标所产生的执行计划,SQL文本缓存到library cache中的heap中。

软解析:
所谓软解析,就是因为相同文本的SQL语句存在于library cache中,所以本次SQL语句的解析就可以去掉硬解析中的一个活多个步骤。从而节省大量的资源的耗费。

软软解析:
所谓的软软解析,就是不解析。当设置了session_cached_cursors参数时,当某个session第三次执行相同的SQL语句时,则会把该SQL语句的游标信息转移到该session的PGA中。这样,当该session在执行该SQL语句时,会直接从PGA中取出执行计划,从而跳过硬解析的所有步骤。


关于使用绑定变量的举例:

SQL> var id number

SQL> select * from t2 where employee_id=:id;

no rows selected

col sql_text for a50

SQL> select sql_text,child_number,executions ,buffer_gets from v$sql where sql_text like 'select * from t2 where employee_id%';

SQL_TEXT                                           CHILD_NUMBER EXECUTIONS BUFFER_GETS
-------------------------------------------------- ------------ ---------- -----------
select * from t2 where employee_id=:id                        0          1          46

**********************************************************************************************************************************
SQL> exec :id:=101

PL/SQL procedure successfully completed.
SQL> select * from t2 where employee_id=:id;

SQL> select sql_text,child_number,executions ,buffer_gets from v$sql where sql_text like 'select * from t2 where employee_id%';

SQL_TEXT                                           CHILD_NUMBER EXECUTIONS BUFFER_GETS
-------------------------------------------------- ------------ ---------- -----------
select * from t2 where employee_id=:id                        0          2          51

**********************************************************************************************************************************
SQL> exec :id:=200

PL/SQL procedure successfully completed.

SQL>  select * from t2 where employee_id=:id;

SQL> select sql_text,child_number,executions ,buffer_gets from v$sql where sql_text like 'select * from t2 where employee_id%';

SQL_TEXT                                           CHILD_NUMBER EXECUTIONS BUFFER_GETS
-------------------------------------------------- ------------ ---------- -----------
select * from t2 where employee_id=:id                        0          3          56

**********************************************************************************************************************************
SQL> select * from t2 where employee_id=202;

SQL> select sql_text,child_number,executions ,buffer_gets from v$sql where sql_text like 'select * from t2 where employee_id%';

SQL_TEXT                                           CHILD_NUMBER EXECUTIONS BUFFER_GETS
-------------------------------------------------- ------------ ---------- -----------
select * from t2 where employee_id=:id                        0          3          61
select * from t2 where employee_id=202                        0          1          10

*************************************************************************************************************************************

共享池:heap(堆)------>extent------>chunk

--x$ksmsp 记录共享池堆所有的chunk,有多少行证明有多少chunk,KSMCHSIZ列是每个chunk的大小

select count(*) ,round(sum(ksmchsiz)/1024/1024,0) total_size_mb,round(avg(ksmchsiz),0) avg_size from x$ksmsp;

 COUNT(*) TOTAL_SIZE_MB   AVG_SIZE
---------- ------------- ----------
     39855           168       4420

--此视图有一个KSMCHCLS列,专门用于记录chunk的类型:

select ksmchcls,count(*),round(sum(ksmchsiz)/1024/1024,0) total_size_mb,round(avg(ksmchsiz),0) avg_size from x$ksmsp group by ksmchcls order by ksmchcls;

KSMCHCLS   COUNT(*) TOTAL_SIZE_MB   AVG_SIZE
-------- ---------- ------------- ----------
R-free           42            10     247750
R-freea          84             0         24
R-perm            5            18    3689303
R-recr            1             4    3977156
free            232             9      39750
freeabl       16356            45       2909
perm             25            46    1910733
recr          23124            37       1676

free:空闲的chunk,可以直接被覆盖,在freelist中
perm:永久型的chunk,和free对应,不会被释放,是oracle内部一些视图的内存结构。
recr:即recreateable,可重建的chunk,在LRU中
freeable:可空闲、可释放、可覆盖的chunk。是子堆中和recr类型chunk相关连的一部分chunk,只是没有被放在LRU链表中。

 ORA-4031的错误
重演:

SQL> show parameter open_cur

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
open_cursors                         integer     300
SQL> alter system set open_cursors=60000; 
SQL> alter system set shared_pool_size=10m;

declare
msql varchar2(500);
mcur number;
mstat varchar2(5000);
begin
for i in 1..90000 loop
mcur:=dbms_sql.open_cursor;
msql:='select object_name from dba_objects where object_id='||to_char(i);
dbms_sql.parse(mcur,msql,dbms_sql.native);
mstat:=dbms_sql.execute(mcur);
end loop;
end;
/

ORA-04031: unable to allocate 132 bytes of shared memory ("shared pool","select /*+ rule */ bucket_cn...","SQLA^337fc737","kccdef: qkxrMemAlloc")
Incident details in: /u01/app/oracle/diag/rdbms/prod4/PROD4/incident/incdir_8593/PROD4_cjq0_2324_i8593.trc
Errors in file /u01/app/oracle/diag/rdbms/prod4/PROD4/trace/PROD4_cjq0_2324.trc:
ORA-00604: error occurred at recursive SQL level 3
ORA-04031: unable to allocate 132 bytes of shared memory ("shared pool","select /*+ rule */ bucket_cn...","SQLA^337fc737","kccdef: qkxrMemAlloc")
Tue Nov 17 15:50:29 2015
Trace dumping is performing id=[cdmp_20151117155029]

select ksmchcls,count(*),round(sum(ksmchsiz)/1024/1024,0) total_size_mb,round(avg(ksmchsiz),0) avg_size from x$ksmsp
group by ksmchcls order by ksmchcls;

SQL> alter system flush shared_pool;

三种原因:
1、共享池内存过小
2、共享池中对象太多
3、共享池碎片太多

判断内存过小:

select 1/20- kghlufsh/kghluops from x$kghlu; 

kghlufsh 是进程flash共享池的次数,主要是合并相邻的chunk,一般内存紧张时才这样做。KGHLUOPS 列代表进程操作chunk的次数。flush的次数和操作chunk的次数比小于1:20,说明共享池太小了,也就说操作20次chunk就要合并一次相邻的chunk,证明内存不够用了。

判断共享池对象太多:

select kglhdnsd,kglobtyd,count(*),sum(kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16)/1024 from x$kglob group by kglhdnsd,kglobtyd;

判断碎片:比较难判断

select ksmchsiz,count(*) from x$ksmsp where ksmchcls='free' and ksmchsiz<=150 group by ksmchsiz order by ksmchsiz;

select KSMCHIDX "SubPool", 'sga heap('||KSMCHIDX||',0)'sga_heap,ksmchcom ChunkComment,
     decode(round(ksmchsiz/1000),0,'0-1K', 1,'1-2K', 2,'2-3K',3,'3-4K',
     4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,
     '8-9k', 9,'9-10k','> 10K') "size",
     count(*),ksmchcls Status, sum(ksmchsiz) Bytes
     from x$ksmsp
     where KSMCHCOM = 'free memory'
     group by ksmchidx, ksmchcls,
     'sga heap('||KSMCHIDX||',0)',ksmchcom, ksmchcls,decode(round(ksmchsiz/1000),0,'0-1K',
     1,'1-2K', 2,'2-3K', 3,'3-4K',4,'4-5K',5,'5-6k',6,
    '6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K');

pmon:监控进程

作用:
a)    监控其他非核心后台进程,如果其他非核心后台进程意外终止,则由它重启;
b)    清理意外终止的死链接在后天残留的垃圾:将其修改的数据回退,释放锁;
c)    pmon动态注册实例的信息到监听程序;

smon:系统监控:

作用:
a)系统监控管理,定期合并空闲,回收临时段;
b)做实例的恢复:前滚、回滚、释放资源

***commit只是将日志log 写盘,与脏数据是否写盘无关!!

dbwn:数据写
定义:将脏数据写盘,(n的取值:0-9,a-j,一共可以并行20个)
问题:什么时候触发dbwn进程?

以下9种情况触发机制:
1) check pointer:有检查点
2) 脏数据达到阀值%25%
3) 扫描整个database buffer cache没有空闲:
4) time off:每三秒调度一次数据写;
5) 在集群环境中的ping请求:将所有结点的脏数据写磁盘,使数据状态一致,协同工作的
6) 删除表、截断表:drop table、trucate table;
7) tablespace read only:表空间只读触发
8) tablespace offline:表空间脱机触发数据写;
9) begin backup:热备份命令触发数据写;

lgwr日志写

定义:日志写进程(日志写比数据写更重要)

触发lgwr的几种情况:
1)    提交命令:commit;
2)    log buffer达到内存的1/3,即达到阀值;
3)    time of:3秒一次;
4)    任何一次数据写之前都必须做lgwr;
5)      log buffer 达到1M;

REDO LOG 切换的时间应该尽可能的不低于10-20 分钟。

select to_char(FIRST_TIME,'yyyy-mm-dd hh24:mi:ss') f_time,SEQUENCE# from v$log_history;

CKPT
检查点进程:检查点的主要任务就是催促DBWn刷新脏块
1)    调度数据写;
2)    会将已经完成的检查点写到数据文件头;
3)    把已经完成的检查点写到控制文件;

select name,to_char(checkpoint_change#),to_char(last_change#) from v$datafile;
数据库的存储结构:

1、查询spfile文件
show parameter spfile

2、查询controlfile 

select name from v$controlfile; 或 show parameter controlfile

3、数据文件的位置:
select file#,name from v$datafile; 或 select file_id,file_name from dba_data_files;

4、临时表空间数据文件的位置:
select file#,name from v$tempfile;  或 select file_id,file_name from dba_temp_files;

5、redo联机日志的位置

日志组及成员个数:
SQL> select group#,bytes,members,status from v$log;

    GROUP#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ----------------
         1   52428800          1 INACTIVE
         2   52428800          1 INACTIVE
         3   52428800          1 CURRENT
日志文件位置:
SQL> select group#,member,status from v$logfile;

实例管理:

oracle 10g alert日志位置:/u01/app/oracle/admin/orcl/bdump/alter_SID.log
ADR 主目录的位置由以下路径给定,该路径以 ADR 基目录开头:./diag/product_type/db_id/instance_id
oracle 11g alert日志位置:/u01/app/oracle/diag/rdbms/prod4/PROD4/trace/altert_SID.log

我们常用的v$ 是v_$的同义词,v_$是基于真正的视图v$,而真正的v$视图是在gv$的基础上限制inst_id得到;
我们常用的gv$是gv_$的同义词,gv_$基于真正的视图gv$,而真正的gv$视图基于系统表X$。

通过查询 V$FIXED_TABLE 查看所有视图名称。

所有数据字典表的查询:

select table_name from dict where table_name like '%关键字%';

 

你可能感兴趣的:(Oracle,数据库,oracle)