|
1 |
体系结构和ASM oracle设计的原则 1.内存读写永远比硬盘读写效率高 2.事物一旦提交就不会丢失
内存(SGA,PGA) 硬盘(数据文件,控制文件,日志文件) 从控制文件中找数据文件 参数文件规定了内存分多大,有多大内存,开多少个进程
写一条SQL语句(select * from students)在客户端录入,客户端通过网络连接把SQL语句传到服务器中,服务器收到之后,谁来接纳这条语句呢?监听接到了用户的连接后,他会把自己转换成oracle中的一个server process(相当于一个管家,什么事情都是他干)。 每一个客户连接,就会产生一个server proces(前台进程,因为只有他是和客户打交道的) oracle中的servier process拿到SQL 语句时,他认识吗,是认识的。但是他要把这条SQL语句变成他自己能理解的东西。也就是SQL语句的执行过程。 SQL语句的执行过程:(selec语句) -------生成serverprocess -------检查语法(server process) -------语义解析(row cache) -------生成执行计划,这个工作还是server process完成的。 --------执行SQL,还是server process带着你去找。 --------把数据返回给用户(还是server process完成的) 到这个时候,内存在干些什么事呢,SGA里面都有什么东西; 我们的执行计划要存在一个地方啊,而这个地方就就library cache。 Shared pool中还有free块,此时shared pool已经被我们的大管家(server process )忙完了。但我们的大管家继续忙。 此时就去忙 db_buffer_cache,我们拿着执行计划去db_buffer_cache中去寻找students文件的第244号块,如果server process发现没有所找的数据,所以得去数据文件中读取数据,读到db_buffer_cache中, 以备后续的用户读。 如果有我找的数据,直接从内存(db_buffer_cache)中读取,此时server process就把数据返回给用户
刚刚我们看到的是一条查询语句,现在我们来看一条更新语句(update student set name=‘tom’ where id =1022;)
SQL语句的执行过程(update) 1)生成了server process 2)检查语法(library cache) 4)语义解析(row cache)(server process) 3)生成执行计划 4)执行SQL语句,我要改students文件中第244号块文件中id为1022的人,比如他的名字叫JACK,如果发现db_buffer_cache中id=1022名字叫JACK的人,我们就直接修改他的名字为tom,没有的话还是从数据文件中读取244号块中名字为JACK的数据,缓存到db_buffer_cache中,此时完全一样的把244号块缓存到了db_buffer_cache中,名字为JACK,然后我们就要把JACK修改为tom;修改的这个动作记录在redo log buffer中,commit,此时的内存数据和dbf数据是不一致的。而这个时候DBWR进程就会把servier process修改好的数据写到磁盘中的数据文件中。(也就是平时所说的刷到了数据文件中) 而在修改之前我们在undo段中存放一份前镜像,因为在没有commit的时候,数据块头部会标记未提交,其他用户读的时候就到undo中读,当我commit的时候,会在数据块头部会标记已提交,我就在db_buffer_cache中读取了。 如果此时有这样一种现象,假如我修改好了数据,但是还没有来得及提交,突然断电了。像这种情况的话也不必惊慌。因为我能的redo log中记录了一些操作: 比如:1》记录了把244号块从数据文件写到db_buffer_cache中的过程 2》记录了把244号块写到了undo中 3》DBWR将SGA中的赃块写到了数据文件中的过程。 分析:突然断电了,也就是我们的SGA不存在了,此时就要进行实例恢复了,在online redo log中进行一条一条的读日志,一直到恢复好日志的最后一行。不管是有commit或者是没有commit的,系统都会自动的进行rollback,也就是说将断电之前的操作进行重新做一遍。此时我们只需要从undo中找到前镜像,然后到内存中进行修改,JACK---->tom!然后数据文件的也同步。 5)把修改后的数据返回给客户。 补充: commit的时候,oracle并没有将数据同步到硬盘中,为什么呢??oracle是怎么干的呢? 我们的SGA中有日志缓冲区,当我commit的时候,oracle就把我在db_buffer_cache中的操作给记录下来,他所记录什么时间,什么人,修改了哪个块,修改了多少?存放在log_buffer_cache中。 如果此时突然突然断电,咱们在244号块中修改的数据就白改了,但是我在commit之前把log_buffer中的记录写到了硬盘中的 online redo_log_files中,同样是什么人什么时间修改了什么,修改了多少?
DBWR这个进程,不管有没有commit,都把db_buffer_cache中的数据同步到数据文件中。
|
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30606702/viewspace-2058419/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30606702/viewspace-2058419/
本文详细介绍了Oracle数据库中SQL语句的执行流程,包括查询与更新语句的处理过程、内存结构的作用及其与硬盘交互的方式,同时深入探讨了Oracle如何确保数据的一致性和可靠性。
&spm=1001.2101.3001.5002&articleId=100374373&d=1&t=3&u=3334e02a72d54914afc6a44d50ff03b8)
806

被折叠的 条评论
为什么被折叠?



