oracle执行语句流程疑问

时间:2022-06-09 08:18:47
各位大大,我学习oracle体系之后,发现对oracle整体工作流程并不是很清楚,有谁能帮忙详细 描述一下当server进程从user进程获取到执行的语句后的完整工作流程吗?以一条查询语句和update语句为例子,下面是我目前能总结出来的:
1.当server获取到SQL时,首先进入到shared pool,根据SQL语句计算出ASC码来查找library cache里的执行计划链(library cache:mutex x),如果查到对应的handle,则获取该执行计划所在的内存地址,得到该执行计划,否则执行硬解析,执行硬解析则会先访问空闲空间链表,获取空闲的内存,生成执行计划后将该内存地址挂到前面查询的执行计划链里,以便下次能够查到,硬解析里需要执行语法检查、语义检查等等。
2.server进程然后在database buffer cache 里查找需要的数据库,首先根据ASC码查找对应的cbc(cache buffer chain),如果查询到则根据chain上的内存地址获取到内存块数据,如果查询不到则从数据文件里获取数据块,先访问cache buffer lru chains找到可用的内存,然后将数据文件的数据块加载到内存中,获取数据并挂在cbc上,如果SQL语句是UPDATE语句,则会先记录redo log buffer,然后数据块的更改并将数据块挂在脏块链表上,并将更改前的数据放到undo buffer cache里,等待DBWR进程写入到数据文件里,同时如果发起COMMIT,LGWR进程将redo log buffer写入到log redo。

上面写的很明显还要很多不顺畅的流程或者没描述清楚的,比如当server进程获取到执行计划后需要去database buffer cache里读数据块,那么此时读数据块需要的ASC码是根据什么计算出来的?如果是UPDATE语句的话,那么读到cbc上的数据块后更改数据后变为数据脏块挂在脏块链表上,那么另一个server执行查询语句查询数据要保证读一致性,必然是在undo里查询,这个查询是怎么判断出来的?是不是在查询完cbc后还要查询脏块链表?如果查询的话查询数据的筛选连接排序等等都在哪里处理?等等等等,作为半吊子的我对许多进程的细节都还不能完全清楚,希望有大大来补充一下,如果能完善出这个流程,相信对后来看到这个帖子的小白来说更能提高对数据库的理解~
希望各位大大给予指点~~~ oracle执行语句流程疑问oracle执行语句流程疑问oracle执行语句流程疑问

8 个解决方案

#1


你的问题略显乱!

回答一个:
那么另一个server执行查询语句查询数据要保证读一致性,必然是在undo里查询,这个查询是怎么判断出来的?

当一个查询提交时,当前的 scn 会随着查询语句一起被提交,这里其他的会话不断在更新数据,即 scn 在不断增长,比这个 scn 大的数据不会被查询出来,只能查小的或相同的;

#2


引用 1 楼 wmxcn2000 的回复:
你的问题略显乱!

回答一个:
那么另一个server执行查询语句查询数据要保证读一致性,必然是在undo里查询,这个查询是怎么判断出来的?

当一个查询提交时,当前的 scn 会随着查询语句一起被提交,这里其他的会话不断在更新数据,即 scn 在不断增长,比这个 scn 大的数据不会被查询出来,只能查小的或相同的;

这个原理我是知道的,可是server进程是如何去工作的?它要查找数据不是得去先根据ASC码找CBC吗?这个ASC码是怎么计算出来的?如果一个内存块变脏了还会不会在CBC上?还是说脏块地址只挂在脏块链上?如果查找到块过新需要去找undo,那么undo内存块应该也有新的地址,如果是通过某个链去找的话那么这个是通过哪个链去找的?这个查找的ASC码是从哪里怎么获得的?
我的问题其实是想梳理清楚整个server工作流程,但是因为整个流程比较复杂,我只能先将我的理解描述出来,因为理解不够透彻所以章法不够,有断节无法连贯,所以只能选择将一部分断节(很显然我的描述还有很多断节没有列举出来)描述出来做个引子让大大们帮助补充一下~
求解答~

#3


希望看到的朋友们都可以对我的描述进行讨论,哪里不正确或者描述不恰当都欢迎指正,我逐渐完善~希望可以学到更多东西~
谢谢~

#4


楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

#5


引用 4 楼 LHDZ_BJ 的回复:
楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

#6


引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

#7


引用 6 楼 LHDZ_BJ 的回复:
Quote: 引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

很感谢你的回答,虽然接触数据库时间比较短,还要许多都不懂,但是我会继续探索学习~也希望有一天自己也有能力为别人解惑,可以将我的知识分享给其他人~ oracle执行语句流程疑问

#8


引用 7 楼 u010412440 的回复:
Quote: 引用 6 楼 LHDZ_BJ 的回复:

Quote: 引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

很感谢你的回答,虽然接触数据库时间比较短,还要许多都不懂,但是我会继续探索学习~也希望有一天自己也有能力为别人解惑,可以将我的知识分享给其他人~ oracle执行语句流程疑问


嗯,加油,你一定可以。

#1


你的问题略显乱!

回答一个:
那么另一个server执行查询语句查询数据要保证读一致性,必然是在undo里查询,这个查询是怎么判断出来的?

