ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Oracle 体系架构

2020-03-09 16:39:20  阅读:148  来源: 互联网

标签:体系 架构 buffer sql SQL Oracle where id select


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 '%关键字%';

 

标签:体系,架构,buffer,sql,SQL,Oracle,where,id,select
来源: https://blog.csdn.net/qq_15993903/article/details/104753587

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有