Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING 247 the current value for Y is now 6—it’s not 5 anymore—and before updating the value of X, Oracle will check to see that Y is still 5. Now what happens? How are the updates affected by this? Obviously, we cannot modify an old version of a block—when we go to modify a row, we must modify the current version of that block. Additionally, Oracle cannot just simply skip this row, as that would be an inconsistent read and unpredictable. What we’ll discover is that in such cases, Oracle will restart the write modification from scratch. Consistent Reads and Current Reads Oracle does do two types of block gets when processing a modification statement. It performs • Consistent reads: When “finding” the rows to modify • Current reads: When getting the block to actually update the row of interest We can see this easily using TKPROF. Consider this small one-row example, which reads and updates the single row in table T from earlier: ops$tkyte@ORA10GR1> alter session set sql_trace=true; Session altered. ops$tkyte@ORA10GR1> select * from t; X ---------- 10001 ops$tkyte@ORA10G> update t t1 set x = x+1; 1 row updated. ops$tkyte@ORA10G> update t t2 set x = x+1; 1 row updated. When we run TKPROF and view the results, we’ll see something like this (note that I removed the ELAPSED, CPU, and DISK columns from this report): select * from t call count query current rows ------- ------ ------ ---------- ---------- Parse 1 0 0 0 Execute 1 0 0 0 Fetch 2 3 0 1 ------- ------ ------ ---------- ---------- total 4 3 0 1 update t t1 set x = x+1
248 CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING call count query current rows ------- ------ ------ ---------- ---------- Parse 1 0 0 0 Execute 1 3 3 1 Fetch 0 0 0 0 ------- ------ ------ ---------- ---------- total 2 3 3 1 update t t2 set x = x+1 call count query current rows ------- ------ ------ ---------- ---------- Parse 1 0 0 0 Execute 1 3 1 1 Fetch 0 0 0 0 ------- ------ ------ ---------- ---------- total 2 3 1 1 So, during just a normal query, we incur three query (consistent) mode gets. During the first UPDATE, we incur the same three I/Os (the search component of the update involves finding all of the rows that are in the table when the update began, in this case) and three current mode gets as well. The current mode gets are performed in order to retrieve the table block as it exists right now, the one with the row on it, to get an undo segment block to begin our transaction, and an undo block. The second update has exactly one current mode get—since we did not have to do the undo work again, we had only the one current get on the block with the row we want to update. The very presence of the current mode gets tells us that a modification of some sort took place. Before Oracle will modify a block with new information, it must get the most current copy of it. So, how does read consistency affect a modification? Well, imagine you were executing the following UPDATE statement against some database table: Update t set x = x+1 where y = 5; We understand that the WHERE Y=5 component, the read-consistent phase of the query, will be processed using a consistent read (query mode gets in the TKPROF report). The set of WHERE Y=5 records that was committed in the table at the beginning of the statement’s execution are the records it will see (assuming READ COMMITTED isolation—if the isolation is SERIALIZABLE, it would be the set of WHERE Y=5 records that existed when the transaction began). This means if that UPDATE statement were to take five minutes to process from start to finish, and someone added and committed a new record to the table with a value of 5 in the Y column, then that UPDATE would not “see” it because the consistent read would not see it. This is expected, and normal. But, the question is, what happens if two sessions execute the following statements in order? Update t set y = 10 where y = 5; Update t Set x = x+1 Where y = 5; Table 7-8 demonstrates the timeline.
- Page 242 and 243: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 244 and 245: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 246 and 247: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 248 and 249: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 250 and 251: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 252 and 253: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 254 and 255: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 256 and 257: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 258 and 259: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 260 and 261: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 262 and 263: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 264 and 265: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 266 and 267: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 268 and 269: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 270 and 271: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 272 and 273: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 274 and 275: CHAPTER 6 ■ LOCKING AND LATCHING
- Page 276 and 277: CHAPTER 7 ■ ■ ■ Concurrency a
- Page 278 and 279: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 280 and 281: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 282 and 283: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 284 and 285: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 286 and 287: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 288 and 289: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 290 and 291: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 294 and 295: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 296 and 297: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 298 and 299: CHAPTER 7 ■ CONCURRENCY AND MULTI
- Page 300 and 301: CHAPTER 8 ■ ■ ■ Transactions
- Page 302 and 303: CHAPTER 8 ■ TRANSACTIONS 257 •
- Page 304 and 305: CHAPTER 8 ■ TRANSACTIONS 259 So,
- Page 306 and 307: CHAPTER 8 ■ TRANSACTIONS 261 X --
- Page 308 and 309: CHAPTER 8 ■ TRANSACTIONS 263 “s
- Page 310 and 311: CHAPTER 8 ■ TRANSACTIONS 265 busi
- Page 312 and 313: CHAPTER 8 ■ TRANSACTIONS 267 Many
- Page 314 and 315: CHAPTER 8 ■ TRANSACTIONS 269 ops$
- Page 316 and 317: CHAPTER 8 ■ TRANSACTIONS 271 last
- Page 318 and 319: CHAPTER 8 ■ TRANSACTIONS 273 Dist
- Page 320 and 321: CHAPTER 8 ■ TRANSACTIONS 275 Auto
- Page 322 and 323: CHAPTER 8 ■ TRANSACTIONS 277 3 Au
- Page 324 and 325: CHAPTER 8 ■ TRANSACTIONS 279 5 pr
- Page 326: CHAPTER 8 ■ TRANSACTIONS 281 scot
- Page 329 and 330: 284 CHAPTER 9 ■ REDO AND UNDO cri
- Page 331 and 332: 286 CHAPTER 9 ■ REDO AND UNDO Fir
- Page 333 and 334: 288 CHAPTER 9 ■ REDO AND UNDO The
- Page 335 and 336: 290 CHAPTER 9 ■ REDO AND UNDO We
- Page 337 and 338: 292 CHAPTER 9 ■ REDO AND UNDO Wha
- Page 339 and 340: 294 CHAPTER 9 ■ REDO AND UNDO row
- Page 341 and 342: 296 CHAPTER 9 ■ REDO AND UNDO If
CHAPTER 7 ■ CONCURRENCY AND MULTI-VERSIONING 247<br />
the current value for Y is now 6—it’s not 5 anymore—<strong>and</strong> before updating the value of X,<br />
<strong>Oracle</strong> will check to see that Y is still 5. Now what happens? How are the updates affected<br />
by this?<br />
Obviously, we cannot modify an old version of a block—when we go to modify a row, we<br />
must modify the current version of that block. Additionally, <strong>Oracle</strong> cannot just simply skip this<br />
row, as that would be an inconsistent read <strong>and</strong> unpredictable. What we’ll discover is that in<br />
such cases, <strong>Oracle</strong> will restart the write modification from scratch.<br />
Consistent Reads <strong>and</strong> Current Reads<br />
<strong>Oracle</strong> does do two types of block gets when processing a modification statement. It performs<br />
• Consistent reads: When “finding” the rows to modify<br />
• Current reads: When getting the block to actually update the row of interest<br />
We can see this easily using TKPROF. Consider this small one-row example, which reads<br />
<strong>and</strong> updates the single row in table T from earlier:<br />
ops$tkyte@ORA10GR1> alter session set sql_trace=true;<br />
Session altered.<br />
ops$tkyte@ORA10GR1> select * from t;<br />
X<br />
----------<br />
10001<br />
ops$tkyte@ORA10G> update t t1 set x = x+1;<br />
1 row updated.<br />
ops$tkyte@ORA10G> update t t2 set x = x+1;<br />
1 row updated.<br />
When we run TKPROF <strong>and</strong> view the results, we’ll see something like this (note that I<br />
removed the ELAPSED, CPU, <strong>and</strong> DISK columns from this report):<br />
select * from t<br />
call count query current rows<br />
------- ------ ------ ---------- ----------<br />
Parse 1 0 0 0<br />
Execute 1 0 0 0<br />
Fetch 2 3 0 1<br />
------- ------ ------ ---------- ----------<br />
total 4 3 0 1<br />
update t t1 set x = x+1