| 1109 | |
| 1110 | |
| 1111 | bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb, |
| 1112 | jrd_tra* transaction, MemoryPool* pool, |
| 1113 | bool writelock, bool noundo) |
| 1114 | { |
| 1115 | /************************************** |
| 1116 | * |
| 1117 | * V I O _ c h a s e _ r e c o r d _ v e r s i o n |
| 1118 | * |
| 1119 | ************************************** |
| 1120 | * |
| 1121 | * Functional description |
| 1122 | * This is the key routine in all of JRD. Given a record, determine |
| 1123 | * what the version, if any, is appropriate for this transaction. This |
| 1124 | * is primarily done by playing with transaction numbers. If, in the |
| 1125 | * process, a record is found that requires garbage collection, by all |
| 1126 | * means garbage collect it. |
| 1127 | * |
| 1128 | **************************************/ |
| 1129 | SET_TDBB(tdbb); |
| 1130 | Database* const dbb = tdbb->getDatabase(); |
| 1131 | Jrd::Attachment* const attachment = transaction->tra_attachment; |
| 1132 | jrd_rel* const relation = rpb->rpb_relation; |
| 1133 | |
| 1134 | const bool gcPolicyCooperative = dbb->dbb_flags & DBB_gc_cooperative; |
| 1135 | const bool gcPolicyBackground = dbb->dbb_flags & DBB_gc_background; |
| 1136 | const TraNumber oldest_snapshot = relation->isTemporary() ? |
| 1137 | attachment->att_oldest_snapshot : transaction->tra_oldest_active; |
| 1138 | |
| 1139 | #ifdef VIO_DEBUG |
| 1140 | VIO_trace(DEBUG_TRACE_ALL, |
| 1141 | "VIO_chase_record_version (rel_id %u, record_param %" QUADFORMAT"d, transaction %" |
| 1142 | SQUADFORMAT", pool %p)\n", |
| 1143 | relation->rel_id, |
| 1144 | rpb->rpb_number.getValue(), transaction ? transaction->tra_number : 0, |
| 1145 | (void*) pool); |
| 1146 | |
| 1147 | VIO_trace(DEBUG_TRACE_ALL_INFO, |
| 1148 | " record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 1149 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT":%d\n", |
| 1150 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 1151 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 1152 | rpb->rpb_f_page, rpb->rpb_f_line); |
| 1153 | #endif |
| 1154 | |
| 1155 | CommitNumber current_snapshot_number; |
| 1156 | bool int_gc_done = (attachment->att_flags & ATT_no_cleanup); |
| 1157 | |
| 1158 | int state = TRA_snapshot_state(tdbb, transaction, rpb->rpb_transaction_nr, ¤t_snapshot_number); |
| 1159 | |
| 1160 | // Reset (if appropriate) the garbage collect active flag to reattempt the backout |
| 1161 | |
| 1162 | if (rpb->rpb_flags & rpb_gc_active) |
| 1163 | checkGCActive(tdbb, rpb, state); |
| 1164 | |
| 1165 | // Take care about modifications performed by our own transaction |
| 1166 | |
| 1167 | rpb->rpb_runtime_flags &= ~RPB_CLEAR_FLAGS; |
| 1168 | int forceBack = 0; |
no test coverage detected