您的位置:首页 > 数据库 > Oracle

Oracle物理的体系结构

2015-04-06 14:07 323 查看
体系结构图的学习:

老余服装店的故事
结构图: SQL查询语句 SGA 共享池shared pool
数据缓存区Buffer cache

PGA
进程

SQL更新语句 SGA: 日志缓存区

日志文件

深入学习 提交
回滚
一致读

实践体会:

内存
进程
启停
文件
监听
学习意义:

体系结构图:





说明:

oracle由实例和数据库组成
实例由:专门开辟出来的一块SGA内存区域和一些列后台进程组成,其中SGA主要被划分为共享池(shared pool),数据缓存区(db cache),日志缓存区(log buffer)这三个部分。另外加上oracle的一些进程:DBWn,LGWR,ARCH,CKPT这些有和硬盘打交道。其它进程还有:PMON,SMON,LCKn,RECO.
数据库的文件组成: 数据本身: 数据文件:
日志文件: 联机日志文件:必须多路复用(group-Nmember);循环写
归档日志文件:归档日志文件会被移动到磁盘或磁带,用于备份和恢复。

启动实例: 参数文件:
控制文件:

PGA也是开辟出来的一块内存区,和SGA的差别是,PGA私有不共享。用户连进来是的第一关就是PGA:
连入数据库时
保存用户的连接信息:如会话属性,绑定变量等。
保存用户的权限,当用户建立会话时,系统会去数据字典查询用户的权限信息,并保存在PGA中。
取回数据时
如果取回的数据需要排序,那么排序的活动在PGA内完成,如果PGA不够,那么使用临时表空间(尽量不使用临时表空间,因为会大量增大磁盘IO,降低性能。)。
上图分为3个区域,内存里面主要是1区PGA,2区SGA,硬盘为3区。一般的数据库操作是1-2-3或者仅仅是1-2.
老余的故事:

顾客的尺寸—soft parse
有效的调整—buffer cache
记录的习惯—目的是提高性能,批量的刷数据,而不是提交一笔刷一笔。
一条查询语句的历险:

sqlplus建立一个会话,执行查询select id from t where obejct_id=29;这个时候先完成PGA的3步骤中的头2步:保存会话信息,用户权限信息,然后将sql语句hash出一条hash值。
带着hash值,sql进入了第二个区域:共享池,在这里首先查找是否有同样的hash值。如果没有,那么就比较辛苦:首先查询语法是否正确,然后查询语义(表和字段有没有写错)是否正确,是否有权限等,确认完这些,将hash值存储下来。接下来进行硬解析,经过优化器分析以后Oracle会选择一个低成本的执行计划。
带着自信计划的sql接下来进入第三个区域:数据缓存区,去获得需要的数据,如果查到该数据,则返回给sql带回到PGA。如果没有,就要大费周章地去磁盘(增大IO降低速度)里面查找。查找的方式就是按照执行计划来。读出来的数据会被放回数据缓存区和PGA
sqlplus xxx/xxx
drop table t;
create table t as select * from all_objects;
create index idx_objid on t(object_id);
set autotrace on;
set linesize 100;
set timing on;
select object_name from t where object_id=29;






前后两次执行同一条语句:第二次比第一次少很多时间。原因是第二次少做了一些事情:

因为会话没有断开,所以不需要再去数据库读取权限和用户信息,少了很多物理读。

因为是第二次执行同一条语句,所以SGA的共享池里已经保存了相对应的hash值,比照一样之后,不需要做语法语义的验证,也不需要做硬解析获得优化的执行计划,只要把已经解析好的执行计划拿来用就好。

数据被取到SGA的数据缓存区里面,也不需要去硬盘读。

可以用/*+full(t)*/强制sql走全表扫描。

一条更新语句的历险:

如果用户还是没有退出session,那么PGA部分保存的内容不需要再做一遍。还是会将sql语句hash出一条hash值。

带着hash值,sql进入了第二个区域:共享池。照旧:首先查询语法是否正确,然后查询语义(表和字段有没有写错)是否正确,是否有权限等,确认完这些,将hash值存储下来。接下来进行硬解析,经过优化器分析以后Oracle会选择一个低成本的执行计划。

