您的位置:首页 > 其它

解析一条Update语句

2016-12-05 16:02 113 查看
1. [oracle@centos6 ~]$ sqlplus test/oracle@orcl

2. SQL> update t set name='AAAAA' where id=1;

3.SQL> commit;       

4.exit

一. sqlplus test/oracle@orcl

1. 客户端sqlplus请求连接,监听接收客户端的TCP连接,并获取客户端发送过来的TNS数据包

2. 监听进程打开与子进程通信的通道,同时fork一个子进程,称为'监听子进程1',然后监听进程等待直至子进程1结束。

3. 监听子进程1 fork出子进程2

4. 完成上面一步,监听子进程1马上退出并结束子进程1

5. 子进程2收集本进程所在的ip地址,主机名,进程号等信息,并把子进程2重命名为server process(也叫作前台进程或服务器进程),申请占用一小块pga内存

6. 前台进程把主机名,Ip地址,进程号发给监听进程

7. 监听进程收到前台进程的信息,并返回客户端的信息(用户名密码,环境变量等)给前台进程。

8. 前台进程查询user$,profile$等数据字典,校验用户名密码是否合法,如果用户名密码错误就报错用户名密码无效,否则就与客户端进行交互

9. 客户端收到前台进程的消息与之交互,整个连接创建完成

二. update t set name=''AAAAA' where id=1

1. server process把sql语句拿到共享池的Library cache里面,首先将sql的每个字符(包括空格)转化成ASCII码,再拿这个ASCII码通过hash函数生成一个sql_hash值,oracle拿这个hash值去扫描hash bucktes,找到对应的backet之后,oracle就沿着bucket取搜索object handle链,在这个Object handel上存有sql的文本,如果和我们执行的sql一模一样,

说明这条sql已经被缓存在共享池中了,这个过程就是软解析。

如果通过上面的方式在object handle链上没有找到这条sql的文本,说明sql不在共享池中,接下来就要进行硬解析。

2.首先是语法的检查,即sql本身的写法有没有问题,其次是语义的检查,即通过dictionary cache中的数据字典判断sql语句操作的对象是否存在,如果有就直接从rowcache中取,如果没有需要到buffer cahce中取,buffer cache中如果也没有就需要先从数据文件中取出相关字典缓存到buffer cache里面,再取到row cache中,然后是权限的检查,同样是通过dictionary cache中的数据字典进行,最后根据oracle的统计信息生成执行计划,并缓存在Library
cache里面。如果有大量的硬解析,会消耗cpu和占用共享池的空间。

3.生成执行计划后,server process把修改后的值拷贝到PGA中,开始执行update。

4.server process寻找被修改的数据块,如果被修改的块不在buffer cache中,server process需要到数据文件中将目标数据块读到buffer cache中,此时为物理读。

此时修改前的值在buffer cache中,修改后的值在server process pga中。

5.要把aaaaa改为AAAAA,oracle将修改前的值和修改后的值拷贝到redo log buffer中,同时在buffer cache中拷贝一个数据块的undo block。

6.发出commit命令,LGWR把log buffer中的数据写到Log file里面

7.如果发生了检查点操作,就会触发dbwr写数据,把修改后的值写到数据文件。修改前的值放到undo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: