Oracle物理的体系结构

体系结构图的学习:

  1. 老余服装店的故事
  2. 结构图:
    1. SQL查询语句
      1. SGA
        1. 共享池shared pool
        2. 数据缓存区Buffer cache
      2. PGA
      3. 进程
    2. SQL更新语句
      1. SGA:
        1. 日志缓存区
      2. 日志文件
  3. 深入学习
    1. 提交
    2. 回滚
    3. 一致读

实践体会:

  1. 内存
  2. 进程
  3. 启停
  4. 文件
  5. 监听

学习意义:

体系结构图:

Oracle物理的体系结构_第1张图片

说明:

  1. oracle由实例和数据库组成
  2. 实例由:专门开辟出来的一块SGA内存区域和一些列后台进程组成,其中SGA主要被划分为共享池(shared pool),数据缓存区(db cache),日志缓存区(log buffer)这三个部分。另外加上oracle的一些进程:DBWn,LGWR,ARCH,CKPT这些有和硬盘打交道。其它进程还有:PMON,SMON,LCKn,RECO.
  3. 数据库的文件组成:
    1. 数据本身:
      1. 数据文件:
      2. 日志文件:
        1. 联机日志文件:必须多路复用(group-Nmember);循环写
        2. 归档日志文件:归档日志文件会被移动到磁盘或磁带,用于备份和恢复。
    2. 启动实例:
      1. 参数文件:
      2. 控制文件:
  4. PGA也是开辟出来的一块内存区,和SGA的差别是,PGA私有不共享。用户连进来是的第一关就是PGA:
    1. 连入数据库时
      1. 保存用户的连接信息:如会话属性,绑定变量等。
      2. 保存用户的权限,当用户建立会话时,系统会去数据字典查询用户的权限信息,并保存在PGA中。
    2. 取回数据时
      1. 如果取回的数据需要排序,那么排序的活动在PGA内完成,如果PGA不够,那么使用临时表空间(尽量不使用临时表空间,因为会大量增大磁盘IO,降低性能。)。
  5. 上图分为3个区域,内存里面主要是1区PGA,2区SGA,硬盘为3区。一般的数据库操作是1-2-3或者仅仅是1-2.

老余的故事:

  1. 顾客的尺寸—soft parse
  2. 有效的调整—buffer cache
  3. 记录的习惯—目的是提高性能,批量的刷数据,而不是提交一笔刷一笔。

一条查询语句的历险:

  1. sqlplus建立一个会话,执行查询select id from t where obejct_id=29;这个时候先完成PGA的3步骤中的头2步:保存会话信息,用户权限信息,然后将sql语句hash出一条hash值。
  2. 带着hash值,sql进入了第二个区域:共享池,在这里首先查找是否有同样的hash值。如果没有,那么就比较辛苦:首先查询语法是否正确,然后查询语义(表和字段有没有写错)是否正确,是否有权限等,确认完这些,将hash值存储下来。接下来进行硬解析,经过优化器分析以后Oracle会选择一个低成本的执行计划。
  3. 带着自信计划的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;
    • Oracle物理的体系结构_第2张图片
    • 前后两次执行同一条语句:第二次比第一次少很多时间。原因是第二次少做了一些事情:
      1. 因为会话没有断开,所以不需要再去数据库读取权限和用户信息,少了很多物理读。
      2. 因为是第二次执行同一条语句,所以SGA的共享池里已经保存了相对应的hash值,比照一样之后,不需要做语法语义的验证,也不需要做硬解析获得优化的执行计划,只要把已经解析好的执行计划拿来用就好。
      3. 数据被取到SGA的数据缓存区里面,也不需要去硬盘读。
      4. 可以用/*+full(t)*/强制sql走全表扫描。

