|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.236 2007/06/09 18:49:54 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.237 2007/08/14 17:35:18 tgl Exp $ |
12 | 12 | * |
13 | 13 | * |
14 | 14 | * INTERFACE ROUTINES |
@@ -1509,6 +1509,34 @@ heap_get_latest_tid(Relation relation, |
1509 | 1509 | }/* end of loop */ |
1510 | 1510 | } |
1511 | 1511 |
|
| 1512 | + |
| 1513 | +/* |
| 1514 | + * UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends |
| 1515 | + * |
| 1516 | + * This is called after we have waited for the XMAX transaction to terminate. |
| 1517 | + * If the transaction aborted, we guarantee the XMAX_INVALID hint bit will |
| 1518 | + * be set on exit. If the transaction committed, we set the XMAX_COMMITTED |
| 1519 | + * hint bit if possible --- but beware that that may not yet be possible, |
| 1520 | + * if the transaction committed asynchronously. Hence callers should look |
| 1521 | + * only at XMAX_INVALID. |
| 1522 | + */ |
| 1523 | +staticvoid |
| 1524 | +UpdateXmaxHintBits(HeapTupleHeadertuple,Bufferbuffer,TransactionIdxid) |
| 1525 | +{ |
| 1526 | +Assert(TransactionIdEquals(HeapTupleHeaderGetXmax(tuple),xid)); |
| 1527 | + |
| 1528 | +if (!(tuple->t_infomask& (HEAP_XMAX_COMMITTED |HEAP_XMAX_INVALID))) |
| 1529 | +{ |
| 1530 | +if (TransactionIdDidCommit(xid)) |
| 1531 | +HeapTupleSetHintBits(tuple,buffer,HEAP_XMAX_COMMITTED, |
| 1532 | +xid); |
| 1533 | +else |
| 1534 | +HeapTupleSetHintBits(tuple,buffer,HEAP_XMAX_INVALID, |
| 1535 | +InvalidTransactionId); |
| 1536 | +} |
| 1537 | +} |
| 1538 | + |
| 1539 | + |
1512 | 1540 | /* |
1513 | 1541 | *heap_insert- insert tuple into a heap |
1514 | 1542 | * |
@@ -1840,16 +1868,8 @@ heap_delete(Relation relation, ItemPointer tid, |
1840 | 1868 | xwait)) |
1841 | 1869 | gotol1; |
1842 | 1870 |
|
1843 | | -/* Otherwise we can mark it committed or aborted */ |
1844 | | -if (!(tp.t_data->t_infomask& (HEAP_XMAX_COMMITTED | |
1845 | | -HEAP_XMAX_INVALID))) |
1846 | | -{ |
1847 | | -if (TransactionIdDidCommit(xwait)) |
1848 | | -tp.t_data->t_infomask |=HEAP_XMAX_COMMITTED; |
1849 | | -else |
1850 | | -tp.t_data->t_infomask |=HEAP_XMAX_INVALID; |
1851 | | -SetBufferCommitInfoNeedsSave(buffer); |
1852 | | -} |
| 1871 | +/* Otherwise check if it committed or aborted */ |
| 1872 | +UpdateXmaxHintBits(tp.t_data,buffer,xwait); |
1853 | 1873 | } |
1854 | 1874 |
|
1855 | 1875 | /* |
@@ -2164,16 +2184,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, |
2164 | 2184 | xwait)) |
2165 | 2185 | gotol2; |
2166 | 2186 |
|
2167 | | -/* Otherwise we can mark it committed or aborted */ |
2168 | | -if (!(oldtup.t_data->t_infomask& (HEAP_XMAX_COMMITTED | |
2169 | | -HEAP_XMAX_INVALID))) |
2170 | | -{ |
2171 | | -if (TransactionIdDidCommit(xwait)) |
2172 | | -oldtup.t_data->t_infomask |=HEAP_XMAX_COMMITTED; |
2173 | | -else |
2174 | | -oldtup.t_data->t_infomask |=HEAP_XMAX_INVALID; |
2175 | | -SetBufferCommitInfoNeedsSave(buffer); |
2176 | | -} |
| 2187 | +/* Otherwise check if it committed or aborted */ |
| 2188 | +UpdateXmaxHintBits(oldtup.t_data,buffer,xwait); |
2177 | 2189 | } |
2178 | 2190 |
|
2179 | 2191 | /* |
@@ -2713,16 +2725,8 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, Buffer *buffer, |
2713 | 2725 | xwait)) |
2714 | 2726 | gotol3; |
2715 | 2727 |
|
2716 | | -/* Otherwise we can mark it committed or aborted */ |
2717 | | -if (!(tuple->t_data->t_infomask& (HEAP_XMAX_COMMITTED | |
2718 | | -HEAP_XMAX_INVALID))) |
2719 | | -{ |
2720 | | -if (TransactionIdDidCommit(xwait)) |
2721 | | -tuple->t_data->t_infomask |=HEAP_XMAX_COMMITTED; |
2722 | | -else |
2723 | | -tuple->t_data->t_infomask |=HEAP_XMAX_INVALID; |
2724 | | -SetBufferCommitInfoNeedsSave(*buffer); |
2725 | | -} |
| 2728 | +/* Otherwise check if it committed or aborted */ |
| 2729 | +UpdateXmaxHintBits(tuple->t_data,*buffer,xwait); |
2726 | 2730 | } |
2727 | 2731 |
|
2728 | 2732 | /* |
|