当一个查询提交时,当前的 scn 会随着查询语句一起被提交,这里其他的会话不断在更新数据,即 scn 在不断增长,比这个 scn 大的数据不会被查询出来,只能查小的或相同的;

#2


引用 1 楼 wmxcn2000 的回复:
你的问题略显乱!

回答一个:
那么另一个server执行查询语句查询数据要保证读一致性,必然是在undo里查询,这个查询是怎么判断出来的?

当一个查询提交时,当前的 scn 会随着查询语句一起被提交,这里其他的会话不断在更新数据,即 scn 在不断增长,比这个 scn 大的数据不会被查询出来,只能查小的或相同的;

这个原理我是知道的,可是server进程是如何去工作的?它要查找数据不是得去先根据ASC码找CBC吗?这个ASC码是怎么计算出来的?如果一个内存块变脏了还会不会在CBC上?还是说脏块地址只挂在脏块链上?如果查找到块过新需要去找undo,那么undo内存块应该也有新的地址,如果是通过某个链去找的话那么这个是通过哪个链去找的?这个查找的ASC码是从哪里怎么获得的?
我的问题其实是想梳理清楚整个server工作流程,但是因为整个流程比较复杂,我只能先将我的理解描述出来,因为理解不够透彻所以章法不够,有断节无法连贯,所以只能选择将一部分断节(很显然我的描述还有很多断节没有列举出来)描述出来做个引子让大大们帮助补充一下~
求解答~

#3


希望看到的朋友们都可以对我的描述进行讨论,哪里不正确或者描述不恰当都欢迎指正,我逐渐完善~希望可以学到更多东西~
谢谢~

#4


楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

#5


引用 4 楼 LHDZ_BJ 的回复:
楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

#6


引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

#7


引用 6 楼 LHDZ_BJ 的回复:
Quote: 引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

很感谢你的回答,虽然接触数据库时间比较短,还要许多都不懂,但是我会继续探索学习~也希望有一天自己也有能力为别人解惑,可以将我的知识分享给其他人~ oracle执行语句流程疑问

#8


引用 7 楼 u010412440 的回复:
Quote: 引用 6 楼 LHDZ_BJ 的回复:

Quote: 引用 5 楼 com_jia的回复:
Quote: 引用 4 楼 LHDZ_BJ 的回复:

楼主,还不错的,加油。
1、楼主说的ASC码,应该是HASH值,就是进行HASH运算后得出的值。
2、获取数据块的HASH值,是根据数据块的地址算出来的。
3、update会话修改数据块后,如果已commit,那么,当其他会话读取该数据块时,会比较查询开始时的SCN和该块的SCN,如果该块的SCN大于查询的SCN,会通过UNDO信息回滚该块,直到产生SCN小于查询SCN的前影像。如果该块的SCN小于查询SCN,直接读取该块,不会发生回滚。如果还没commit,那么,其他会话读取该块时,也会发生回滚。回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置。
4、数据的筛选排序等操作时在server进程的私有内存空间或磁盘上进行,也就是通常所说的PGA中。
5、数据块被改写后,会挂到脏数据缓存链上,被写出后,该缓冲块的缓冲头会回到数据缓冲链上,但具体什么位置,会有一定的算法,这样,这个块还可以被其他会话使用,满足一定条件后,会返还到空闲缓冲链上,这时,可以再被其他会话使用。

十分感谢你的解惑,本来感觉已经对这个帖子不抱任何希望了,没想到可以获得这么有用的回答,我会继续学习探索,希望有一天可以搞清楚这些东西~ oracle执行语句流程疑问
还有一个问题就是看到这句话“回滚发生时,会从数据块的头部获取到开始回滚的UNDO记录的起始位置”,这个获取的起始位置是什么SCN还是内存地址或者物理地址?
如果是SCN怎么查找?我感觉数据库大部分都是根据内存地址或者数据块物理地址来查数据的,使用SCN我还没见过~
如果是内存地址的话那么也就是说每个内存块都会存有其对应的前镜像的内存位置?
如果是UNDO前镜像块的物理地址,也就是说每个数据块更改后会保存这次修改的前镜像物理位置信息,需要查找前镜像时再根据物理地址计算一下HASH然后再去数据缓冲链上查找数据?
大大~希望在闲暇之时帮我解惑~ oracle执行语句流程疑问

这个起始位置是undo记录在回滚段中的位置。每个数据块头部会存储操作这个块的事务的信息,回滚也是从事务的角度进行。当会话开始一个事务前,会先获取某个回滚段的槽号,以存储事务产生的undo记录,这个槽号也是这个事务的号,这也为今后的事务操作提供了起始线索。事务的undo空间,也就是extents,是通过地址连接的链表,所以,要回滚某个事务,只需要从头开始沿着这个链表执行所有的回滚记录即可。看似并行的事务,内部其实部分是串行,每个事务结束时,会获取一个独一无二的scn号,并将其写到数据块的头部,而其他商业库的锁和事务机制是通过内存实现的,这也是oracle库的独特之处。当然,也有例外,那就扯远了,这里不赘述,希望我的回答能帮到你。

很感谢你的回答,虽然接触数据库时间比较短,还要许多都不懂,但是我会继续探索学习~也希望有一天自己也有能力为别人解惑,可以将我的知识分享给其他人~ oracle执行语句流程疑问


嗯,加油,你一定可以。