当前位置:首页 » 编程语言 » sql执行原理

sql执行原理

发布时间: 2022-05-25 14:55:18

sql存储过程是怎么执行的(是执行过程)谢了

就像你调用方法一样嘛
通过调用
exec
存储过程名
参数名1,参数名2,.....
进入存储过程,根据存储过程编写语句顺序执行

㈡ SQL SERVER 索引的工作原理

SQL 当一个新表被创建之时,系统将在磁盘中分配一段以8K为单位的连续空间,当字段的值从内存写入磁盘时,就在这一既定空间随机保存,当一个8K用完的时候, SQLS指针会自动分配一个8K的空间。这里,每个8K空间被称为一个数据页(Page),又名页面或数据页面,并分配从0-7的页号,每个文件的第0页记录引导信息,叫文件头(File header);每8个数据页(64K)的组合形成扩展区(Extent),称为扩展。全部数据页的组合形成堆(Heap)。
SQLS 规定行不能跨越数据页,所以,每行记录的最大数据量只能为8K。这就是char和varchar这两种字符串类型容量要限制在8K以内的原因,存储超过 8K的数据应使用text类型,实际上,text类型的字段值不能直接录入和保存,它只是存储一个指针,指向由若干8K的文本数据页所组成的扩展区,真正的数据正是放在这些数据页中。
页面有空间页面和数据页面之分。当一个扩展区的8个数据页中既包含了空间页面又包括了数据或索引页面时,称为混合扩展(Mixed Extent),每张表都以混合扩展开始;反之,称为一致扩展专门保存数据及索引信息。表被创建之时,SQLS在混合扩展中为其分配至少一个数据页面,随着数据量的增长,SQLS可即时在混合扩展中分配出7个页面,当数据超过8个页面时,则从一致扩展中分配数据页面。
空间页面专门负责数据空间的分配和管理,包括:PFS页面(Page free space):记录一个页面是否已分配、位于混合扩展还是一致扩展以及页面上还有多少可用空间等信息;GAM页面(Global allocation map)和SGAM页面(Secodary global allocation map):用来记录空闲的扩展或含有空闲页面的混合扩展的位置。SQLS综合利用这三种类型的页面文件
在必要时为数据表创建新空间;数据页或索引页则专门保存数据及索引信息,SQLS使用4种类型的数据页面来管理表或索引:它们是IAM页、数据页、文本/图像页和索引页。
在WINDOWS 中,我们对文件执行的每一步操作,在磁盘上的物理位置只有系统(system)才知道;SQL SERVER沿袭了这种工作方式,在插入数据的过程中,不但每个字段值在数据页面中的保存位置是随机的,而且每个数据页面在“堆”中的排列位置也只有系统(system)才知道。这是为什么呢?众所周知,OS 之所以能管理DISK,是因为在系统启动时首先加载了文件分配表:FAT(File Allocation Table),正是由它管理文件系统并记录对文件的一切操作,系统才得以正常运行;同理,作为管理系统级的SQL
SERVER,也有这样一张类似FAT的表存在,它就是索引分布映像页:IAM(Index Allocation Map)。
IAM的存在,使SQLS对数据表的物理管理有了可能。
IAM 页从混合扩展中分配,记录了8个初始页面的位置和该扩展区的位置,每个IAM页面能管理512,000个数据页面,如
果数据量太大,SQLS也可以增加更多的IAM页,可以位于文件的任何位置。第一个IAM页被称为FirstIAM,其中记录了以
后的IAM页的位置。
数据页和文本/图像页互反,前者保存非文本/图像类型的数据,因为它们都不超过8K的容量,后者则只保存超过8K容
量的文本或图像类型数据。而索引页顾名思义,保存的是与索引结构相关的数据信息。了解页面的问题有助我们下
一步准确理解SQLS维护索引的方式,如页拆分、填充因子等。

二、索引的基本概念
什么是索引呢?索引是一种特殊类型的数据库对象,它与表有着密切的联系。
索引是为检索而存在的。如一些书籍的末尾就专门附有索引,指明了某个关键字在正文中的出现的页码位置,方便我们查找,但大多数的书籍只有目录,目录不是索引,只是书中内容的排序,并不提供真正的检索功能。可见建立索引要单独占用空间;索引也并不是必须要建立的,它们只是为更好、更快的检索和定位关键字而存在。
再进一步说,我们要在图书馆中查阅图书,该怎么办呢?图书馆的前台有很多叫做索引卡片柜的小柜子,里面分了若干的类别供我们检索图书,比如你可以用书名的笔画顺序或者拼音顺序作为查找的依据,你还可以从作者名的笔画顺序或拼音顺序去查询想要的图书,反正有许多检索方式,但有一点很明白,书库中的书并没有按照这些卡片柜中的顺序排列——虽然理论上可以这样做,事实上,所有图书的脊背上都人工的粘贴了一个特定的编号①,它们是以这个顺序在排列。索引卡片中并没有指明这本书摆放在书库中的第几个书架的第几本,仅仅指明了这个特定的编号。管理员则根据这一编号将请求的图书返回到读者手中。这是很形象的例子,以下的讲解将会反复用到它。
SQLS 在安装完成之后,安装程序会自动创建master、model、tempdb等几个特殊的系统数据库,其中master是SQLS的
主数据库,用于保存和管理其它系统数据库、用户数据库以及SQLS的系统信息,它在SQLS中的地位与WINDOWS下的注册表相当。
master中有一个名为sysindexes的系统表,专门管理索引。SQLS查询数据表的操作都必须用到它,毫无疑义,它是本文主角之一。查看一张表的索引属性,可以在查询分析器中使用以下命令:select * from sysindexes where id=object_id(‘tablename’);而要查看表的索引所占空间的大小,可以使用系统存储过程命令:sp_spaceused tablename,其中参数tablename为被索引的表名。