带着自信计划的sql接下来进入第三个区域:数据缓存区。去磁盘里面按照执行计划来查找,读出来的数据会被放回数据缓存区。

sql执行update改变缓存区中数据的值。

这个改变动作导致内存中的数据块变脏。DBWn专门负责将脏数据写入磁盘。

这个改变动作被oracle记录到日志缓存区,有LGWR快速写入联机日志文件。

如果联机日志文件写满,切换日志时会把写满的联机日志文件用ARCH写入归档日志文件。这里面有个速度问题,如果有个联机日志ARCH进程没有完全归档完,就有LGWR要来写,说明联机日志文件太小或者文件个数太少。

提交:只有用户commit,这条更新语句才会在数据库生效,如果用户放弃,则用rollback。

日志文件和数据文件的关系:日志存在的目的在系统崩溃后重启时,把在日志中记载的,但是没刷到数据文件的操作重新做一遍。所以如果平时DBWn不勤快的刷数据,数据库的性能越好,但是同时的日志里面没刷的内容相应的也越多,断电恢复需要的时间也越长。可是如果平时DBWn很勤快,那么固然恢复的时间段了,却会影响到数据库的性能。控制这个平衡的就是CKPT。

什么时候数据由数据缓存区写入到磁盘,这是由CKPT来控制的(傻把式DBWn是听CKPT来指挥的),另外如果LGWR出了故障,那么DBWn会被拦住,因为DBWn必须等LGWR把操作记录到日志以后才能写相应的数据到磁盘,这就是“凡事有记录”。

劳模评选:LGWR

PMON:这个是进程监视进程,如果你的sql更新语句进程崩溃,PMON自动帮你rollback,其它进程如RECO等崩溃,PMON帮助重启进程,遇到LGWR崩溃,PMON为终止整个实例,以避免数据产生不一致现象。

SMON:系统监视进程,与PMON不同,SMON关注的是系统级别的操作,而非单个进程。重点工作在于实例恢复,同时还有清理临时表空间和回滚段表空间,合并空闲空间等。

LCKn:仅仅用于RAC,用于实例间的封锁,n从1到10.

RECO:用于分布式的恢复: 比如有A,B,C三个分布式数据库,一个应用横跨这3个数据库,一个提交一定在3个库全部提交成功才成功,否则回滚。

CKPT:通过FAST_START_MTTR_TARGET(eg. 300秒)的设定来控制DBWn写入的频繁程度,参数越短,恢复时间越短,写入越频繁,性能越差。

DBWn:系统最核心的进程,负责将数据写入磁盘,受CKPT指挥,和LGWR密切相关。

LGWR:也是系统最核心的进程,负责把日志缓存的日志写到磁盘的日志文件中。日志文件必须是按顺序记录,中间错了任何一条,其后的所有日志就报废了。所以多路复用非常关键。另外因为日志必须按顺序记录,所以LGWR无法采用多进程,只能采用单一进程,否则次序错乱了。 在这样的情况下,为了保证LGWR及时有效的写入日志文件,LGWR自己给自己加压,定了5条规矩,通过这些规矩从不同侧面保证日志文件的可靠性,:

每个3秒跑一次,将这3秒内的日志写入磁盘。

任何Commit触发LGWR运行一次,将commit的内容写入磁盘。

DBWn要把数据从缓存写到磁盘前,触发LGWR运行一次,把相关内容写入磁盘。

日志缓存区满1/3,或者日志满1m,触发LGWR运行一次,把1/3的内容,或者1m的内容写入磁盘。

联机日志文件切换,触发LGWR运行一次,将切换前的日志写入磁盘。

ARCH:日志切换是会触发ARCH进程,另外日志在被覆盖之前如果没有归档,会触发ARCH归档完毕以后再覆盖。

回滚段:更新语句时,旧数据会被写入回滚段。

首先找到要更新的记录,读入到数据缓存区(和查询一样)。

在回滚段表空间分配空间,在数据缓存区中创建该记录的镜像,通过DBWn将镜像写入回滚段表空间,并且用日志记录下这个动作。

在2做好的前提下,然后对有镜像的原记录进行修改,并且将这个修改的动作写入日志。

