[原文链接] http://nvd11.blog.163.com/blog/static/200018312201301310585758/
[原文视频] http://www.jiagulun.com/thread-2674-1-1.html
1. 数据库文件
Oracle
数据库文件大概可分为3种,分别是:
控制文件(control files):
存放数据库本身物理结构信息
数据文件(data files):
存放数据库数据啦~
日志文件(log files):
包括重做日志文件和归档日志文件, 记录数据库数据的变化.
如下图:
2. 数据库实例
用户和应用程序是无法直接访问数据库文件的数据的,
这时 Oracle 服务器会启动 (1或多个..RAC集群啦)个实例.,用户可以通过连接这个实例来访问数据库的数据。
实例有两个组成部分,分别是:
系统全局内存区(SGA):服务器专门划分给 Oracle 实例使用的内存块。
Oracle进程:包括服务器进程和后台进程, 后面会解析。
2.1 系统全局内存区(SGA)
SGA 可以分成 6 大块,分别是 Java pool,
shared pool, database buffer cache, large pool, streams pool, Redo log
buffer
[注] 可用 v$sga 这个视图去查看 sga 各大块大小.
这篇文章介绍的是 sql 语句的执行流程,所以主要讲解其中的3个大块:
共享缓冲区(shared
pool)
数据库缓冲高速缓存(database buffer cache)
重做日志缓冲区(redo log
buffer)
如下图:
2.2 服务器进程
当用户(客户端)要连接 Oracle 数据库时,
Oracle就会创建 1 个 session(会话),并且在服务器上创建 1个专门处理这个 session 的进程,就是服务器进程啦。
如下图
2.3 PGA(Program Global Area)
对应上面的 Server
Process, Oracle 会在服务器上对每一条 Server Process 分配一定大小的内存,就是PGA了,
注意有几个 session 就会有几个对应的 SGA 块, 所以服务器对内存需求很大的。
可以用
select
sum(pga_userd_mem) from v$process
语句来查看当前使用的总 PGA 大小。
如图:
3. 客户端与服务器的SQL语句传输
这条语句通过什么来传输呢?答案就是session啦, 那么服务器上用什么来接受这个sql 语句呢, 答案就是Server Process。
如图:
5. server process根据 sql 语句生成执行计划(execute plan).
Oracle 是无法直接执行 sql 语句的,必须先生成执行计划,然后 Oracle 就会根据执行计划去执行了。而生成执行计划要访问许多数据库对象, 是一个比较消耗服务器资源(CPU,IO,Memory)的动作。
而且因为同一条 sql 语句可能会有多个用户多次重复的执行, 那么是否每次都生成一次执行计划呢? 这时 SGA 里面的 Shared pool 就发挥作用了,它会缓存 sql 的执行计划。
所以 server process 会首先从 Shared pool 里面查找有无现成的执行计划, 如果有就直接采用。如果无, 就自己生成一个,然后看情况把这个执行计划放入shared pool。
6. server process 根据执行计划去取(写)数据.
好了。当 server process 得到执行计划后就可以去取数据了。Oracle 的数据放在哪里呢? 放在数据文件,这个大家都懂,但是 server process 是不是就直接去访问数据文件呢?
因为计算机的时间消耗主要都在物理IO,所以要尽量避免物理读写,所以SGA 里面的 database buffer cache 起作用了。说明白点, database buffer cache 就是用来缓冲 Data files 里的数据的。这样就可以避免了对数据文件的读写。
所以 server process 得到执行计划后,第一步是首先去 database buffer cache 去找有没有现成的数据;如果有最好, 如果无或者缓存中数据不全的话就只能去访问data files 啦。
从 data files 获得数据后, 也不是直接发给用户客户端,而是根据情况放入database buffer cache 里面, 以便当前或其他用户多次使用啦。
7. 逻辑读、物理读与缓存命中率.
由上图得知,所谓逻辑读,就是从缓存(一般是内存)里读取数据。而物理读,也就是从磁盘(数据文件)里读取数据啦。
至于缓存命中率,就是取出数据的过程中 逻辑读次数/ (逻辑读次数+物理读次数) 这个比率。当然这个比率越接近1越好, 因为物理读相当费时间啦, 除非有服务器用SSD做硬盘。
当然命中率并不是数据库健康的唯一指标,因为当逻辑读十分巨大的时候, 即使物理读也很大,这个比率也很好看的, 所以有时要关心每秒物理读(tps)。
可以在 linux 下使用 iostat 命令来查看当前磁盘的每秒物理读啦。
8. 在缓存中修改数据
9. 修改数据会产生重做日志
上面提到日志是用来记录数据库的数据变化的,所以对数据改动产生一定量的日志数据。那么这些日志是不是直接就写到日志文件中呢?写日志文件也是物理读,所以 SGA 就有个 Redo log buffer,就是日志缓存,专门实时存放产生的日志数据啦。
10. 最终Server Process把返回数据或信息通过session传回给用客户端
Server Process 做完读取和修改数据的动作后,就会将结果返给用户了。
11. 将数据缓存和日志缓存写入磁盘
其实到上面那一步为止, 整个 sql 语句执行流程已经完成了。可能有人会问, Server process 修改的数据和产生的日志还在 SGA 里面呢,它们不用被写入磁盘吗?
答案是肯定需要的,但是这些动作已经不是 sql 执行流程之内,而且这些动作也不是 server process 负责的, 他们分别由 DBWR 和 LGWR 这个两个进程负责。
如图:
DBWR: Database writer,后台进程之一,负责将 Database buffer cache 里被修改的数据写入数据文件。
LGWR: Log writer,后台进程之一,负责将 Redo log buffer 里的日志数据写入到日志文件。
12.为什么Oracle要将server process 和后台进程分开?
为什么写入数据文件和日志文件要交给后台进程去完成呢? 其实我们在流程可以发现, 服务器与用户打交道的就只有一个进程,就是Server Process, 所以 server Process 的速度直接影响了用户的感受。无论后台进程多么繁忙,只要 server process 响应迅捷, 用户还是觉得数据库很快的。 相反,后台进程没事做,服务器 CPU 很空闲,但 server process 反应慢的话, 用户就觉得数据库慢了。
所以就要尽量精简 server process 的动作, 看看后台进程 DBWR 和 LGWR 进行的是什么动作, 磁盘写动作啊! 所以这些动作完全可以在sql流程执行完慢慢来嘛。
Server Process 唯一进行的物理操作就是物理读, 这个是无办法避免的, 因为数据都在磁盘上嘛。除非有办法预测用户要提取的数据,提前拿出来。但也没有那么大的内存啊。
13. 顺便介绍其余3大系统进程 CKPT, SMON, PMON
都说 Oracle 有 SGA 6 大池,3 大数据库文件, 5 大系统进程。其中DBWR 和 LGWR上面已经介绍过了。剩下其余3个:
CKPT : Checkpoint 检查点进程,负责更新控制文件和数据文件的头部信息, 控件文件在这篇blog开头就已经介绍过啦。至于数据文件的头部信息就是当前数据块的状态信息啦。
SMON : system monitor 系统监视器,负责监视维护 SGA 和后台进程啦,例如合并SGA里面的碎片。
PMON : process monitor 进程监视器, 这里主要指服务器进程啦。例如一个用户突然掉线了,但是该服务器进程还在服务器,Pmon会隔一段时间把该进程清理掉并且释放SGA 啦。
最后感谢老相老师用心做的教学视频, 真的很通俗易懂, 截个图。哈哈