三、平衡树
如果你通过书后的索引知道了一个关键字所在的页码,你有可能通过随机的翻寻,最终到达正确的页码。但更科学更快捷的方法是:首先把书翻到大概二分之一的位置,如果要找的页码比该页的页码小,就把书向前翻到四分之一处,否则,就把书向后翻到四分之三的地方,依此类推,把书页续分成更小的部分,直至正确的页码。这叫“两分法”,微软在官方教程MOC里另有一种说法:叫B树(B-Tree,Balance Tree),即平衡树。
一个表索引由若干页面组成,这些页面构成了一个树形结构。B 树由“根”(root)开始,称为根级节点,它通过指向另外两个页,把一个表的记录从逻辑上分成两个部分:“枝”—--非叶级节点(Non-Leaf Level);而非叶级节点又分别指向更小的部分:“叶”——叶级节点(Leaf Level)。根节点、非叶级节点和叶级节点都位于索引页中,统称为索引节点,属于索引页的范筹。这些“枝”、“叶”最终指向了具体的数据页(Page)。在根级节点和叶级节点之间的叶又叫数据中间页。
“根”(root)对应了sysindexes表的Root字段,其中记载了非叶级节点的物理位置(即指针);非叶级节点位于根
节点和叶节点之间,记载了指向叶级节点的指针;而叶级节点则最终指向数据页。这就是“平衡树”。

四、聚集索引和非聚集索引
从形式上而言,索引分为聚集索引(Clustered Indexes)和非聚集索引(NonClustered Indexes)。
聚集索引相当于书籍脊背上那个特定的编号。如果对一张表建立了聚集索引,其索引页中就包含着建立索引的列的值(下称索引键值),那么表中的记录将按照该索引键值进行排序。比如,我们如果在“姓名”这一字段上建立了聚集索引,则表中的记录将按照姓名进行排列;如果建立了聚集索引的列是数值类型的,那么记录将按照该键值的数值大小来进行排列。
非聚集索引用于指定数据的逻辑顺序,也就是说,表中的数据并没有按照索引键值指定的顺序排列,而仍然按照插入记录时的顺序存放。其索引页中包含着索引键值和它所指向该行记录在数据页中的物理位置,叫做行定位符(RID:Row ID)。好似书后面的的索引表,索引表中的顺序与实际的页码顺序也是不一致的。而且一本书也许有多个索引。比如主题索引和作者索引。
SQL Server在默认的情况下建立的索引是非聚集索引,由于非聚集索引不对表中的数据进行重组,而只是存储索引键
值并用一个指针指向数据所在的页面。一个表如果没有聚集索引时,理论上可以建立249个非聚集索引。每个非聚集索引提供访问数据的不同排序顺序。

㈢ mysql数据库 sql语句执行的原理

简单点说:
1. 先执行联接。外联接(left join,right join,full join)分为3步:生成笛卡尔积;根据on语句筛选满足a.id=b.tid的行;补齐null行;
2. 根据where子句,再一次进行筛选出a.id=10的行;
3. 执行select子句,取出被请求的字段a.title和b.content

㈣ SQL语句执行流程与顺序原理解析

