121
121
Record* RecordVersion::fetchVersion(Transaction * trans)
123
Sync syncPrior(format->table->getSyncPrior(this), "RecordVersion::fetchVersion");
125
syncPrior.lock(Shared);
127
return fetchVersionRecursive(trans);
130
Record* RecordVersion::fetchVersionRecursive(Transaction * trans)
123
132
// Unless the record is at least as old as the transaction, it's not for us
125
134
Transaction *recTransaction = transaction;
144
153
if (!priorVersion)
147
return priorVersion->fetchVersion(trans);
156
return priorVersion->fetchVersionRecursive(trans);
150
Record* RecordVersion::rollback(Transaction *transaction)
159
void RecordVersion::rollback(Transaction *transaction)
155
return format->table->rollbackRecord (this, transaction);
162
format->table->rollbackRecord (this, transaction);
158
165
bool RecordVersion::isVersion()
174
181
// Scavenge record versions by the scavenger thread. Return true if the
175
// record is a scavenge candidate
182
// record or any prior version of the record is a scavenge candidate.
177
bool RecordVersion::scavenge(RecordScavenge *recordScavenge)
184
bool RecordVersion::scavenge(RecordScavenge *recordScavenge, LockType lockType)
182
if (transaction || (transactionId >= recordScavenge->transactionId))
186
// Scavenge criteria:
188
// 1. Use count == 1 AND
189
// 2. Record Version is older than the record version that was visible
190
// to the oldest active transaction AND
191
// 3. Either the record generation is older than the current generation
192
// OR the scavenge is forced
193
// OR there is no record data associated with the record version.
197
&& transactionId < recordScavenge->transactionId
199
|| generation <= recordScavenge->scavengeGeneration
200
|| recordScavenge->forced))
203
// Expunge all record versions prior to this
205
if (priorVersion && lockType == Exclusive)
206
format->table->expungeRecordVersions(this, recordScavenge);
212
// Signal Table::cleanupRecords() that there is work to do
184
214
format->table->activeVersions = true;
187
priorVersion->scavenge(recordScavenge);
216
// Scavenge criteria not met for this base record, so check prior versions.
218
if (priorVersion && (recordScavenge->forced || recordScavenge->scavengeGeneration != UNDEFINED))
221
// Scavenge prior record versions only if we have an exclusive lock on
222
// the record leaf. Return 'false' because the base record is not scavengable.
224
if (lockType == Exclusive)
225
priorVersion->scavenge(recordScavenge, lockType);
228
// Scan the prior record versions and return 'true' if a scavenge
229
// candidate is found.
231
for (Record *rec = priorVersion; rec; rec = rec->getPriorVersion())
232
if ( rec->useCount == 1
233
&& !rec->getTransaction()
234
&& rec->getTransactionId() < recordScavenge->transactionId
235
&& (!rec->hasRecord()
236
|| rec->generation <= recordScavenge->scavengeGeneration))
193
format->table->expungeRecordVersions(this, recordScavenge);
198
243
// Scavenge record versions replaced within a savepoint.
261
313
return superceded;
316
// Set the priorVersion to NULL and return its pointer.
317
// The caller is responsivble for releasing the associated useCount.
319
Record* RecordVersion::clearPriorVersion(void)
321
Record * prior = priorVersion;
264
326
void RecordVersion::setPriorVersion(Record *oldVersion)
347
409
if (table->debugThawedBytes >= table->database->configuration->recordChillThreshold)
349
Log::debug("Record Thaw/Fetch: table=%-5ld records=%7ld bytes=%8ld\n",table->tableId, table->debugThawedRecords, table->debugThawedBytes);
411
Log::debug("%d: Record thaw (fetch): table %d, %ld records, %ld bytes\n", this->format->table->database->deltaTime,
412
table->tableId, table->debugThawedRecords, table->debugThawedBytes);
350
413
table->debugThawedRecords = 0;
351
414
table->debugThawedBytes = 0;