解析一条Update语句

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值