SQL语句执行流程与顺序原理解析
Oracle语句执行流程
第一步:客户端把语句发给服务器端执行
当我们在客户端执行SQL语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作,他的主要任务就是把客户端产生的一些SQL语句发送给服务器端。服务器进程从用户进程把信息接收到后, 在PGA 中就要此进程分配所需内存,存储相关的信息,如:在会话内存存储相关的登录信息等。
虽然在客户端也有一个数据库进程,但是,这个进程的作用跟服务器上的进程作用是不相同的,服务器上的数据库进程才会对SQL 语句进行相关的处理。不过,有个问题需要说明,就是客户端的进程跟服务器的进程是一一对应的。也就是说,在客户端连接上服务器后,在客户端与服务器端都会形成一个进程,客户端上的我们叫做客户端进程,而服务器上的我们叫做服务器进程。
第二步:语句解析
当客户端把SQL语句传送到服务器后,服务器进程会对该语句进行解析。这个解析的工作是在服务器端所进行的,解析动作又可分为很多小动作。
1)查询高速缓存(library cache)
服务器进程在接到客户端传送过来的SQL语句时,不会直接去数据库查询。服务器进程把这个SQL语句的字符转化为ASCII等效数字码,接着这个ASCII码被传递给一个HASH函数,并返回一个hash值,然后服务器进程将到shared pool中的library cache(高速缓存)中去查找是否存在相同的hash值。如果存在,服务器进程将使用这条语句已高速缓存在SHARED POOL的library cache中的已分析过的版本来执行,省去后续的解析工作,这便是软解析。若调整缓存中不存在,则需要进行后面的步骤,这便是硬解析。硬解析通常是昂贵的操作,大约占整个SQL执行的70%左右的时间,硬解析会生成执行树,执行计划,等等。
所以,采用高速数据缓存的话,可以提高SQL 语句的查询效率。其原因有两方面:一方面是从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高,另一方面也是因为避免语句解析而节省了时间。
不过这里要注意一点,这个数据缓存跟有些客户端软件的数据缓存是两码事。有些客户端软件为了提高查询效率,会在应用软件的客户端设置数据缓存。由于这些数据缓存的存在,可以提高客户端应用软件的查询效率。但是,若其他人在服务器进行了相关的修改,由于应用软件数据缓存的存在,导致修改的数据不能及时反映到客户端上。从这也可以看出,应用软件的数据缓存跟数据库服务器的高速数据缓存不是一码事。
2)语句合法性检查(data dict cache)
当在高速缓存中找不到对应的SQL语句时,则服务器进程就会开始检查这条语句的合法性。这里主要是对SQL语句的语法进行检查,看看其是否合乎语法规则。如果服务器进程认为这条SQL语句不符合语法规则的时候,就会把这个错误信息反馈给客户端。在这个语法检查的过程中,不会对SQL语句中所包含的表名、列名等等进行检查,只是检查语法。
3)语言含义检查(data dict cache)
若SQL 语句符合语法上的定义的话,则服务器进程接下去会对语句中涉及的表、索引、视图等对象进行解析,并对照数据字典检查这些对象的名称以及相关结构,看看这些字段、表、视图等是否在数据库中。如果表名与列名不准确的话,则数据库会就会反馈错误信息给客户端。
所以,有时候我们写select语句的时候,若语法与表名或者列名同时写错的话,则系统是先提示说语法错误,等到语法完全正确后再提示说列名或表名错误。
4)获得对象解析锁(control structer)
当语法、语义都正确后,系统就会对我们需要查询的对象加锁。这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象的结构发生改变。
5)数据访问权限的核对(data dict cache)
当语法、语义通过检查之后,客户端还不一定能够取得数据,服务器进程还会检查连接用户是否有这个数据访问的权限。若用户不具有数据访问权限的话,则客户端就不能够取得这些数据。要注意的是数据库服务器进程先检查语法与语义,然后才会检查访问权限。
6)确定最佳执行计划
当语法与语义都没有问题权限也匹配,服务器进程还是不会直接对数据库文件进行查询。服务器进程会根据一定的规则,对这条语句进行优化。在执行计划开发之前会有一步查询转换,如:视图合并、子查询解嵌套、谓语前推及物化视图重写查询等。为了确定采用哪个执行计划,Oracle还需要收集统计信息确定表的访问联结方法等,最终确定可能的最低成本的执行计划。
不过要注意,这个优化是有限的。一般在应用软件开发的过程中,需要对数据库的sql语句进行优化,这个优化的作用要大大地大于服务器进程的自我优化。
当服务器进程的优化器确定这条查询语句的最佳执行计划后, 就会将这条SQL语句与执行计划保存到数据高速缓存(library cache)。如此,等以后还有这个查询时,就会省略以上的语法、语义与权限检查的步骤,而直接执行SQL语句,提高SQL语句处理效率。
第三步:绑定变量赋值
如果SQL语句中使用了绑定变量,扫描绑定变量的声明,给绑定变量赋值,将变量值带入执行计划。若在解析的第一个步骤,SQL在高速缓冲中存在,则直接跳到该步骤。
第四步:语句执行
语句解析只是对SQL语句的语法进行解析,以确保服务器能够知道这条语句到底表达的是什么意思。等到语句解析完成之后,数据库服务器进程才会真正的执行这条SQL语句。
对于SELECT语句:
1)首先服务器进程要判断所需数据是否在db buffer存在,如果存在且可用,则直接获取该数据而不是从数据库文件中去查询数据,同时根据LRU 算法增加其访问计数;
2)若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲区中(buffer cache)。
其中,若数据存在于db buffer,其可用性检查方式为:查看db buffer块的头部是否有事务,如果有事务,则从回滚段中读取数据;如果没有事务,则比较select的scn和db buffer块头部的scn,如果前者小于后者,仍然要从回滚段中读取数据;如果前者大于后者,说明这是一非脏缓存,可以直接读取这个db buffer块的中内容。
对于DML语句(insert、delete、update):
1)检查所需的数据库是否已经被读取到缓冲区缓存中。如果已经存在缓冲区缓存,则直接执行步骤3;
2)若所需的数据库并不在缓冲区缓存中,则服务器将数据块从数据文件读取到缓冲区缓存中;
3)对想要修改的表取得的数据行锁定(Row Exclusive Lock),之后对所需要修改的数据行取得独占锁;
4)将数据的Redo记录复制到redo log buffer;
5)产生数据修改的undo数据;
6)修改db buffer;
7)dbwr将修改写入数据文件;
其中,第2步,服务器将数据从数据文件读取到db buffer经经历以下步骤:
1)首先服务器进程将在表头部请求TM锁(保证此事务执行过程其他用户不能修改表的结构),如果成功加TM锁,再请求一些行级锁(TX锁),如果TM、TX锁都成功加锁,那么才开始从数据文件读数据。
2)在读数据之前,要先为读取的文件准备好buffer空间。服务器进程需要扫描LRU list寻找free db buffer,扫描的过程中,服务器进程会把发现的所有已经被修改过的db buffer注册到dirty list中。如果free db buffer及非脏数据块缓冲区不足时,会触发dbwr将dirty buffer中指向的缓冲块写入数据文件,并且清洗掉这些缓冲区来腾出空间缓冲新读入的数据。
3)找到了足够的空闲buffer,服务器进程将从数据文件中读入这些行所在的每一个数据块(db block)(DB BLOCK是ORACLE的最小操作单元,即使你想要的数据只是DB BLOCK中很多行中的一行或几行,ORACLE也会把这个DB BLOCK中的所有行都读入Oracle DB BUFFER中)放入db buffer的空闲的区域或者覆盖已被挤出LRU list的非脏数据块缓冲区,并且排列在LRU列表的头部,也就是在数据块放入db buffer之前也是要先申请db buffer中的锁存器,成功加锁后,才能读数据到db buffer。
若数据块已经存在于db buffer cache(有时也称db buffer或db cache),即使在db buffer中找到一个没有事务,而且SCN比自己小的非脏缓存数据块,服务器进程仍然要到表的头部对这条记录申请加锁,加锁成功才能进行后续动作,如果不成功,则要等待前面的进程解锁后才能进行动作(这个时候阻塞是tx锁阻塞)。
在记redo日志时,其具体步骤如下:
1)数据被读入到db buffer后,服务器进程将该语句所影响的并被读入db buffer中的这些行数据的rowid及要更新的原值和新值及scn等信息从PGA逐条的写入redo log buffer中。在写入redo log buffer之前也要事先请求redo log buffer的锁存器,成功加锁后才开始写入。
2)当写入达到redo log buffer大小的三分之一或写入量达到1M或超过三秒后或发生检查点时或者dbwr之前发生,都会触发lgwr进程把redo log buffer的数据写入磁盘上的redo file文件中(这个时候会产生log file sync等待事件)。
3)已经被写入redo file的redo log buffer所持有的锁存器会被释放,并可被后来的写入信息覆盖,redo log buffer是循环使用的。Redo file也是循环使用的,当一个redo file写满后,lgwr进程会自动切换到下一redo file(这个时候可能出现log file switch(check point complete)等待事件)。如果是归档模式,归档进程还要将前一个写满的redo file文件的内容写到归档日志文件中(这个时候可能出现log file switch(archiving needed)。
在为事务建立undo信息时,其具体步骤如下:
1)在完成本事务所有相关的redo log buffer之后,服务器进程开始改写这个db buffer的块头部事务列表并写入scn(一开始scn是写在redo log buffer中的,并未写在db buffer)。
2)然后包含这个块的头部事务列表及scn信息的数据副本放入回滚段中,将这时回滚段中的信息称为数据块的“前映像”,这个“前映像”用于以后的回滚、恢复和一致性读。(回滚段可以存储在专门的回滚表空间中,这个表空间由一个或多个物理文件组成,并专用于回滚表空间,回滚段也可在其它表空间中的数据文件中开辟)。
在修改信息写入数据文件时,其具体步骤如下:
1)改写db buffer块的数据内容,并在块的头部写入回滚段的地址。
2)将db buffer指针放入dirty list。如果一个行数据多次update而未commit,则在回滚段中将会有多个“前映像”,除了第一个“前映像”含有scn信息外,其他每个"前映像"的头部都有scn信息和"前前映像"回滚段地址。一个update只对应一个scn,然后服务器进程将在dirty list中建立一条指向此db buffer块的指针(方便dbwr进程可以找到dirty list的db buffer数据块并写入数据文件中)。接着服务器进程会从数据文件中继续读入第二个数据块,重复前一数据块的动作,数据块的读入、记日志、建立回滚段、修改数据块、放入dirty list。
3)当dirty queue的长度达到阀值(一般是25%),服务器进程将通知dbwr把脏数据写出,就是释放db buffer上的锁存器,腾出更多的free db buffer。前面一直都是在说明oracle一次读一个数据块,其实oracle可以一次读入多个数据块(db_file_multiblock_read_count来设置一次读入块的个数)
当执行commit时,具体步骤如下:
1)commit触发lgwr进程,但不强制dbwr立即释放所有相应db buffer块的锁。也就是说有可能虽然已经commit了,但在随后的一段时间内dbwr还在写这条sql语句所涉及的数据块。表头部的行锁并不在commit之后立即释放,而是要等dbwr进程完成之后才释放,这就可能会出现一个用户请求另一用户已经commit的资源不成功的现象。
2)从Commit和dbwr进程结束之间的时间很短,如果恰巧在commit之后,dbwr未结束之前断电,因为commit之后的数据已经属于数据文件的内容,但这部分文件没有完全写入到数据文件中。所以需要前滚。由于commit已经触发lgwr,这些所有未来得及写入数据文件的更改会在实例重启后,由smon进程根据重做日志文件来前滚,完成之前commit未完成的工作(即把更改写入数据文件)。
3)如果未commit就断电了,因为数据已经在db buffer更改了,没有commit,说明这部分数据不属于数据文件。由于dbwr之前触发lgwr也就是只要数据更改,(肯定要先有log)所有dbwr在数据文件上的修改都会被先一步记入重做日志文件,实例重启后,SMON进程再根据重做日志文件来回滚。
其实smon的前滚回滚是根据检查点来完成的,当一个全部检查点发生的时候,首先让LGWR进程将redologbuffer中的所有缓冲(包含未提交的重做信息)写入重做日志文件,然后让dbwr进程将dbbuffer已提交的缓冲写入数据文件(不强制写未提交的)。然后更新控制文件和数据文件头部的SCN,表明当前数据库是一致的,在相邻的两个检查点之间有很多事务,有提交和未提交的。
当执行rollback时,具体步骤如下:
服务器进程会根据数据文件块和db buffer中块的头部的事务列表和SCN以及回滚段地址找到回滚段中相应的修改前的副本,并且用这些原值来还原当前数据文件中已修改但未提交的改变。如果有多个”前映像“,服务器进程会在一个“前映像”的头部找到“前前映像”的回滚段地址,一直找到同一事务下的最早的一个“前映像”为止。一旦发出了commit,用户就不能rollback,这使得commit后dbwr进程还没有全部完成的后续动作得到了保障。
第五步:提取数据
当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作。
从这整个查询处理过程中,我们在数据库开发或者应用软件开发过程中,需要注意以下几点:
一是要了解数据库缓存跟应用软件缓存是两码事情。数据库缓存只有在数据库服务器端才存在,在客户端是不存在的。只有如此,才能够保证数据库缓存中的内容跟数据库文件的内容一致。才能够根据相关的规则,防止数据脏读、错读的发生。而应用软件所涉及的数据缓存,由于跟数据库缓存不是一码事情,所以,应用软件的数据缓存虽然可以提高数据的查询效率,但是,却打破了数据一致性的要求,有时候会发生脏读、错读等情况的发生。所以,有时候,在应用软件上有专门一个功能,用来在必要的时候清除数据缓存。不过,这个数据缓存的清除,也只是清除本机上的数据缓存,或者说,只是清除这个应用程序的数据缓存,而不会清除数据库的数据缓存。
二是绝大部分SQL语句都是按照这个处理过程处理的。我们DBA或者基于Oracle数据库的开发人员了解这些语句的处理过程,对于我们进行涉及到SQL语句的开发与调试,是非常有帮助的。有时候,掌握这些处理原则,可以减少我们排错的时间。特别要注意,数据库是把数据查询权限的审查放在语法语义的后面进行检查的。所以,有时会若光用数据库的权限控制原则,可能还不能满足应用软件权限控制的需要。此时,就需要应用软件的前台设置,实现权限管理的要求。而且,有时应用数据库的权限管理,也有点显得繁琐,会增加服务器处理的工作量。因此,对于记录、字段等的查询权限控制,大部分程序涉及人员喜欢在应用程序中实现,而不是在数据库上实现。
Oracle SQL语句执行顺序
(8)SELECT (9) DISTINCT (11) <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE | ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
1)FROM:对FROM子句中的表执行笛卡尔积(交叉联接),生成虚拟表VT1。
2)ON:对VT1应用ON筛选器,只有那些使为真才被插入到TV2。
3)OUTER (JOIN):如果指定了OUTER JOIN(相对于CROSS JOIN或INNER JOIN),保留表中未找到匹配的行将作为外部行添加到VT2,生成TV3。如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表位置。
4)WHERE:对TV3应用WHERE筛选器,只有使为true的行才插入TV4。
5)GROUP BY:按GROUP BY子句中的列列表对TV4中的行进行分组,生成TV5。
6)CUTE|ROLLUP:把超组插入VT5,生成VT6。
7)HAVING:对VT6应用HAVING筛选器,只有使为true的组插入到VT7。
8)SELECT:处理SELECT列表,产生VT8。
9)DISTINCT:将重复的行从VT8中删除,产品VT9。
10)ORDER BY:将VT9中的行按ORDER BY子句中的列列表顺序,生成一个游标(VC10),生成表TV11,并返回给调用者。
以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句,将跳过相应的步骤。

