美文网首页
Oracle体系结构2

Oracle体系结构2

作者: 苏水的北 | 来源:发表于2021-04-09 14:52 被阅读0次

    Oracle体系结构

    一、内存结构:

    image.png

    1、SGA:系统全局区,是Oracle的进程共享的内存区域。

    SGA中包含6大区域:(这些内存区域在Oracle实例运行期间,承担着不同的作用)

    1.1、shared pool 共享池

    image.png

    共享池包含:

    概念理解:
    一条SQL的执行流程:
    客户端-->连接实例-->执行SQL语句(客户端)-->SQL发送给Oracle实例-->SQL解析-->产生所谓的执行计划-->数据库实例中的优化器会基于各方面的成本进行考虑,选择最优的执行计划-->最终执行SQL语句-->结果返回给客户端。

    1.1.1、库高速缓存区
    1.1.1.1、共享SQL区域:Oracle为了提升执行效率,将执行过的SQL的执行计划保存在共享SQL区域。一旦有后续的SQL需要执行,则先来共享SQL区域中进行SQL对比。
    select * from test;  此语句一旦执行,`共享SQL区域`会保存该SQL执行的执行计划。
    select * from test;  如果有完全一样的SQL再次执行,则直接调用共享池(`共享SQL区域`)中的执行计划来执行, 获取最终结果。
    软解析:直接应用`共享SQL区域`中的执行计划的解析方式。
    select * from TEST;   重新解析SQL,重新生成执行计划,重新执行。
    硬解析:当未匹配到完全一样的SQL的执行计划,则需要SQL进行完整解析,并重新确定执行计划。
    
    1.1.2、数据字典高速缓存区(data dictionary)
    update test set id=100 where name='zhangsan';
    哪些情况会导致SQL执行失败:
    1.test表不存在。如果遍历硬盘中的所有表,固然能够确定该表是否存在,但是这样操作效率太低。
    数据库会自动维护数据字典,包含对象名称,为了提升查询数据字典的性能,数据字典默认缓存到内存中供进程访问。
    2.id字段,name字段不存在。数据字典中会缓存表结构中基本字段信息。
    3.zhangsan不存在。查询数据的操作是在表中完成的。
    4.权限不足。
    为了提高SQL的执行效率,数据库会自动维护数据字典信息,用于SQL对象确认,权限验证等操作。
    
    1.1.3、控制结构

    1.2、DB buffer cache 数据库缓冲区高速缓存

    image.png

    DB buffer cache:用于缓存数据块,提供逻辑IO,提升数据库性能。数据块是我们在建库时定义的数据库的基本IO单位。

    注意:建库时可以定义数据块的大小,但是建库完成后不能修改。

    SQL> show parameter block;
    
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    db_block_buffers                     integer     0
    db_block_checking                    string      FALSE
    db_block_checksum                    string      TYPICAL
    db_block_size                        integer     8192
    db_file_multiblock_read_count        integer     128
    

    buffer cache中缓存的就是来自数据库文件的数据块。

    select  * from test;(涉及到test表的一个数据块)
    Oracle实例会将test表对应的数据块从硬盘中加载到内存中,进行查询,将结果返回给客户端。
    update test set id=100 where name='zhangsan';
    Oracle 实例会将zhangsan数据所在的数据块加载到内存,对buffer cache 中的数据块进行修改,返回结果给客户端。
    总结:无论是查看还是修改数据,都是先将数据所在的数据块加载到内存,然后执行查询/修改的操作。
    
    1、脏数据:数据块刚被加载到内存,和硬盘中数据库文件中的数据块是一致的,但是一旦修改,则产生脏数据(脏块)。

    注:数据保存在内存中是不安全的,所以需要脏块落盘,buffer cache中的脏块落盘,才能保证已修改的数据的安全,但是脏块直接落盘性能很差,oracle中提出redo来保证脏块数据安全。
    思考:为什么不直接对硬盘进行修改操作?
    1、进程直接修改硬盘上的数据,理论上是可行的,但是对于数据库软件需要定位到修改的行数据。
    原id=99
    update test set id=100 where name='zhangsan';
    Oracle需要先定位99在硬盘上的位置,然后再将99改修为100。其实Oracle做不到这一点。
    2、Oracle实例将数据块加载到内存中进行查询和修改。
    Oracle实际直接修改硬盘数据。
    这两个过程都是涉及到内存中的实例和硬盘中的数据块进行交互。
    物理IO:内存和硬盘之间的数据交互。
    逻辑IO:数据块在之前已经被加载到内存中,此时如果再查找此数据只需要将内存数据块进行修改即可。

    undo回滚段:保存已修改但未提交的数据。

    2、Oracle中undo回滚段作用:

    1、支持事务rollback;
    2、隔离级别RC中, undo解决脏读问题。

    3、Oracle中redo重做日志作用:一旦事务提交,则redo落盘,相较于脏块直接落盘,redo落盘性能更好。

    事务举例:

    现在硬盘中内存中zhangsan的id都是99.
    session1执行:
    update test set id=100 where name='zhangsan';(不提交)
    session2执行:
    select id from test where name='zhangsan';
    返回结果是99,此时内存中数据块已经被修改为100,为什么返回99,这是因为在内存中有对应的undo区域,undo保存已修改旦未提交的数据。
    注:在当前会话中执行undate语句,又在此会话中执行select语句,查看到的是数据块当前值id=100;
    在其他会话中进行select查询,查询到的都是undo中的快照值id=99.
    这么做的目的就是为了保证事务之间是隔离的。
    
    4、事务的隔离性:
    Mysql的隔离级别:
    名称 简写 解释
    读未提交 RU 脏读,读到了未提交的数据
    读已提交 RC 解决了脏读问题(undo),出现幻读(读取到其他事务已提交数据,insert语句引起),不可重复读(读取到其他事务已提交的数据,delect、update语句引起)
    可重复读 RR 解决了幻读问题(间隙锁),解决了不可重复读问题(undo的MVCC),MVCC:多版本并发控制
    序列化 串行执行事务,并发度太低,不使用
    Mysql的隔离举例:
    session1 session2
    begin;
    begin;
    select id-->99 读数据块,发生物理IO
    select id-->99 读数据块,发生逻辑IO
    update id-->100 修改数据块,发生逻辑IO。 数据块-->100,undo-->99
    select id-->100 读数据块,发生逻辑IO
    结果1:select id-->100 读数据块,发生逻辑IO。当隔离级别是“读未提交(RU)”时出现这个结果,读到了未提交(脏)数据
    结果2:select id-->99 读取undo数据块,发生逻辑IO。当隔离级别是“读已提交(RC)”时出现这个结果。解决了脏读问题
    commit;事务提交,100生效
    结果1:select id-->100 读取数据块,当隔离级别是“读已提交(RC)”时出现这个结果,发生了"不可重复读"(同一会话中连续读取的值不一致)。RC级别解决了脏读问题(undo),但是存在幻读与不可重复读问题
    结果2:select id-->99 读取数据块,当隔离级别是“可重复读(RR)”时出现这个结果,解决了幻读问题(间隙锁),解决了不可重复读问题(undo的MVCC),MVCC:多版本并发控制,在undo中保存之前的多个值
    Oracle的隔离级别:

    Oracle中也存在事务的概念,事务之间也应该存在隔离性,但是很少讨论Oracle的隔离级别。

    名称 简写 解释
    读已提交 RC 默认隔离级别。解决了脏读问题(undo),出现幻读(读取到其他事务已提交数据,insert语句引起),不可重复读(读取到其他事务已提交的数据,delect、update语句引起)
    序列化 串行执行事务,并发度太低,不使用
    只读模式 只读模式的事务只能进行select操作,不能进行insert、update、delete操作

    1.3、redo log buffer 重做日志高速缓冲区

    image.png
    redo log buffer重做日志缓冲区:用于缓存redo log(重做日志)
    redo log 重做日志:实际上就是我们进行DML操作时,对数据块进行修改产生的日志信息。

    注:一旦数据库崩溃/发生异常,内存中的脏块消失,启动数据库实例是可以使用硬盘中的数据页+redo重构脏页恢复数据。

    对数据块修改:

    1、脏块---->脏块保存在buffer cache中;
    2、日志信息---->redo log---->redo log会被存放在redo log buffer中--->日志优先落盘
    为什么日志优先落盘?
    1、日志数据量小于数据块数据量;
    2、顺序IO(日志落盘)性能高于随机IO(脏块落盘)。
    注:buffer cache中的脏数据是异步落盘的;
    redo log buffer中的redo log是同步落盘的。
    在某种情况下,Oracle实例中的某些进程会将某些数据块刷新到硬盘。
    举例:

    原id是99,update id=100 后修改操作是发生在数据块中的。此时id变为100,id=100是脏数据,所在数据块脏块,脏块保存在内存中数据是不安全的,要求数据尽快落盘,又因为脏块直接落盘性能差,所以引入redo log的机制来代替脏块直接落盘。
    在现在传统关系型数据库中,保证数据持久性,都是通过redo机制来保证的。
    

    1.4、large pool 大型池

    image.png
    1.4.1共享服务器:一对多的工作场景。与监听进程的工作机制相关。
    服务器进程:客户端连接,在Oracle数据库服务器中产生服务器进程,服务器进程的工作室一对一的。一个服务器进程使用一块PGA空间,为一个用户连接/会话提供服务。
    1.4.2备份恢复操作:后续解释。

    1.5、java pool java池

    1.6、stream pool 流池

    2、PGA:进程全局区,是Oracle的服务器进程(前台进程)独占的内存区域。

    image.png

    PGA区域包含(这些内存区域在Oracle实例运行期间,承担着不同的作用):

    2.1、堆栈空间

    2.2、用户全局区(UGA)

    UGA最主要作用:

    1、保存会话信息;
    2、用于查询排序。当用户执行查询操作并且对查询结果进行排序。

    索引组织表和堆表区别:

    1、Mysql --->InnoDB索引组织表
    Mysql会自动基于主键创建聚簇索引,并且向表中插入数据时,数据会按照聚簇索引段/主键值进行排序存放。Mysql中存放的数据是有序的(主键值数据有序)。
    2、Oracle ---> 堆表
    Oracle数据表中存放的数据是不进行排序的,数据是无序的。堆表中的数据顺序取决于插入顺序。
    例如:
    select * from test order by id; 希望看到所有的行记录并且是按顺序显示。
    怎么实现:我们对数据的排序操作,并不是在物理的数据块中直接进行的,而是先获取数据块中的数据,然后再进行排序操作。
    排序区使用级别:
    1、UGA--->数据量小时使用;
    2、临时表空间--->数据量大时使用。

    二、进程结构:

    image.png

    Mysql和Oracle进程区别:

    1、Mysql是典型的单进程多线程数据库。

    Mysql实例中包含的进程只有一个“mysqld”,我们从操作系统层面也只能观察到进程层面的内容,Mysql实例真正进行操作的实际是mysqld进程中包含的很多线程。

    2、Oracle是典型的多进程数据库。

    Oracle实例运行起来后,会同时启动很多进程,用于执行用户操作。

    2.1Oracle进程:

    image.png
    2.1.1、实例中后台进程:是Oracle实例运行起来后自动运行的进程,完成Oracle的基本功能。
    1、数据库写进程database write(DBWn):作用就是将内存中的脏块刷新到硬盘中。为了提高刷脏效率(脏块落盘效率),会存在多个DBW进程并发刷脏。

    DBWn进程刷脏的两种场景:
    1、DBWn进程刷脏操作跟事务是异步发生的,会以一定的频率进行异步刷脏;
    2、触发检查点,立即进行刷脏(触发检查点:alter system checkpoint)。

    检查点(checkpoint):
    所谓检查点,就是在数据库中设置一个时间点,保证该时间点之前的脏块都落盘。一旦触发检查点,就会进行刷脏操作,保证该时间点的数据块数据一致。
    检查点优点:
    1、促进刷脏,在buffer cache中提供更多的可用空间,用于加载硬盘数据块;
    2、推进检查点,能减少数据库恢复时间。
    注:redo log如何保证数据安全?
    真正的数据其实是在buffer cache中的脏块中。一旦故障启动数据库,数据库就会使用硬盘中数据块和redo log重构脏块。如果不进行积极落盘,buffer cache中存在大量脏块,一旦异常意味着大量的脏块需要重构,实例启动好费时间。

    2、日志写进程Log write(LGWR):负责将sga中的redo log buffer中的redo log落盘到redo log file中。
    image.png

    redo log 工作机制:

    英文名 中文名 归属区
    redo log buffer 重做日志缓冲区 内存结构
    lgwr 日志写进程 进程结构
    redo log file 重做日志文件 文件结构

    redo log设计目的?
    redo log就是为了替代脏块落盘,脏块落盘性能差(数据量大、随机IO),redo log(数据量小、顺序IO)。所以redo log落盘性能好。
    注:无论是脏块落盘还是redo log落盘,最终目的都是实现事务的持久化,保证数据的安全性。
    redo log落盘和事务提交是同步的。当事务进行提交时,执行commit操作,只要redo log落盘成功后,就会给用户返回commit成功的结果。
    在以下情况下lgwr会触发redo落盘操作:
    1、事务提交commit;
    2、重做日志缓冲区的三分之一已满时;
    3、每3s redo log落盘;
    4、每当redo log满1M。
    总结:出发redo log落盘,对于现在的OLTP业务而言,都是一些比较简单比较小的事务,这些业务中事务的redo基本都是commit落盘。其他的机制更多的应用场景是保证数据库中大事务数据的安全。

    3、检查点进程check point(CKPT):为了尽量缩短数据恢复时间。注意:一旦触发检查点,会发生脏块落盘。
    image.png
    4、系统监督进程system monitor(SMON):smon进程管理其他进程。作用:1、在实例启动时执行恢复操作;2、清除不使用的临时段。

    注:当kill掉smon会导致实例结束。当kill掉非smon实例不会结束,且会被自动运行起来。


    image.png

    查看Oracle实例进程时,仅需要查看smon进程即可,smon进程是整个Oracle实例的主进程。
    Oracle实例中的进程都是独立运行的,这些进程的ppid都是1,简言之这些进程的父进程都是Linux操作系统的init。
    如果数据库异常,则数据库实例启动时,可以基于数据块+redo进行脏页重构从而恢复数据。

    5、进程监督进程process monitor(PMON):进程监视器进程(PMON) 在用户进程失败时执行进程恢复。PMON 负责清除数据库缓冲

    区高速缓存和释放该用户进程占用的资源。例如,PMON 会重置活动事务处理表的状态,释放锁,并从活动进程列表中删除该进程ID。
    举例解释:pmon:当用户进程发送update语句后,用户进程崩溃,导致用户进程并没有给服务器进程发送commit/rollback指令,此时服务器进程执行了update语句,也就意味着数据被修改,脏块产生。pmon此时检测到这种情况发生,会自动在服务器进程中进行回滚操作。也能够保证数据不受影响,释放锁。
    注:本身当客户端发送exit(断开连接,结束会话)操作,意味着服务器进程结束+pga释放资源--->pmon则负责结束服务器进程并释放pga。

    总结pmon作用:

    1、保证数据不受异常影响,并且释放锁,负责结束服务器进程并释放pga资源。
    2、pmon会检测会话的空闲时间,超过超时时间后,释放空闲会话占用的资源。
    3、在监听中自动注册数据库实例。


    image.png

    注:smon/pmon本身作为监视器进程都会对其他进程进行监视。

    6、归档进程archive(ARCn):归档进程负责将redo log file中的数据转储到归档日志文件。

    archive log(数据)工作流程:当buffer cache(数据块)中数据块被修改后,会产生redo log(数据偏移量),此时redo log(数据)会被暂存在redo log buffer(内存)中,再由lgwr进程写入到redo log file文件中落盘。这个时候ARCn进程就可以将redo log file文件写入archive log file中。引入archive log file的目的是因为redo log file是循环覆盖。

    2.1.2、前台进程:用户连接,在数据库中创建的进程,用于执行用户操作。
    2.2Oracle中特殊进程介绍(守护进程):

    1、监听进程(TNSLSNR进程):监听进程只是实例与Linux内核之间的桥梁,监听进程仅服务于实例,但不属于实例。数据库实例的启停不会影响监听进程。
    2、GI进程(grid集群管理软件运行的进程):独立于Oracle实例进程之外。

    相关文章

      网友评论

          本文标题:Oracle体系结构2

          本文链接:https://www.haomeiwen.com/subject/nufgkltx.html