Oracle学习笔记一

读《收获,不止oracle一书》笔记。

------------------------------------------------------------------------<一>------------------------------------------------------------------------

oracle体系结构

一、基本体系结构

1区PGA (Program Global Area):是有内存区,用户发起的查询或更新等请求首先在PGA区进行预处理,主要有三点:

      a、保存用户的数据库连接信息,形成连接池。如会话属性、绑定变量等;

      b、保存用户权限等重要信息,当用户进程与数据库建立会话时,系统会将这个用户的相关权限查询出来,然后保存在这个会话区内;

      c、当发起的指令需要排序的时候,PGA正是这个排序区,如果在内存中可以放下排序的尺寸,就在PGA区内完成,如果放不下,超出的部分就在临时表空间中完成排序,也就是在磁盘中完成排序。

 

2区实例(instance)=SGA(System Global Area)+一系列后台进程:SGA被划分为共享池(shared pool)、数据库缓冲区(db  cache)和日志缓冲区(log buffer)三类。后台进程包括PMON(ProcessMonitor)、SMON(System Monitor)、LCKn、RECO、CKPT、DBWR、LGWR、ARCH等系列进程

 

3区数据库:由数据文件、参数文件、日志文件、控制文件、归档日志文件等系列文件组成、其中归档日志最终可能会被转移到新的存储介质中,用于备份与恢复。

 

二、Oracle体系内执行查询语句的一般流程

用户发起普通的SQL查询语句如select object_name from t where object_id=29,在object_id列建有索引的情况下,执行过程一般可分解如下:

a、PGA区保存用户的数据库连接信息和权限信息,针对该条SQL会立即匹配一条唯一的HASH值;

b、进入2区SGA的共享池,在共享池内查询是否有存储过这个SQL指令的HASH值(身份证,认证之前是否有执行过与之一样的SQL语句)。如果没有,需要认证该条语句,主要有语句语法是否正确(比如from是否写成了form)、语义是否正确(比如id字段根本就不存在)、是否有数据库数据访问权限等;

c、认证完后,共享池会存下该条语句的HASH值;

d、预估 在有索引情况下,是采用索引更高效还是全表扫描更高效?并选定一种查询方式  (预估并不是真正的执行),选定后执行计划将和SQL语句的HASH值关联存储在共享池。

e、得到执行计划后,先去数据缓存区(内存)找数据;如果数据缓存区没有,则需要从数据库文件中查找,将查找到的数据存到数据缓存区中,然后返回结果给用户。

 

Oracle体系内二次执行语句效率提升点

a、用户首次执行SQL指令时,连接信息需要读取文件tnsname.ora,需要物理读。二次执行时从PGA中直接获取,避免物理读。

b、二次执行同一条语句时,在SGA共享池中能够查找该语句的HASH值,跳过了语法检查和执行计划预估

c、二次执行同一条语句时,数据缓存区里已经缓存了包含查询结果的数据,只需在内存中少量的数据里查询,无需去数据库文件(物理读)中查询。(问:数据库缓存的数据与查询结果数据是什么关系,如果有索引,是否是返回所在索引节点内的数据,没有索引返回全部数据?--待了解)

 

三、Oracle执行更新语句的一般流程

除了查询语句执行的动作之外,更新语句还执行了:

1、修改数据缓冲区内对应记录的数据

2、DBWR进程将更新的数据从内存中刷入磁盘,Oracle根据一定的规则完成commit动作,就是缓存去数据积累到一定程度再刷入磁盘,CKPT进程触发DBWR写出;内存数据丢掉,可以通过日志文件恢复。可以设置期望的断电恢复时间等参数来控制CKPT的触发时间。DBWR不是由COMMIT控制的,是由CKPT进程决定的,所以不希望提交修改需要ROLLBACK