一条更新语句的历险:

  1. 如果用户还是没有退出session,那么PGA部分保存的内容不需要再做一遍。还是会将sql语句hash出一条hash值。
  2. 带着hash值,sql进入了第二个区域:共享池。照旧:首先查询语法是否正确,然后查询语义(表和字段有没有写错)是否正确,是否有权限等,确认完这些,将hash值存储下来。接下来进行硬解析,经过优化器分析以后Oracle会选择一个低成本的执行计划。
  3. 带着自信计划的sql接下来进入第三个区域:数据缓存区。去磁盘里面按照执行计划来查找,读出来的数据会被放回数据缓存区。
  4. sql执行update改变缓存区中数据的值。
    1. 这个改变动作导致内存中的数据块变脏。DBWn专门负责将脏数据写入磁盘。
    2. 这个改变动作被oracle记录到日志缓存区,有LGWR快速写入联机日志文件。
    3. 如果联机日志文件写满,切换日志时会把写满的联机日志文件用ARCH写入归档日志文件。这里面有个速度问题,如果有个联机日志ARCH进程没有完全归档完,就有LGWR要来写,说明联机日志文件太小或者文件个数太少。
  5. 提交:只有用户commit,这条更新语句才会在数据库生效,如果用户放弃,则用rollback。
  6. 日志文件和数据文件的关系:日志存在的目的在系统崩溃后重启时,把在日志中记载的,但是没刷到数据文件的操作重新做一遍。所以如果平时DBWn不勤快的刷数据,数据库的性能越好,但是同时的日志里面没刷的内容相应的也越多,断电恢复需要的时间也越长。可是如果平时DBWn很勤快,那么固然恢复的时间段了,却会影响到数据库的性能。控制这个平衡的就是CKPT。
  7. 什么时候数据由数据缓存区写入到磁盘,这是由CKPT来控制的(傻把式DBWn是听CKPT来指挥的),另外如果LGWR出了故障,那么DBWn会被拦住,因为DBWn必须等LGWR把操作记录到日志以后才能写相应的数据到磁盘,这就是“凡事有记录”。

劳模评选:LGWR

  1. PMON:这个是进程监视进程,如果你的sql更新语句进程崩溃,PMON自动帮你rollback,其它进程如RECO等崩溃,PMON帮助重启进程,遇到LGWR崩溃,PMON为终止整个实例,以避免数据产生不一致现象。
  2. SMON:系统监视进程,与PMON不同,SMON关注的是系统级别的操作,而非单个进程。重点工作在于实例恢复,同时还有清理临时表空间和回滚段表空间,合并空闲空间等。
  3. LCKn:仅仅用于RAC,用于实例间的封锁,n从1到10.
  4. RECO:用于分布式的恢复: 比如有A,B,C三个分布式数据库,一个应用横跨这3个数据库,一个提交一定在3个库全部提交成功才成功,否则回滚。
  5. CKPT:通过FAST_START_MTTR_TARGET(eg. 300秒)的设定来控制DBWn写入的频繁程度,参数越短,恢复时间越短,写入越频繁,性能越差。
  6. DBWn:系统最核心的进程,负责将数据写入磁盘,受CKPT指挥,和LGWR密切相关。
  7. LGWR:也是系统最核心的进程,负责把日志缓存的日志写到磁盘的日志文件中。日志文件必须是按顺序记录,中间错了任何一条,其后的所有日志就报废了。所以多路复用非常关键。另外因为日志必须按顺序记录,所以LGWR无法采用多进程,只能采用单一进程,否则次序错乱了。 在这样的情况下,为了保证LGWR及时有效的写入日志文件,LGWR自己给自己加压,定了5条规矩,通过这些规矩从不同侧面保证日志文件的可靠性,:
    1. 每个3秒跑一次,将这3秒内的日志写入磁盘。
    2. 任何Commit触发LGWR运行一次,将commit的内容写入磁盘。
    3. DBWn要把数据从缓存写到磁盘前,触发LGWR运行一次,把相关内容写入磁盘。
    4. 日志缓存区满1/3,或者日志满1m,触发LGWR运行一次,把1/3的内容,或者1m的内容写入磁盘。
    5. 联机日志文件切换,触发LGWR运行一次,将切换前的日志写入磁盘。
  8. ARCH:日志切换是会触发ARCH进程,另外日志在被覆盖之前如果没有归档,会触发ARCH归档完毕以后再覆盖。

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

  1. 首先找到要更新的记录,读入到数据缓存区(和查询一样)。
  2. 在回滚段表空间分配空间,在数据缓存区中创建该记录的镜像,通过DBWn将镜像写入回滚段表空间,并且用日志记录下这个动作。
  3. 在2做好的前提下,然后对有镜像的原记录进行修改,并且将这个修改的动作写入日志。
  4. 此时,如果用户提交,那么LGWR要立即写入这个提交信息。并且,将回滚段的事务表上的该事务标记为非活跃状态,表示允许重写。
  5. 如果进行了回滚,则oracle要从回滚段中读取镜像记录,还原被修改的记录。这个过程也会被日志记录起来。
  6. UNDO_MANAGEMENT=AUTO:自动管理回滚段
  7. UNDO_RETENTION=900:commit后900秒才能覆盖回滚段的内容.

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

  1. insert压力最小.只记录rowid,回滚的时候只要定位到行删除即可.delete压力最大,需要重新插入回来整行.
  2. 对于日志文件则反之.

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

  1. SCN全称系统改变号码,存在于数据库的最小单位块中.每一个块的改变都会引起SCN的递增.
  2. 数据库的回滚段记录事务槽,这个是用来分配回滚段空间的.如果你更新某块,事务就被写进槽里,若未提交或者未回滚,则该槽就是活跃的.数据库读到这一块可以识别这种情况.
  3. 查询的时候,如果scn号比发起的scn号小,则看是否是活跃事务,如果是活跃事务,去回滚段读数据.如果scn号比发起的scn号大,那么也去回滚段读数据.
  4. Oracle宁可返回错误,也不能返回不一致读.如果回滚段的镜像由于反复修改被覆盖了,oracle会返回ORA-01555错误.
  5. 块头的ITL槽记录scn号,活动的话,可以找到对应的undo表空间.