㈤ Mybatis动态sql是做什么的都有哪些动态sql能简述一下动态sql的执行原理

摘要 1.动态SQL的概念

㈥ 我是菜鸟 求SQL数据库最基本原理

数据库就是一个仓库,以mssql为例,sqlserver是一个仓库管理员,里面分多个仓库,就是多个数据库.库里面分有多张表,存放各种数据,如数字,文本,图片,文件等.所谓的文件,在磁盘是二进制形式放着的,而在数据库里是在某个表里面的某个行的某个字段中.所以没有路径,但可以查询得到.只是查询等到的只是一个二进制的值.如果转换成磁盘文件,将这个二进制串写到磁盘上就行了.
sqlserver 只是个仓管员,数据库一般以2个文件存在,一个是库文件mdf,一个是日志文件ldf,这2个文件一般在C:\Program Files\Microsoft SQL Server\MSSQL\Data下面,你可以停止mssqlserver服务,把这2个文件COPY出来,到其它服务器上附加就行.也可以备份数据库再到其他服务器上还原.

㈦ Mysql的工作原理是什么

Mysql工作原理图

Mysql是由SQL接口,解析器,优化器,缓存,存储引擎组成的。

mysql原理图各个组件说明:

1. connectors

与其他编程语言中的sql语句进行交互,如phpjava等。

