~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/row/row0vers.c

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
Finds out if an active transaction has inserted or modified a secondary
34
34
index record. NOTE: the kernel mutex is temporarily released in this
35
35
function! */
36
 
 
 
36
UNIV_INTERN
37
37
trx_t*
38
38
row_vers_impl_x_locked_off_kernel(
39
39
/*==============================*/
40
40
                                /* out: NULL if committed, else the active
41
41
                                transaction; NOTE that the kernel mutex is
42
42
                                temporarily released! */
43
 
        rec_t*          rec,    /* in: record in a secondary index */
 
43
        const rec_t*    rec,    /* in: record in a secondary index */
44
44
        dict_index_t*   index,  /* in: the secondary index */
45
45
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
46
46
{
158
158
                mem_heap_free(heap2); /* free version and clust_offsets */
159
159
 
160
160
                if (prev_version) {
 
161
                        row_ext_t*      ext;
 
162
 
161
163
                        clust_offsets = rec_get_offsets(
162
164
                                prev_version, clust_index, NULL,
163
165
                                ULINT_UNDEFINED, &heap);
 
166
                        /* The stack of versions is locked by mtr.
 
167
                        Thus, it is safe to fetch the prefixes for
 
168
                        externally stored columns. */
164
169
                        row = row_build(ROW_COPY_POINTERS, clust_index,
165
 
                                        prev_version, clust_offsets, heap);
166
 
                        entry = row_build_index_entry(row, index, heap);
 
170
                                        prev_version, clust_offsets,
 
171
                                        NULL, &ext, heap);
 
172
                        entry = row_build_index_entry(row, ext, index, heap);
 
173
                        /* entry may be NULL if a record was inserted
 
174
                        in place of a deleted record, and the BLOB
 
175
                        pointers of the new record were not
 
176
                        initialized yet.  But in that case,
 
177
                        prev_version should be NULL. */
 
178
                        ut_a(entry);
167
179
                }
168
180
 
169
181
                mutex_enter(&kernel_mutex);
254
266
/*********************************************************************
255
267
Finds out if we must preserve a delete marked earlier version of a clustered
256
268
index record, because it is >= the purge view. */
257
 
 
 
269
UNIV_INTERN
258
270
ibool
259
271
row_vers_must_preserve_del_marked(
260
272
/*==============================*/
286
298
if there is any not delete marked version of the record where the trx
287
299
id >= purge view, and the secondary index entry and ientry are identified in
288
300
the alphabetical ordering; exactly in this case we return TRUE. */
289
 
 
 
301
UNIV_INTERN
290
302
ibool
291
303
row_vers_old_has_index_entry(
292
304
/*=========================*/
294
306
        ibool           also_curr,/* in: TRUE if also rec is included in the
295
307
                                versions to search; otherwise only versions
296
308
                                prior to it are searched */
297
 
        rec_t*          rec,    /* in: record in the clustered index; the
 
309
        const rec_t*    rec,    /* in: record in the clustered index; the
298
310
                                caller must have a latch on the page */
299
311
        mtr_t*          mtr,    /* in: mtr holding the latch on rec; it will
300
312
                                also hold the latch on purge_view */
301
313
        dict_index_t*   index,  /* in: the secondary index */
302
 
        dtuple_t*       ientry) /* in: the secondary index entry */
 
314
        const dtuple_t* ientry) /* in: the secondary index entry */
303
315
{
304
 
        rec_t*          version;
 
316
        const rec_t*    version;
305
317
        rec_t*          prev_version;
306
318
        dict_index_t*   clust_index;
307
319
        ulint*          clust_offsets;
308
320
        mem_heap_t*     heap;
309
321
        mem_heap_t*     heap2;
310
 
        dtuple_t*       row;
311
 
        dtuple_t*       entry;
 
322
        const dtuple_t* row;
 
323
        const dtuple_t* entry;
312
324
        ulint           err;
313
325
        ulint           comp;
314
326
 
315
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
316
 
              || mtr_memo_contains(mtr, buf_block_align(rec),
317
 
                                   MTR_MEMO_PAGE_S_FIX));
 
327
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
328
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
318
329
#ifdef UNIV_SYNC_DEBUG
319
330
        ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
320
331
#endif /* UNIV_SYNC_DEBUG */
329
340
                                        ULINT_UNDEFINED, &heap);
