~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/falcon/RecordVersion.cpp

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
120
120
 
121
121
Record* RecordVersion::fetchVersion(Transaction * trans)
122
122
{
 
123
        Sync syncPrior(format->table->getSyncPrior(this), "RecordVersion::fetchVersion");
 
124
        if (priorVersion)
 
125
                syncPrior.lock(Shared);
 
126
 
 
127
        return fetchVersionRecursive(trans);
 
128
}
 
129
 
 
130
Record* RecordVersion::fetchVersionRecursive(Transaction * trans)
 
131
{
123
132
        // Unless the record is at least as old as the transaction, it's not for us
124
133
 
125
134
        Transaction *recTransaction = transaction;
144
153
        if (!priorVersion)
145
154
                return NULL;
146
155
                
147
 
        return priorVersion->fetchVersion(trans);
 
156
        return priorVersion->fetchVersionRecursive(trans);
148
157
}
149
158
 
150
 
Record* RecordVersion::rollback(Transaction *transaction)
 
159
void RecordVersion::rollback(Transaction *transaction)
151
160
{
152
 
        if (superceded)
153
 
                return NULL;
154
 
 
155
 
        return format->table->rollbackRecord (this, transaction);
 
161
        if (!superceded)
 
162
                format->table->rollbackRecord (this, transaction);
156
163
}
157
164
 
158
165
bool RecordVersion::isVersion()
172
179
}
173
180
 
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.
176
183
 
177
 
bool RecordVersion::scavenge(RecordScavenge *recordScavenge)
 
184
bool RecordVersion::scavenge(RecordScavenge *recordScavenge, LockType lockType)
178
185
{
179
 
        if (useCount != 1)
180
 
                return false;
181
 
 
182
 
        if (transaction || (transactionId >= recordScavenge->transactionId))
183
 
                {
 
186
        // Scavenge criteria:
 
187
        // 
 
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.
 
194
 
 
195
        if (    useCount == 1
 
196
                && !transaction
 
197
                && transactionId < recordScavenge->transactionId
 
198
                && (!hasRecord()
 
199
                        || generation <= recordScavenge->scavengeGeneration
 
200
                        || recordScavenge->forced))
 
201
                {
 
202
                
 
203
                // Expunge all record versions prior to this
 
204
 
 
205
                if (priorVersion && lockType == Exclusive)
 
206
                        format->table->expungeRecordVersions(this, recordScavenge);
 
207
                        
 
208
                return true;
 
209
                }
 
210
        else
 
211
                {
 
212
                 // Signal Table::cleanupRecords() that there is work to do
 
213
                 
184
214
                format->table->activeVersions = true;
185
215
 
186
 
                if (priorVersion)
187
 
                        priorVersion->scavenge(recordScavenge);
 
216
                // Scavenge criteria not met for this base record, so check prior versions.
 
217
                
 
218
                if (priorVersion && (recordScavenge->forced || recordScavenge->scavengeGeneration != UNDEFINED))
 
219
                        {
 
220
                        
 
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. 
 
223
                        
 
224
                        if (lockType == Exclusive)
 
225
                                priorVersion->scavenge(recordScavenge, lockType);
 
226
                        else
188
227
 
 
228
                                // Scan the prior record versions and return 'true' if a scavenge
 
229
                                // candidate is found.
 
230
                                
 
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))
 
237
                                                return true;
 
238
                        }
 
239
                }
189
240
                return false;
190
 
                }
191
 
 
192
 
        if (priorVersion)
193
 
                format->table->expungeRecordVersions(this, recordScavenge);
194
 
 
195
 
        return true;
196
241
}
197
242
 
198
243
// Scavenge record versions replaced within a savepoint.
202
247
        if (!priorVersion)
203
248
                return;
204
249
 
 
250
        Sync syncPrior(getSyncPrior(), "RecordVersion::scavenge()-savepoint");
 
251
        syncPrior.lock(Shared);
 
252
        
205
253
        Record *rec = priorVersion;
206
254
        Record *ptr = NULL;
207
255
        
229
277
        
230
278
        Record *prior = priorVersion;
231
279
        prior->addRef();
 
280
 
 
281
        syncPrior.unlock();
 
282
        syncPrior.lock(Exclusive);
 
283
        
232
284
        setPriorVersion(rec);
233
285
        //ptr->setPriorVersion(NULL);
234
286
        ptr->state = recEndChain;
261
313
        return superceded;
262
314
}
263
315
 
 
316
// Set the priorVersion to NULL and return its pointer.
 
317
// The caller is responsivble for releasing the associated useCount.
 
318
 
 
319
Record* RecordVersion::clearPriorVersion(void)
 
320
{
 
321
        Record * prior = priorVersion;
 
322
        priorVersion = NULL;
 
323
        return prior;
 
324
}
 
325
 
264
326
void RecordVersion::setPriorVersion(Record *oldVersion)
265
327
{
266
328
        if (oldVersion)
346
408
                        
347
409
                        if (table->debugThawedBytes >= table->database->configuration->recordChillThreshold)
348
410
                                {
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;
352
415
                                }
402
465
        else
403
466
                stream->putInt(2);
404
467
}
 
468