3、LGWR进程将日志缓存区里的数据写入到日志文件1、2、3、4,文件写满之后,ARCH进程负责将日志文件1备份,日志覆盖到1中,然后依次是2,3,4备份与覆盖。日志文件记录了数据库操作的动作,比如A动作建立一张表T;B动作,插入一条数据进T表;C动作将改数据更新某字段。A、B、C动作都被记录到日志中,若记录被删除了可以重新执行B、C恢复;若表被删除了,可以重新执行A、B、C恢复。------凡事有记录

 

四、ORACLE后台进程职责介绍

PMON(Process Monitor):进程监视器。主要功能如:更新时未提交进程崩溃,PMON会自动回滚该操作,无需人工执行ROLLBACK;可以在进程异常失败进行相应处理,如RECO异常可以重启进程,但是如果是LGWR进程,则会终止数据库实例。

SMON(System Monitor):系统监视器,SMON关注的是系统级的操作而非单个进程,重点工作在于instance recovery,除此之外还有清理临时表空间、清理回滚段表空间、合并空闲空间,等等

LCKn:仅适用于RAC数据库,最多有10个进程(LCK0,LCK1,......,LCK9),用于实例间的封锁

RECO(Distributed Database Recovery):分布式的数据库恢复,适用于两阶段提交的应用场景。比如某个应用跨越三个数据库,在发起的过程中需要A、B、C库都提交成功,事务才会成功,只要有一个失败,就必须全部回滚。

CKPT:控制触发DBWR将数据缓冲区数据写入到数据文件

LCWR:把日志缓冲区的数据从内存写到磁盘的REDO文件里,完成数据库对象的创建、更新数据等操作过程的记录。REDO文件可用来做数据库的异常恢复,理论上来说即使数据文件被删除光了,只要保存好REDO文件和归档文件,还是可以让数据库根据这些日志记录,把所有的在数据库中曾经做过的操作全部重做一遍,从而恢复数据库中的记录。这里的前提是REDO文件和归档文件保存顺序和结构都没有被破坏。LGWR是单进程遵循5条严格的制度:

      a、每个三秒中,LGWR运行一次。

      b、任何COMMIT触发LGWR运行一次。

      c、DBWR要把数据从数据缓存区写到磁盘,触发LGWR运行一次

      d、日志缓冲区满三分之一或记录满1MB,触发LGWR运行一次

      e、联机日志文件切换也将触发LGWR

ARCH:它的作用是在LGWR写日志写到需要覆盖重写的时候,触发ARCH进程去转移日志文件,复制出去形成归档日志文件,以免日志丢失。

 

五、回滚的原理

 事务槽分配回滚空间。前镜像是与回滚事务槽对应的,表示指向每次更新写入的最新内存空间,当每次更新时,上次更新的内存会提交到回滚事务槽中,回滚事务槽保存有限的事务(分为活动事务和已提交的事务)。这与数据库缓冲区的机制差不多,数据缓存区最终是提交到数据库的。回退就是将回滚事务槽中的数据更新到数据库中

 示例:update t set object_id=92 where ogject_id=29   

      a、数据缓冲区中查找想要更新的记录,不存在则从磁盘中预拉数据;

      b、在回滚表空间响应回滚段事务表上分配事务槽,从而在回滚表空间分配到空间。该动作需要记录日志写进日志缓存区

      c、在数据缓冲区中创建object_id=29的前镜像,前镜像数据也会有CKPT控制写进磁盘的数据文件里(回滚表空间的数据文件),该动作会记录到日志。

      d、前面的步骤做好了,才允许将object_id=29修改为object_id=92,该步骤被记录到日志

      e、此时用户如果执行了提交,日志缓存区立即要记录这个提交信息,然后把回滚段事务标记为非激活状态,表示允许重写;

      f、如果用户执行的是回滚,Oracle需要从回滚段中将前镜像object_id=29的数据读出来,修改数据缓存区(预拉数据到缓冲区,普通的查询是拉数据库中正常的数据;回滚操作是拉数据库中回滚表中的数据),完成回滚,这个过程依然要产生日志。

 