330
341
 
331
342
        if (also_curr && !rec_get_deleted_flag(rec, comp)) {
 
343
                row_ext_t*      ext;
 
344
 
 
345
                /* The stack of versions is locked by mtr.
 
346
                Thus, it is safe to fetch the prefixes for
 
347
                externally stored columns. */
332
348
                row = row_build(ROW_COPY_POINTERS, clust_index,
333
 
                                rec, clust_offsets, heap);
334
 
                entry = row_build_index_entry(row, index, heap);
 
349
                                rec, clust_offsets, NULL, &ext, heap);
 
350
                entry = row_build_index_entry(row, ext, index, heap);
 
351
 
 
352
                /* If entry == NULL, the record contains unset BLOB
 
353
                pointers.  This must be a freshly inserted record.  If
 
354
                this is called from
 
355
                row_purge_remove_sec_if_poss_low(), the thread will
 
356
                hold latches on the clustered index and the secondary
 
357
                index.  Because the insert works in three steps:
 
358
 
 
359
                        (1) insert the record to clustered index
 
360
                        (2) store the BLOBs and update BLOB pointers
 
361
                        (3) insert records to secondary indexes
 
362
 
 
363
                the purge thread can safely ignore freshly inserted
 
364
                records and delete the secondary index record.  The
 
365
                thread that inserted the new record will be inserting
 
366
                the secondary index records. */
335
367
 
336
368
                /* NOTE that we cannot do the comparison as binary
337
369
                fields because the row is maybe being modified so that
338
 
                the clustered index record has already been updated
339
 
                to a different binary value in a char field, but the
 
370
                the clustered index record has already been updated to
 
371
                a different binary value in a char field, but the
340
372
                collation identifies the old and new value anyway! */
