<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Oracle PL/SQL Loop to Update Fields with Periodic Commits</title>
	<atom:link href="http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html/feed" rel="self" type="application/rss+xml" />
	<link>http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html</link>
	<description>Java, ATG, Seam, and related Technologies</description>
	<pubDate>Sat, 05 Jul 2008 18:29:52 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
		<item>
		<title>By: Devon</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-4018</link>
		<dc:creator>Devon</dc:creator>
		<pubDate>Tue, 19 Feb 2008 18:37:58 +0000</pubDate>
		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/general/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-4018</guid>
		<description>Peter:

That is the best comment ever!  Thank you very much for taking the time to explain that, I appreciate it.

Thanks!

Devon</description>
		<content:encoded><![CDATA[<p>Peter:</p>
<p>That is the best comment ever!  Thank you very much for taking the time to explain that, I appreciate it.</p>
<p>Thanks!</p>
<p>Devon</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: peter rurenga</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-4012</link>
		<dc:creator>peter rurenga</dc:creator>
		<pubDate>Tue, 19 Feb 2008 13:22:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/general/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-4012</guid>
		<description>Hi Devon,

When an update starts, Oracle 'queries' what data it will update. This is the starting point and needs to be consistent untill the update has finished. This is often referred to as read consistent view of the data.
Now, what is the use of that?
Say, for example, that another user would start inserting data while you're still busy updating, then this user wouldn't be happy to find that his new inserted data would be included in the update statement. 
So, Oracle needs to keep track of the original state of the data as it was when the update started.  

Now, how does commiting affect this read consistency?
While updating, undo information is saved. After a commit, this undo information is no longer protected. 
This doesn't have to be a problem, becaust Oracle can still access the information in the undo segment to create a read consistent view of the data.
But, the moment a another transaction reuses this undo space, the undo is overwritten by other undo and there is no longer read consistency: you'll get the 'ORA-01555: snapshot too old'  error.

Be aware that it doesn't need to be another user to reuse undo: it might be yourself updating the next set.
Large and many undo segments will make it less likely to hit that error, but are no garantee.
You can have lots of undo space, but still run into this error, because after a commit a rollback segment will not grow but reuse the freed up space. 
If your next transaction happens to use the same rollback segment, you're hit the ORA-01555

To do it in one large update, how big should your rollback segment be?
That is hard to predict how much you need, I would suggest to just go for it. 
If it fails, no damage is done. You can enlarge your undo tablespace and/or rollback segment and retry it. 
If it doesn't, fail, you're home free.

I tried this update in my own test environment:
update dps_user set password = lower(password);
It took about 5 minutes, updated 3.7 million records and used 560 MB (70K undo blocks  * 8K (db_block_size)).

I'm happy enough with that.

Cheers, 

Peter</description>
		<content:encoded><![CDATA[<p>Hi Devon,</p>
<p>When an update starts, Oracle &#8216;queries&#8217; what data it will update. This is the starting point and needs to be consistent untill the update has finished. This is often referred to as read consistent view of the data.<br />
Now, what is the use of that?<br />
Say, for example, that another user would start inserting data while you&#8217;re still busy updating, then this user wouldn&#8217;t be happy to find that his new inserted data would be included in the update statement.<br />
So, Oracle needs to keep track of the original state of the data as it was when the update started.  </p>
<p>Now, how does commiting affect this read consistency?<br />
While updating, undo information is saved. After a commit, this undo information is no longer protected.<br />
This doesn&#8217;t have to be a problem, becaust Oracle can still access the information in the undo segment to create a read consistent view of the data.<br />
But, the moment a another transaction reuses this undo space, the undo is overwritten by other undo and there is no longer read consistency: you&#8217;ll get the &#8216;ORA-01555: snapshot too old&#8217;  error.</p>
<p>Be aware that it doesn&#8217;t need to be another user to reuse undo: it might be yourself updating the next set.<br />
Large and many undo segments will make it less likely to hit that error, but are no garantee.<br />
You can have lots of undo space, but still run into this error, because after a commit a rollback segment will not grow but reuse the freed up space.<br />
If your next transaction happens to use the same rollback segment, you&#8217;re hit the ORA-01555</p>
<p>To do it in one large update, how big should your rollback segment be?<br />
That is hard to predict how much you need, I would suggest to just go for it.<br />
If it fails, no damage is done. You can enlarge your undo tablespace and/or rollback segment and retry it.<br />
If it doesn&#8217;t, fail, you&#8217;re home free.</p>
<p>I tried this update in my own test environment:<br />
update dps_user set password = lower(password);<br />
It took about 5 minutes, updated 3.7 million records and used 560 MB (70K undo blocks  * 8K (db_block_size)).</p>
<p>I&#8217;m happy enough with that.</p>
<p>Cheers, </p>
<p>Peter</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Devon</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-3999</link>
		<dc:creator>Devon</dc:creator>
		<pubDate>Mon, 18 Feb 2008 16:41:26 +0000</pubDate>
		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/general/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-3999</guid>
		<description>Peter:

Thanks, although I'm sort of confused (not being very good with PL/SQL that shouldn't be a surprise), the snapshot too old error seems to be related to running out of undo space, isn't it?  If I'm committing every 10k records, why would I run into that?

Also you suggest doing it one statement, but wouldn't I definitely run out of undo space given the large size of the records?


Thanks!

Devon</description>
		<content:encoded><![CDATA[<p>Peter:</p>
<p>Thanks, although I&#8217;m sort of confused (not being very good with PL/SQL that shouldn&#8217;t be a surprise), the snapshot too old error seems to be related to running out of undo space, isn&#8217;t it?  If I&#8217;m committing every 10k records, why would I run into that?</p>
<p>Also you suggest doing it one statement, but wouldn&#8217;t I definitely run out of undo space given the large size of the records?</p>
<p>Thanks!</p>
<p>Devon</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: peter rurenga</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-3997</link>
		<dc:creator>peter rurenga</dc:creator>
		<pubDate>Mon, 18 Feb 2008 15:16:22 +0000</pubDate>
		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/general/oracle-plsql-loop-to-update-fields-with-periodic-commits.html#comment-3997</guid>
		<description>You got very lucky that you didn't run into exception 'ora-01555 snapshot too old'.
Best would be to update in one statement, second best to do it in a loop that is restartable.
The code above is not restartable, this will always update all records.
My advice  would be:

begin
  loop
    update dps_user
    set password = lower(password)
    where password != lower(password)
    and rowcount &#60;= 10000; 
    exit when sql%notfound; -- this will be true after last records have been updated
    commit; 
  end loop
end;

Might anything crash during execution, than you happily submit this code again and it will continue from wherever it crashed.

Cheers</description>
		<content:encoded><![CDATA[<p>You got very lucky that you didn&#8217;t run into exception &#8216;ora-01555 snapshot too old&#8217;.<br />
Best would be to update in one statement, second best to do it in a loop that is restartable.<br />
The code above is not restartable, this will always update all records.<br />
My advice  would be:</p>
<p>begin<br />
  loop<br />
    update dps_user<br />
    set password = lower(password)<br />
    where password != lower(password)<br />
    and rowcount &lt;= 10000;<br />
    exit when sql%notfound; &#8212; this will be true after last records have been updated<br />
    commit;<br />
  end loop<br />
end;</p>
<p>Might anything crash during execution, than you happily submit this code again and it will continue from wherever it crashed.</p>
<p>Cheers</p>
]]></content:encoded>
	</item>
</channel>
</rss>