2. Management Serveices & Utilities

系统管理和控制工具

3. Connection Pool (连接池)

管理缓冲用户连接,线程处理等需要缓存的需求

4. SQL Interface (SQL接口)

接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface

5. Parser(解析器)

SQL命令传递到解析器的时候会被解析器验证和解析。

主要功能:

a .将SQL语句分解成数据结构,并将这个结构传递到后续步骤,后面SQL语句的传递和处理就是基于这个结构的

b. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的,语句将不会继续执行下去

6. Optimizer (查询优化器)

SQL语句在查询之前会使用查询优化器对查询进行优化(产生多种执行计划,最终数据库会选择最优化的方案去执行,尽快返会结果)他使用的是“选取-投影-联接”策略进行查询。

用一个例子就可以理解:select uid,name from user where gender = 1;

这个select查询先根据where语句进行选取,而不是先将表全部查询出来以后再进行gender过滤

这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤

将这两个查询条件联接起来生成最终查询结果.

7. Cache和Buffer (查询缓存)

如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。

这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等

8.Engine (存储引擎)

存储引擎是MySql中具体的与文件打交道的子系统。也是Mysql最具有特色的一个地方。

Mysql的存储引擎是插件式的。它根据MySql AB公司提供的文件访问层的一个抽象接口来定制一种文件访问机制(这种访问机制就叫存储引擎)

SQL语句执行过程

数据库通常不会被直接使用,而是由其他编程语言通过SQL语句调用mysql,由mysql处理并返回执行结果。那么Mysql接受到SQL语句后,又是如何处理

首先程序的请求会通过mysql的connectors与其进行交互,请求到处后,会暂时存放在连接池(connection pool)中并由处理器(Management Serveices & Utilities)管理。当该请求从等待队列进入到处理队列,管理器会将该请求丢给SQL接口(SQL Interface)。SQL接口接收到请求后,它会将请求进行hash处理并与缓存中的结果进行对比,如果完全匹配则通过缓存直接返回处理结果;否则,需要完整的走一趟流程:

(1)由SQL接口丢给后面的解释器(Parser),解释器会判断SQL语句正确与否,若正确则将其转化为数据结构。

(2)解释器处理完,便来到后面的优化器(Optimizer),它会产生多种执行计划,最终数据库会选择最优化的方案去执行,尽快返会结果。

(3)确定最优执行计划后,SQL语句此时便可以交由存储引擎(Engine)处理,存储引擎将会到后端的存储设备中取得相应的数据,并原路返回给程序。

注意点

(1)如何缓存查询数据

存储引擎处理完数据,并将其返回给程序的同时,它还会将一份数据保留在缓存中,以便更快速的处理下一次相同的请求。具体情况是,mysql会将查询的语句、执行结果等进行hash,并保留在cache中,等待下次查询。

(2)buffer与cache的区别

从mysql原理图可以看到,缓存那里实际上有buffer和cache两个,那它们之间的区别:简单的说就是,buffer是写缓存,cache是读缓存。

(3)如何判断缓存中是否已缓存需要的数据

这里可能有一个误区,觉得处理SQL语句的时候,为了判断是否已缓存查询结果,会将整个流程走一遍,取得执行结果后再与需要的进行对比,看看是否命中,并以此说,既然不管缓存中有没有缓存到查询内容,都要整个流程走一遍,那缓存的优势在哪?

其实并不是这样,在第一次查询后,mysql便将查询语句以及查询结果进行hash处理并保留在缓存中,SQL查询到达之后,对其进行同样的hash处理后,将两个hash值进行对照,如果一样,则命中,从缓存中返回查询结果;否则,需要整个流程走一遍。

㈧ SQL语句执行过程详解