341
 
 
342
 
                if (dtuple_datas_are_ordering_equal(ientry, entry)) {
 
373
                if (entry && !dtuple_coll_cmp(ientry, entry)) {
343
374
 
344
375
                        mem_heap_free(heap);
345
376
 
369
400
                                                NULL, ULINT_UNDEFINED, &heap);
370
401
 
371
402
                if (!rec_get_deleted_flag(prev_version, comp)) {
 
403
                        row_ext_t*      ext;
 
404
 
 
405
                        /* The stack of versions is locked by mtr.
 
406
                        Thus, it is safe to fetch the prefixes for
 
407
                        externally stored columns. */
372
408
                        row = row_build(ROW_COPY_POINTERS, clust_index,
373
 
                                        prev_version, clust_offsets, heap);
374
 
                        entry = row_build_index_entry(row, index, heap);
 
409
                                        prev_version, clust_offsets,
 
410
                                        NULL, &ext, heap);
 
411
                        entry = row_build_index_entry(row, ext, index, heap);
 
412
 
 
413
                        /* If entry == NULL, the record contains unset
 
414
                        BLOB pointers.  This must be a freshly
 
415
                        inserted record that we can safely ignore.
 
416
                        For the justification, see the comments after
 
417
                        the previous row_build_index_entry() call. */
375
418
 
376
419
                        /* NOTE that we cannot do the comparison as binary
377
420
                        fields because maybe the secondary index record has
379
422
                        a char field, but the collation identifies the old
380
423
                        and new value anyway! */
381
424
 
382
 
                        if (dtuple_datas_are_ordering_equal(ientry, entry)) {
 
425
                        if (entry && !dtuple_coll_cmp(ientry, entry)) {
383
426
 
384
427
                                mem_heap_free(heap);
385
428
 
395
438
Constructs the version of a clustered index record which a consistent
396
439
read should see. We assume that the trx id stored in rec is such that
397
440
the consistent read should not see rec in its present version. */
398
 
 
 
441
UNIV_INTERN
399
442
ulint
400
443
row_vers_build_for_consistent_read(
401
444
/*===============================*/
402
445
                                /* out: DB_SUCCESS or DB_MISSING_HISTORY */
403
 
        rec_t*          rec,    /* in: record in a clustered index; the
 
446
        const rec_t*    rec,    /* in: record in a clustered index; the
404
447
                                caller must have a latch on the page; this
405
448
                                latch locks the top of the stack of versions
406
449
                                of this records */
412
455
        mem_heap_t**    offset_heap,/* in/out: memory heap from which
413
456
                                the offsets are allocated */
414
457
        mem_heap_t*     in_heap,/* in: memory heap from which the memory for
415
 
                                old_vers is allocated; memory for possible
 
458
                                *old_vers is allocated; memory for possible
416
459
                                intermediate versions is allocated and freed
417
460
                                locally within the function */
418
461
        rec_t**         old_vers)/* out, own: old version, or NULL if the
419
462
                                record does not exist in the view, that is,
420
463
                                it was freshly inserted afterwards */
421
464
{
422
 
        rec_t*          version;
 
465
        const rec_t*    version;
423
466
        rec_t*          prev_version;
424
467
        dulint          trx_id;
425
468
        mem_heap_t*     heap            = NULL;
426
469
        byte*           buf;
427
470
        ulint           err;
428
471
 
429
 
        ut_ad(index->type & DICT_CLUSTERED);
430
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
431
 
              || mtr_memo_contains(mtr, buf_block_align(rec),
432
 
                                   MTR_MEMO_PAGE_S_FIX));
 
472
        ut_ad(dict_index_is_clust(index));
 
473
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
474
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
433
475
#ifdef UNIV_SYNC_DEBUG
434
476
        ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
435
477
#endif /* UNIV_SYNC_DEBUG */
528
570
/*********************************************************************
529
571
Constructs the last committed version of a clustered index record,
530
572
which should be seen by a semi-consistent read. */
531
 
 
 
573
UNIV_INTERN
532
574
ulint
533
575
row_vers_build_for_semi_consistent_read(
534
576
/*====================================*/
535
577
                                /* out: DB_SUCCESS or DB_MISSING_HISTORY */
536
 
        rec_t*          rec,    /* in: record in a clustered index; the
 
578
        const rec_t*    rec,    /* in: record in a clustered index; the
537
579
                                caller must have a latch on the page; this
538
580
                                latch locks the top of the stack of versions
539
581
                                of this records */
544
586
        mem_heap_t**    offset_heap,/* in/out: memory heap from which
545
587
                                the offsets are allocated */
546
588
        mem_heap_t*     in_heap,/* in: memory heap from which the memory for
547
 
                                old_vers is allocated; memory for possible
 
589
                                *old_vers is allocated; memory for possible
548
590
                                intermediate versions is allocated and freed
549
591
                                locally within the function */
550
 
        rec_t**         old_vers)/* out, own: rec, old version, or NULL if the
 
592
        const rec_t**   old_vers)/* out: rec, old version, or NULL if the
551
593
                                record does not exist in the view, that is,
552
594
                                it was freshly inserted afterwards */
553
595
{
554
 
        rec_t*          version;
 
596
        const rec_t*    version;
555
597
        mem_heap_t*     heap            = NULL;
556
598
        byte*           buf;
557
599
        ulint           err;
558
 
        dulint          rec_trx_id      = ut_dulint_create(0, 0);
 
600
        dulint          rec_trx_id      = ut_dulint_zero;
559
601
 
560
 
        ut_ad(index->type & DICT_CLUSTERED);
561
 
        ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
562
 
              || mtr_memo_contains(mtr, buf_block_align(rec),
563
 
                                   MTR_MEMO_PAGE_S_FIX));
 
602
        ut_ad(dict_index_is_clust(index));
 
603
        ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
 
604
              || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
564
605
#ifdef UNIV_SYNC_DEBUG
565
606
        ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
566
607
#endif /* UNIV_SYNC_DEBUG */