http://blog.csdn.net/knowhow/archive/2008/01/13/2042266.aspx
那么,为什么COMMIT
的响应时间相当“平”,而不论事务大小呢?在数据库中执行COMMIT
之前,困难的工作都已经做了。我们已经修改了数据库中的数据,所以99.9%
的工作都已经完成。例如,已经发生了以下操作:
q
已经在SGA
中生成了undo
块。
q
已经在SGA
中生成了已修改数据块。
q
已经在SGA
中生成了对于前两项的缓存redo
。
q
取决于前三项的大小,以及这些工作花费的时间,前面的每个数据(或某些数据)可能已经刷新输出到磁盘。
q
已经得到了所需的全部锁。
执行COMMIT
时,余下的工作只是:
q
为事务生成一个SCN
。如果你还不熟悉SCN
,起码要知道,SCN
是Oracle
使用的一种简单的计时机制,用于保证事务的顺序,并支持失败恢复。SCN
还用于保证数据库中的读一致性和检查点。可以把SCN
看作一个钟摆,每次有人COMMIT
时,SCN
都会增1.
q
LGWR
将所有余下的缓存重做日志条目写到磁盘,并把SCN
记录到在线重做日志文件中。这一步就是真正的COMMIT
。如果出现了这一步,即已经提交。事务条目会从V$TRANSACTION
中“删除”,这说明我们已经提交。
q
V$LOCK
中记录这我们的会话持有的锁,这些所都将被释放,而排队等待这些锁的每一个人都会被唤醒,可以继续完成他们的工作。
q
如果事务修改的某些块还在缓冲区缓存中,则会以一种快速的模式访问并“清理”
。块清除(Block cleanout
)是指清除存储在数据库块首部的与锁相关的信息。实质上讲,我们在清除块上的事务信息,这样下一个访问这个块的人就不用再这么做了。我们采用一种无需生成重做日志信息的方式来完成块清除,这样可以省去以后的大量工作(在下面的“块清除”一节中将更全面地讨论这个问题)。
可以看到,处理COMMIT
所要做的工作很少。其中耗时最长的操作要算LGWR
执行的活动(一般是这样),因为这些磁盘写是物理磁盘I/O
。不过,这里LGWR
花费的时间并不会太多,之所以能大幅减少这个操作的时间,原因是LGWR
一直在以连续的方式刷新输出重做日志缓冲区的内容。在你工作期间,LGWR
并非缓存这你做的所有工作;实际上,随着你的工作的进行,LGWR
会在后台增量式地刷新输出重做日志缓冲区的内容。这样做是为了避免COMMIT
等待很长时间来一次性刷新输出所有的redo
。
因此,即使我们有一个长时间运行的事务,但在提交之前,它生成的许多缓存重做日志已经刷新输出到磁盘了(而不是全部等到提交时才刷新输出)。这也有不好的一面,COMMIT
时,我们必须等待,直到尚未写出的所有缓存redo
都已经安全写到磁盘上才行。也就是说,对LGWR
的调用是一个同步(synchronous
)调用。尽管LGWR
本身可以使用异步I/O
并行地写至日志文件,但是我们的事务会一直等待LGWR
完成所有写操作,并收到数据都已在磁盘上的确认才会返回。
前面我提高过,由于某种原因,我们用的是一个Java
程序而不是PL/SQL
,这个原因就是PL/SQL
提供了提交时优化(commit-time optimization
)。我说过,LGWR
是一个同步调用,我们要等待它完成所有写操作。在Oracle
10g
Release 1
及以前版本中,除PL/SQL
以外的所有编程语言都是如此。PL/SQL
引擎不同,要认识到直到PL/SQL
例程完成之前,客户并不知道这个PL/SQL
例程中是否发生了COMMIT
,所以PL/SQL
引擎完成的是异步提交。它不会等待LGWR
完成;相反,PL/SQL
引擎会从COMMIT
调用立即返回。不过,等到PL/SQL
例程完成,我们从数据库返回客户时,PL/SQL
例程则要等待LGWR
完成所有尚未完成的COMMIT
。因此,如果在PL/SQL
中提交了100
次,然后返回客户,会发现由于存在这种优化,你只会等待LGWR
一次,而不是100
次。这是不是说可以在PL/SQL
中频繁地提交呢?这是一个很好或者不错的主意吗?不是,绝对不是,在PL/SQ;
中频繁地提交与在其他语言中这样做同样糟糕。指导原则是,应该在逻辑工作单元完成时才提交,而不要在此之前草率地提交。
注意
如果你在执行分布式事务或者以最大可能性模式执行Data Guard
,PL/SQL
中的这种提交时优化可能会被挂起。因为此时存在两个参与者,PL/SQL
必须等待提交确实完成后才能继续。
分享到:
相关推荐
1. COMMIT_FORM和COMMIT 都对form和数据库进行提交。针对form上面的数据变动提交到后台数据库,同时数据库提交数据。 2. DO_KEY(‘COMMIT_FORM’) 它会首先执行KEY-COMMIT触发器里面的代码,如果没有这个触发器,则...
这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在oracle中,执行了update或者insert语句后,都会要求commit,如果不commit却强制关闭连接,oracle就会将这条提交的记录锁住。由于我的java程序...
ORACLE里锁有以下几种模式: 0:none 1:null 空 2:Row-S 行共享(RS):共享表锁 3:Row-X 行专用(RX):用于行的修改 4:Share 共享锁(S):阻止其他DML操作 5:S/Row-X 共享行专用(SRX):阻止其他...
ORACLE INSERT INTO SELECT *FROM 分批提交例子
COMMIT 指定是否在每个数组(其大小由BUFFER参数设置)插入后进行提交 ..................(见附件) --导入 --整个文件导入 ..................(见附件) --物理备份 冷备份 ..................(见附件) 冷...
捕获oracle中提交过频语句SQL语句,快速定位问题sql。
oracle中数据delete且commit 恢复误删数据
这种类型的临时表可以使用 ON COMMIT PRESERVE ROWS 说明,表示临时表是会话指定,当中断会话时(commit or rollback),Oracle 自动清除临时表中数据。 临时表的特点 1. 临时表的数据只对当前 Session 有效,每个...
CDC(Change Data Capture)是oracle在数据库级别实现的增量抽取解决...而异步CDC则是通过分析已经commit的日志记录来得到增量数据信息,有一定的时间延迟,并且提供了到Oracle Streams的接口。异步CDC只在10g中支持。
Oracle 数据库支持多种事务控制语句,例如 COMMIT、ROLLBACK 和 SAVEPOINT。 Oracle 数据库语句大全是 Oracle 数据库管理系统中的一系列语句,用于管理和操作数据库。这些语句可以分为四大类:数据定义语言(DDL)...
Oracle_Undo与Redo的通俗 Oracle中的Undo和Redo是两个非常重要的概念,它们都是Oracle数据库中事务管理和恢复机制的关键组件。Undo和Redo都是为了确保数据库的一致性和可靠性。 什么是REDO? REDO记录transaction...
ORACLE常用命令 一、ORACLE的启动和关闭 1、在单机环境下 要想启动或关闭ORACLE系统必须首先切换到ORACLE用户,如下 su - oracle a、启动ORACLE系统 oracle>svrmgrl SVRMGR>connect internal SVRMGR>startup ...
shell连接oracle数据库工具脚本:支持select/insert/update/delete 部署位置:/root/sysmonitor db:数据库文件夹 dbconfig.properties:数据库配置文件, dbConnectTest.sh:连接测试文件 dbExecurteSQL.sh:...
Oracle 创建 Job 实例 Oracle 创建 Job 实例是指在 Oracle 数据库中创建一个计划任务,用于在特定的时间点执行特定的操作。以下是创建 Job 实例的详细过程和相关知识点: 一、创建 Job 实例 要创建一个 Job 实例...
17由于没有COMMIT,导致数据库表被锁住 18索引创建不合理,导致数据库查询特别慢 19 由于BUFFER参数设置不合理导致EXP失败 20由于EXP不向上兼容,语言不兼容,导致不同版本、不同字符集的数据库无法导入 21 由于创建...
oracle版本的undolog建表语句。 2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案。Fescar 的愿景是让分布式事务的使用像本地...
因为你每删一条数据,oracle要自动执行一次commit。commit是需要资源的。所以如果你手动设置为每删数据1000条,执行一次commit. 那你可以节省资源了。 (2)充分利用batch update。如果不用batch,每个
Oracle Redo 和 Undo Mechanism Oracle 中的 redo 和 undo 机制是数据库的核心组件,它们一起协作以确保数据库的事务一致性和可靠性。在本文中,我们将深入探讨 redo 和 undo 机制的工作原理和协作机制。 Undo ...