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