DML语句不同于查询语句,是会改变数据库的数据,除此之外还会产生用于将来恢复的redo和用于回退的undo。为另外一个细节就是,由于undo也需要保护,所以还会专门产生保护undo操作的redo每次更新都会有个内存块记录,该记录地址保存在回滚事务槽中,用于undo和redo操作。

六、一致读原理

SCN(Systen Change Number):记录Oracle最小单位内存块的时间戳,当块中的内容被更新时。SCN号就会递增。

数据库的回滚段记录事务槽分配回滚空间,如果你更新了某块,事务就被写进事务槽里。如果未提交或者回滚,该块就存在活动事务,活动事务可别Oracle识别。

 

 例:假如用户在数据库中有4个户头,户头1有1000元,户头2有2000元,户头3有3000元,户头4有4000元,问:如果查询持续时间8:00-9:00,期间户头1转账到户头4500元,如何保证查询到的用户账户总额正确?

假如8:00以后户头未更新过,即每个户头对应的块SCN号都在8点以前(比如SCN7:00、SCN6:00、SCN7:00、SCN7:30),则当前的查询SCN号如SCN8:00一定大于各个户头的SCN号,此时只需全部读取最新SCN块的金额相加。

假如8:30查询到户头3刚结束,户头4接收到户头1转过来500块钱,此时户头1和户头4的SCN号更新成SCN8:30,户头1SCN8:30的块里成了500,户头4SCN8:30的块里变成了4500。此时户头3读完后,读户头4不能读最新的内存块SCN8:30了,否则查询到的数据不一致,而是找undo块8点或以前的SCN记录SCN7:30,值为4000。

如果别的用户更改了某个户头,未提交,则该户头的SCN号更新为当前时间,但是事务槽中的事务为活动事务,查询的时候不会取活动事务的值,而如果前镜像一直被重写,导致找不到1000这个数据,Oracle会包ORA-01555错误终止退出。

一致读解决方案解决了早期数据库边度边锁(允许修改读过的,锁住未修改的数据)的问题,保证了读一致性,大大增强数据库并发操作的能力。

 七、数据库启停

数据库启动可以分为startup nomount、startup mount和alter database open三步,也可以startup启动。show parameter spfile | control (参数文件,控制文件);select file_name from dba_data_files(数据文件)

startup nomount:该阶段必须读取到数据库的参数文件(PFILE或者SPFILE),根据参数文件上的内存分配策略分配相应的内存区域,并启动相应的后台进程(创建实例)。

startup mount::根据参数文件上描述的控制文件的名称及位置,去查找控制文件,一旦查找到立即锁定该控制文件。控制文件里记录了数据库中数据文件、日志文件、检查点信息等非常重要的信息。

alter database open:根据控制文件记录的信息,定位到数据库文件、日志文件等,从而正式开通了实例和数据库之间的桥梁。

数据库关闭:shutdown immediate

八、修改数据库参数

sqlplus tablename/'password'@db_user连接上数据库,执行命令 alter system  set <parameter_name> scope=memory|spfile|both [sid=<sid_name>]

memory立即生效,重启失效;spfile重启后才生效;both 前两者的结合,一致有效。学会根据实际情况改变参数进行数据库性能调优;
如:alter system set sga_targe=2000M scope=spfile; 修改SGA内存共享区大小

alter system set log_buffer = 15000000 scope=spfile; scope选项可以不写,只支持spfile,重启后生效。

九、了解数据体系结构的应用

1、合理设置SGA内存大小,解决共享池、数据缓存区分配的内存过小影响性能,过大造成主机内存不足的问题。

2、合理设置PGA内存区大小,避免物理排序或者主机内存浪费。

3、加入数据库系统存在大量的更新操作,需要从REDO BUFFER中写出到日志文件里,日志文件的切换动作会非常频繁,REDO BUFFER需要等待切换后写出,而数据缓冲区数据在REDO BUFFER后产生,造成数据更新走走停停,此时我们可以合理的增加日志文件的尺寸。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值