实践:

  1. 内存的体会: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 在操作系统查看共享内存。
    1. 现在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即可。
    2. log_buffer是不能自动分配的。必须手动,一般15m就够了。由于每1/3写一次,每满1m写一次,所以分配太大优化也不是太明显。
    3. 修改语法:ALTER SYSTEM SET <parametername>=<value> SCOPE={MEMORY|SPFILE|BOTH}.
      1. 如果实例使用pfile启动,则scope的默认值是memory,如果是spfile启动,默认值是both。
      2. 有些参数必须重启才能生效,如log_buffer,sga_max_size等。会报错:ORA-02095: specified initialization parameter cannot be modified。
      3. 如果参数文件有问题而启动不了的解决方案:
        1. >create pfile='/tmp/swat.ora' from spfile;
        2. 去操作系统修改/tmp/swat.ora.
        3. >create spfile from pfile='/tmp/swat.ora';
        4. >startup
  2. 进程的体会:
    show parameter instance_name
    ps-ef |grep arc
    archive log list;
    shutdown immediate
    startup mount;
    alter database archivelog;
    alter database open;
  3. 启停的体会:
    startup nomount:读取参数文件,通过参数文件的指定来启动实例。
    startup mount:锁定控制文件。控制文件:记录数据文件,日志文件,检查点信息。 
    startup:
    alter database mount;
    alter database open;通过控制文件里面的信息来比较数据库的状态,如果状态一致,顺利打开数据库。
    
    shutdown immediate:结束所有会话,回滚未提交操作。
    shutdown abort :直接杀死所有会话,没有回滚,数据库重启后会出现数据不一致要reover。
    shutdown transactional:没有事务的会话杀掉,有事务的等事务提交才杀。不需要回滚操作。
    shutdown normal:新的会话无法连入,非常客气的等待所有会话退出才关闭。
  4. 文件的体会:
    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*
  5. 监听:lsnrctl status | lsnrctl stop | lsnrctl start

你可能感兴趣的:(oracle)