SQL语句执行过程详解
一条sql,plsql的执行到底是怎样执行的呢?
一、SQL语句执行原理:
第一步:客户端把语句发给服务器端执行当我们在客户端执行 select 语句时,客户端会把这条 SQL 语句发送给服务器端,让服务器端的
进程来处理这语句。也就是说,Oracle 客户端是不会做任何的操作,他的主要任务就是把客户端产生
的一些 SQL 语句发送给服务器端。虽然在客户端也有一个数据库进程,但是,这个进程的作用跟服务器
上的进程作用事不相同的。服务器上的数据库进程才会对SQL 语句进行相关的处理。不过,有个问题需
要说明,就是客户端的进程跟服务器的进程是一一对应的。也就是说,在客户端连接上服务器后,在客户
端与服务器端都会形成一个进程,客户端上的我们叫做客户端进程;而服务器上的我们叫做服务器进程。
第二步:语句解析
当客户端把 SQL 语句传送到服务器后,服务器进程会对该语句进行解析。同理,这个解析的工作,
也是在服务器端所进行的。虽然这只是一个解析的动作,但是,其会做很多“小动作”。
1. 查询高速缓存(library cache)。服务器进程在接到客户端传送过来的 SQL 语句时,不
会直接去数据库查询。而是会先在数据库的高速缓存中去查找,是否存在相同语句的执行计划。如果在
数据高速缓存中,则服务器进程就会直接执行这个 SQL 语句,省去后续的工作。所以,采用高速数据缓
存的话,可以提高 SQL 语句的查询效率。一方面是从内存中读取数据要比从硬盘中的数据文件中读取
数据效率要高,另一方面,也是因为这个语句解析的原因。
不过这里要注意一点,这个数据缓存跟有些客户端软件的数据缓存是两码事。有些客户端软件为了
提高查询效率,会在应用软件的客户端设置数据缓存。由于这些数据缓存的存在,可以提高客户端应用软
件的查询效率。但是,若其他人在服务器进行了相关的修改,由于应用软件数据缓存的存在,导致修改的
数据不能及时反映到客户端上。从这也可以看出,应用软件的数据缓存跟数据库服务器的高速数据缓存
不是一码事。
2. 语句合法性检查(data dict cache)。当在高速缓存中找不到对应的 SQL 语句时,则服
务器进程就会开始检查这条语句的合法性。这里主要是对 SQL 语句的语法进行检查,看看其是否合乎
语法规则。如果服务器进程认为这条 SQL 语句不符合语法规则的时候,就会把这个错误信息,反馈给客
户端。在这个语法检查的过程中,不会对 SQL 语句中所包含的表名、列名等等进行 SQL 他只是语法
上的检查。
3. 语言含义检查(data dict cache)。若 SQL 语句符合语法上的定义的话,则服务器进程
接下去会对语句中的字段、表等内容进行检查。看看这些字段、表是否在数据库中。如果表名与列名不
准确的话,则数据库会就会反馈错误信息给客户端。所以,有时候我们写 select 语句的时候,若语法
与表名或者列名同时写错的话,则系统是先提示说语法错误,等到语法完全正确后,再提示说列名或表名
错误。
4. 获得对象解析锁(control structer)。当语法、语义都正确后,系统就会对我们需要查询
的对象加锁。这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象的结构发
生改变。
5. 数据访问权限的核对(data dict cache)。当语法、语义通过检查之后,客户端还不一定
能够取得数据。服务器进程还会检查,你所连接的用户是否有这个数据访问的权限。若你连接上服务器
的用户不具有数据访问权限的话,则客户端就不能够取得这些数据。有时候我们查询数据的时候,辛辛苦
苦地把 SQL 语句写好、编译通过,但是,最后系统返回个 “没有权限访问数据”的错误信息,让我们气
半死。这在前端应用软件开发调试的过程中,可能会碰到。所以,要注意这个问题,数据库服务器进程先
检查语法与语义,然后才会检查访问权限。
6. 确定最佳执行计划 ?。当语句与语法都没有问题,权限也匹配的话,服务器进程还是不会直接对
数据库文件进行查询。服务器进程会根据一定的规则,对这条语句进行优化。不过要注意,这个优化是有
限的。一般在应用软件开发的过程中,需要对数据库的 sql 语言进行优化,这个优化的作用要大大地大
于服务器进程的自我优化。所以,一般在应用软件开发的时候,数据库的优化是少不了的。当服务器进程
的优化器确定这条查询语句的最佳执行计划后,就会将这条 SQL 语句与执行计划保存到数据高速缓存
(library cache)。如此的话,等以后还有这个查询时,就会省略以上的语法、语义与权限检查的步骤,
而直接执行 SQL 语句,提高 SQL 语句处理效率。
第三步:语句执行
语句解析只是对 SQL 语句的语法进行解析,以确保服务器能够知道这条语句到底表达的是什么意
思。等到语句解析完成之后,数据库服务器进程才会真正的执行这条 SQL 语句。这个语句执行也分两
种情况。
一是若被选择行所在的数据块已经被读取到数据缓冲区的话,则服务器进程会直接把这个数据传递
给客户端,而不是从数据库文件中去查询数据。
若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲
区中(buffer cache)。
第四步:提取数据
当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,
在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给
用户端进程,从而完成整个查询动作。从这整个查询处理过程中,我们在数据库开发或者应用软件开发过
程中,需要注意以下几点:
一是要了解数据库缓存跟应用软件缓存是两码事情。数据库缓存只有在数据库服务器端才存在,在
客户端是不存在的。只有如此,才能够保证数据库缓存中的内容跟数据库文件的内容一致。才能够根据
相关的规则,防止数据脏读、错读的发生。而应用软件所涉及的数据缓存,由于跟数据库缓存不是一码事
情,所以,应用软件的数据缓存虽然可以提高数据的查询效率,但是,却打破了数据一致性的要求,有时候
会发生脏读、错读等情况的发生。所以,有时候,在应用软件上有专门一个功能,用来在必要的时候清除
数据缓存。不过,这个数据缓存的清除,也只是清除本机上的数据缓存,或者说,只是清除这个应用程序
的数据缓存,而不会清除数据库的数据缓存。
二是绝大部分 SQL 语句都是按照这个处理过程处理的。我们 DBA 或者基于 Oracle 数据库的
开发人员了解这些语句的处理过程,对于我们进行涉及到 SQL 语句的开发与调试,是非常有帮助的。有
时候,掌握这些处理原则,可以减少我们排错的时间。特别要注意,数据库是把数据查询权限的审查放在
语法语义的后面进行检查的。所以,有时会若光用数据库的权限控制原则,可能还不能满足应用软件权限
控制的需要。此时,就需要应用软件的前台设置,实现权限管理的要求。而且,有时应用数据库的权限管
理,也有点显得繁琐,会增加服务器处理的工作量。因此,对于记录、字段等的查询权限控制,大部分程
序涉及人员喜欢在应用程序中实现,而不是在数据库上实现。
DBCC DROPCLEANBUFFERS
从缓冲池中删除所有清除缓冲区。
DBCC FREEPROCCACHE
从过程缓存中删除所有元素。
DBCC FREESYSTEMCACHE
从所有缓存中释放所有未使用的缓存条目
SQL语句中的函数、关键字、排序等执行顺序:
1. FROM 子句返回初始结果集。
2. WHERE 子句排除不满足搜索条件的行。
3. GROUP BY 子句将选定的行收集到 GROUP BY 子句中各个唯一值的组中。
4. 选择列表中指定的聚合函数可以计算各组的汇总值。
5. 此外,HAVING 子句排除不满足搜索条件的行。
6. 计算所有的表达式;
7. 使用 order by 对结果集进行排序。
8. 查找你要搜索的字段。
二、SQL语句执行完整过程:
1.用户进程提交一个 sql 语句:
update temp set a=a*2,给服务器进程。
2.服务器进程从用户进程把信息接收到后,在 PGA 中就要此进程分配所需内存,存储相关的信息,如在会
话内存存储相关的登录信息等。
3.服务器进程把这个 sql 语句的字符转化为 ASCII 等效数字码,接着这个 ASCII 码被传递给一个
HASH 函数,并返回一个 hash 值,然后服务器进程将到shared pool 中的 library cache 中去查找是否存在相
同的 hash 值,如果存在,服务器进程将使用这条语句已高速缓存在 SHARED POOL 的library cache 中的已
分析过的版本来执行。
4.如果不存在,服务器进程将在 CGA 中,配合 UGA 内容对 sql,进行语法分析,首先检查语法的正确性,接
着对语句中涉及的表,索引,视图等对象进行解析,并对照数据字典检查这些对象的名称以及相关结构,并根据
ORACLE 选用的优化模式以及数据字典中是否存在相应对象的统计数据和是否使用了存储大纲来生成一个
执行计划或从存储大纲中选用一个执行计划,然后再用数据字典核对此用户对相应对象的执行权限,最后生成
一个编译代码。
5.ORACLE 将这条 sql 语句的本身实际文本、HASH 值、编译代码、与此语名相关联的任何统计数据
和该语句的执行计划缓存在 SHARED POOL 的 library cache中。服务器进程通过 SHARED POOL 锁存
器(shared pool latch)来申请可以向哪些共享 PL/SQL 区中缓存这此内容,也就是说被SHARED POOL 锁存
器锁定的 PL/SQL 区中的块不可被覆盖,因为这些块可能被其它进程所使用。
6.在 SQL 分析阶段将用到 LIBRARY
CACHE,从数据字典中核对表、视图等结构的时候,需要将数据
字典从磁盘读入 LIBRARY
CACHE,因此,在读入之前也要使用LIBRARY
CACHE 锁存器(library cache
pin,library cache lock)来申请用于缓存数据字典。 到现在为止,这个 sql 语句已经被编译成可执行的代码了,
但还不知道要操作哪些数据,所以服务器进程还要为这个 sql 准备预处理数据。
7.首先服务器进程要判断所需数据是否在 db buffer 存在,如果存在且可用,则直接获取该数据,同时根据
LRU 算法增加其访问计数;如果 buffer 不存在所需数据,则要从数据文件上读取首先服务器进程将在表头部
请求 TM 锁(保证此事务执行过程其他用户不能修改表的结构),如果成功加 TM 锁,再请求一些行级锁(TX
锁),如果 TM、TX 锁都成功加锁,那么才开始从数据文件读数据,在读数据之前,要先为读取的文件准备好
buffer 空间。服务器进程需要扫面 LRU list 寻找 free db buffer,扫描的过程中,服务器进程会把发现的所有
已经被修改过的 db buffer 注册到 dirty list 中, 这些 dirty buffer 会通过 dbwr 的触发条件,随后会被写出到
数据文件,找到了足够的空闲 buffer,就可以把请求的数据行所在的数据块放入到 db buffer 的空闲区域或者
覆盖已经被挤出 LRU list 的非脏数据块缓冲区,并排列在 LRU list 的头部,也就是在数据块放入 DB
BUFFER 之前也是要先申请 db buffer 中的锁存器,成功加锁后,才能读数据到 db buffer。
8.记日志 现在数据已经被读入到 db buffer 了,现在服务器进程将该语句所影响的并被读
入 db buffer 中的这些行数据的 rowid 及要更新的原值和新值及 scn 等信息从 PGA 逐条的写入 redo log
buffer 中。在写入 redo log buffer 之前也要事先请求 redo log buffer 的锁存器,成功加锁后才开始写入,当
写入达到 redo log buffer 大小的三分之一或写入量达到 1M 或超过三秒后或发生检查点时或者 dbwr 之前
发生,都会触发 lgwr 进程把 redo log buffer 的数据写入磁盘上的 redo file 文件中(这个时候会产生log file
sync 等待事件)
已经被写入 redofile 的 redo log buffer 所持有的锁存器会被释放,并可被后来的写入信息覆盖,
redo log buffer是循环使用的。Redo file 也是循环使用的,当一个 redo file 写满后,lgwr 进程会自动切换到
下一 redo file(这个时候可能出现 log fileswitch(checkpoint complete)等待事件)。如果是归档模式,归档进
程还要将前一个写满的 redo file 文件的内容写到归档日志文件中(这个时候可能出现 log file
switch(archiving needed)。
9.为事务建立回滚段 在完成本事务所有相关的 redo log buffer 之后,服务器进程开始改写这个 db buffer
的块头部事务列表并写入 scn,然后 包含这个块的头部事务列表及 scn 信息的数据副本放入回滚段中,将
这时回滚段中的信息称为数据块的“前映像“,这个”前映像“用于以后的回滚、恢复和一致性读。(回滚段可以
存储在专门的回滚表空间中,这个表空间由一个或多个物理文件组成,并专用于回滚表空间,回滚段也可在其它
表空间中的数据文件中开辟。
10.本事务修改数据块 准备工作都已经做好了,现在可以改写 db buffer 块的数据内容了,并在块的头部写
入回滚段的地址。
11.放入 dirty list 如果一个行数据多次 update 而未 commit,则在回滚段中将会有多个“前映像“,除了第
一个”前映像“含有 scn 信息外,其他每个“前映像“的头部都有 scn 信息和“前前映像”回滚段地址。一个
update 只对应一个 scn,然后服务器进程将在 dirty list 中建立一
条指向此 db buffer 块的指针(方便 dbwr 进程可以找到 dirty list 的 db buffer 数据块并写入数据文件中)。
接着服务器进程会从数据文件中继续读入第二个数据块,重复前一数据块的动作,数据块的读入、记日志、建
立回滚段、修改数据块、放入 dirty list。当 dirty queue 的长度达到阀值(一般是 25%),服务器进程将通知
dbwr 把脏数据写出,就是释放 db buffer 上的锁存器,腾出更多的 free db buffer。前面一直都是在说明
oracle 一次读一个数据块,其实 oracle 可以一次读入多个数据块(db_file_multiblock_read_count 来设置一
次读入块的个数)
说明:
在预处理的数据已经缓存在 db buffer 或刚刚被从数据文件读入到 db buffer 中,就要根据 sql 语句
的类型来决定接下来如何操作。
1>如果是 select 语句,则要查看 db buffer 块的头部是否有事务,如果有事务,则从回滚段中读取数据;如
果没有事务,则比较 select 的 scn 和 db buffer 块头部的 scn,如果前者小于后者,仍然要从回滚段中读取数据;
如果前者大于后者,说明这是一非脏缓存,可以直接读取这个 db buffer 块的中内容。
2>如果是 DML 操作,则即使在 db buffer 中找到一个没有事务,而且 SCN 比自己小的非脏
缓存数据块,服务器进程仍然要到表的头部对这条记录申请加锁,加锁成功才能进行后续动作,如果不成功,则要
等待前面的进程解锁后才能进行动作(这个时候阻塞是 tx 锁阻塞)。
用户 commit 或 rollback 到现在为止,数据已经在 db buffer 或数据文件中修改完
成,但是否要永久写到数文件中,要由用户来决定 commit(保存更改到数据文件) rollback 撤销数据的更改)。
1.用户执行 commit 命令
只有当 sql 语句所影响的所有行所在的最后一个块被读入 db buffer 并且重做信息被写入 redo log
buffer(仅指日志缓冲区,而不包括日志文件)之后,用户才可以发去 commit 命令,commit 触发 lgwr 进程,但不
强制立即 dbwr来释放所有相应 db buffer 块的锁(也就是no-force-at-commit,即提交不强制写),也就是说有
可能虽然已经 commit 了,但在随后的一段时间内 dbwr 还在写这条 sql 语句所涉及的数据块。表头部的行锁
并不在 commit 之后立即释放,而是要等 dbwr 进程完成之后才释放,这就可能会出现一个用户请求另一用户
已经 commit 的资源不成功的现象。
A .从 Commit 和 dbwr 进程结束之间的时间很短,如果恰巧在 commit 之后,dbwr 未结束之前断电,因为
commit 之后的数据已经属于数据文件的内容,但这部分文件没有完全写入到数据文件中。所以需要前滚。由
于 commit 已经触发 lgwr,这些所有未来得及写入数据文件的更改会在实例重启后,由 smon 进程根据重做日
志文件来前滚,完成之前 commit 未完成的工作(即把更改写入数据文件)。
B.如果未 commit 就断电了,因为数据已经在 db buffer 更改了,没有 commit,说明这部分数据不属于数
据文件,由于 dbwr 之前触发 lgwr 也就是只要数据更改,(肯定要先有 log) 所有 DBWR,在数据文件上的修改
都会被先一步记入重做日志文件,实例重启后,SMON 进程再根据重做日志文件来回滚。
其实 smon 的前滚回滚是根据检查点来完成的,当一个全部检查点发生的时候,首先让 LGWR 进程将
redo log buffer 中的所有缓冲(包含未提交的重做信息)写入重做日志文件,然后让 dbwr 进程将 db buffer 已
提交的缓冲写入数据文件(不强制写未提交的)。然后更新控制文件和数据文件头部的 SCN,表明当前数据库
是一致的,在相邻的两个检查点之间有很多事务,有提交和未提交的。
像前面的前滚回滚比较完整的说法是如下的说明:

A.发生检查点之前断电,并且当时有一个未提交的改变正在进行,实例重启之后,SMON 进程将从上一个
检查点开始核对这个检查点之后记录在重做日志文件中已提交的和未提交改变,因为
dbwr 之前会触发 lgwr,所以 dbwr 对数据文件的修改一定会被先记录在重做日志文件中。因此,断电前被
DBWN 写进数据文件的改变将通过重做日志文件中的记录进行还原,叫做回滚,
B. 如果断电时有一个已提交,但 dbwr 动作还没有完全完成的改变存在,因为已经提交,提交会触发 lgwr
进程,所以不管 dbwr 动作是否已完成,该语句将要影响的行及其产生的结果一定已经记录在重做日志文件中
了,则实例重启后,SMON 进程根据重做日志文件进行前滚.
实例失败后用于恢复的时间由两个检查点之间的间隔大小来决定,可以通个四个参数设置检查点执行的频
率:

Log_checkpoint_interval:
决定两个检查点之间写入重做日志文件的系统物理块(redo blocks)
的大小,默认值是 0,无限制。
log_checkpoint_timeout:
两 个 检 查 点 之 间 的 时 间 长 度(秒)默 认 值 1800s。
fast_start_io_target:
决定了用于恢复时需要处理的块的多少,默认值是 0,无限制。
fast_start_mttr_target:
直接决定了用于恢复的时间的长短,默认值是 0,无限制(SMON 进程执行的前滚
和回滚与用户的回滚是不同的,SMON 是根据重做日志文件进行前滚或回滚,而用户的回滚一定是根据回滚段
的内容进行回滚的。
在这里要说一下回滚段存储的数据,假如是 delete 操作,则回滚段将会记录整个行的数据,假如是 update,
则回滚段只记录被修改了的字段的变化前的数据(前映像),也就是没有被修改的字段是不会被记录的,假如是
insert,则回滚段只记录插入记录的 rowid。 这样假如事务提交,那回滚段中简单标记该事务已经提交;假如是
回退,则如果操作是 delete,回退的时候把回滚段中数据重新写回数据块,操作如果是 update,则把变化前数据
修改回去,操作如果是 insert,则根据记录的 rowid 把该记录删除。
2.如果用户 rollback。
则服务器进程会根据数据文件块和 DB BUFFER 中块的头部的事务列表和 SCN 以及回滚段地址找到
回滚段中相应的修改前的副本,并且用这些原值来还原当前数据文件中已修改但未提交的改变。如果有多个
“前映像”,服务器进程会在一个“前映像”的头部找到“前前映像”的回滚段地址,一直找到同一事务下的最早的
一个“前映像”为止。一旦发出了 COMMIT,用户就不能rollback,这使得 COMMIT 后 DBWR 进程还没有
全部完成的后续动作得到了保障。到现在为例一个事务已经结束了。
说明:
TM 锁:
符合 lock 机制的,用于保护对象的定义不被修改。 TX 锁:
这个锁代表一个事务,是行
级锁,用数据块头、数据记录头的一些字段表示,也是符合 lock 机制,有 resource structure、lock
structure、enqueue 算法。

热点内容
c搜索算法 发布:2025-02-12 23:05:47 浏览:860
返回服务器地址 发布:2025-02-12 23:05:45 浏览:179
我的世界推荐在线服务器 发布:2025-02-12 23:00:18 浏览:460
什么是解压目录 发布:2025-02-12 22:49:24 浏览:979
惠普电脑选购要考虑哪些因素配置 发布:2025-02-12 22:43:50 浏览:221
算法导论和算法 发布:2025-02-12 22:43:13 浏览:930
儿童电动车遥控如何配置 发布:2025-02-12 22:37:54 浏览:248
crm客户关系管理源码 发布:2025-02-12 22:34:10 浏览:987
c与java编译过程 发布:2025-02-12 21:47:47 浏览:374
python的面向对象 发布:2025-02-12 21:46:10 浏览:614