此时,如果用户提交,那么LGWR要立即写入这个提交信息。并且,将回滚段的事务表上的该事务标记为非活跃状态,表示允许重写。

如果进行了回滚,则oracle要从回滚段中读取镜像记录,还原被修改的记录。这个过程也会被日志记录起来。

UNDO_MANAGEMENT=AUTO:自动管理回滚段

UNDO_RETENTION=900:commit后900秒才能覆盖回滚段的内容.

增删改对于回滚段的压力大小问题:

insert压力最小.只记录rowid,回滚的时候只要定位到行删除即可.delete压力最大,需要重新插入回来整行.

对于日志文件则反之.

读一致性:查询的规则,如果你是9:00开始查询的,那么数据库应该返回9:00时的数据库的值给你,而不是9:01的.这个叫读一致性.

SCN全称系统改变号码,存在于数据库的最小单位块中.每一个块的改变都会引起SCN的递增.

数据库的回滚段记录事务槽,这个是用来分配回滚段空间的.如果你更新某块,事务就被写进槽里,若未提交或者未回滚,则该槽就是活跃的.数据库读到这一块可以识别这种情况.

查询的时候,如果scn号比发起的scn号小,则看是否是活跃事务,如果是活跃事务,去回滚段读数据.如果scn号比发起的scn号大,那么也去回滚段读数据.

Oracle宁可返回错误,也不能返回不一致读.如果回滚段的镜像由于反复修改被覆盖了,oracle会返回ORA-01555错误.

块头的ITL槽记录scn号,活动的话,可以找到对应的undo表空间.

实践:

内存的体会:SGA/PGA:

sqlplus / as sysdba
show parameter sga
show parameter pga
show parameter shared_pool_size
show parameter db_cache_size


show parameter log_buffer


ipcs –m 在操作系统查看共享内存。


现在SGA一般为自动管理,只需设一些总体参数即可:SGA_MAXSIZE=8G,SGA_TARGET=2G, 指正常情况分配2G给oracle,如果不够再增加,最大不超过8G。另外11g以后多了memory_max_target,memory_target.如果设置了这个,就不用设SGA和PGA了。如果要手动设置SGA,就把SGA_TARGET=0,然后设置shared_pool_size, db_cache_size为非0即可。

log_buffer是不能自动分配的。必须手动,一般15m就够了。由于每1/3写一次,每满1m写一次,所以分配太大优化也不是太明显。

修改语法:ALTER SYSTEM SET <parametername>=<value> SCOPE={MEMORY|SPFILE|BOTH}.

如果实例使用pfile启动,则scope的默认值是memory,如果是spfile启动,默认值是both。

有些参数必须重启才能生效,如log_buffer,sga_max_size等。会报错:ORA-02095: specified initialization parameter cannot be modified。

如果参数文件有问题而启动不了的解决方案:

>create pfile='/tmp/swat.ora' from spfile;

去操作系统修改/tmp/swat.ora.

>create spfile from pfile='/tmp/swat.ora';

>startup

进程的体会:

show parameter instance_name
ps-ef |grep arc
archive log list;
shutdown immediate
startup mount;
alter database archivelog;
alter database open;


启停的体会:

startup nomount:读取参数文件,通过参数文件的指定来启动实例。
startup mount:锁定控制文件。控制文件:记录数据文件,日志文件,检查点信息。
startup:
alter database mount;
alter database open;通过控制文件里面的信息来比较数据库的状态,如果状态一致,顺利打开数据库。


shutdown immediate:结束所有会话,回滚未提交操作。
shutdown abort :直接杀死所有会话,没有回滚,数据库重启后会出现数据不一致要reover。
shutdown transactional:没有事务的会话杀掉,有事务的等事务提交才杀。不需要回滚操作。
shutdown normal:新的会话无法连入,非常客气的等待所有会话退出才关闭。


文件的体会:

show parameter spfile 参数文件位置
show parameter control 控制文件位置


set linesize 1000


col file_name format a100


col member format a100
select file_name from dba_data_files; 数据文件位置
select group#,member from v$logfile;日志文件位置
show parameter recovery 归档文件位置
set linesize 1000
show parameter dump 日志警告文件位置
ls -lart alert*


监听:lsnrctl status | lsnrctl stop | lsnrctl start
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: