~ubuntu-branches/ubuntu/natty/mysql-5.1/natty-proposed

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/row/row0purge.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
13
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
 
Place, Suite 330, Boston, MA 02111-1307 USA
 
14
this program; if not, write to the Free Software Foundation, Inc.,
 
15
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
387
387
marked record if that record contained an externally stored field. */
388
388
static
389
389
void
390
 
row_purge_upd_exist_or_extern(
391
 
/*==========================*/
 
390
row_purge_upd_exist_or_extern_func(
 
391
/*===============================*/
 
392
#ifdef UNIV_DEBUG
 
393
        const que_thr_t*thr,    /*!< in: query thread */
 
394
#endif /* UNIV_DEBUG */
392
395
        purge_node_t*   node)   /*!< in: row purge node */
393
396
{
394
397
        mem_heap_t*     heap;
403
406
 
404
407
        ut_ad(node);
405
408
 
406
 
        if (node->rec_type == TRX_UNDO_UPD_DEL_REC) {
 
409
        if (node->rec_type == TRX_UNDO_UPD_DEL_REC
 
410
            || (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
407
411
 
408
412
                goto skip_secondaries;
409
413
        }
413
417
        while (node->index != NULL) {
414
418
                index = node->index;
415
419
 
416
 
                if (row_upd_changes_ord_field_binary(NULL, node->index,
417
 
                                                     node->update)) {
 
420
                if (row_upd_changes_ord_field_binary(node->index, node->update,
 
421
                                                     thr, NULL, NULL)) {
418
422
                        /* Build the older version of the index entry */
419
423
                        entry = row_build_index_entry(node->row, NULL,
420
424
                                                      index, heap);
496
500
        }
497
501
}
498
502
 
 
503
#ifdef UNIV_DEBUG
 
504
# define row_purge_upd_exist_or_extern(thr,node)        \
 
505
        row_purge_upd_exist_or_extern_func(thr,node)
 
506
#else /* UNIV_DEBUG */
 
507
# define row_purge_upd_exist_or_extern(thr,node)        \
 
508
        row_purge_upd_exist_or_extern_func(node)
 
509
#endif /* UNIV_DEBUG */
 
510
 
499
511
/***********************************************************//**
500
512
Parses the row reference and other info in a modify undo log record.
501
513
@return TRUE if purge operation required: NOTE that then the CALLER
519
531
        roll_ptr_t      roll_ptr;
520
532
        ulint           info_bits;
521
533
        ulint           type;
522
 
        ulint           cmpl_info;
523
534
 
524
535
        ut_ad(node && thr);
525
536
 
526
537
        trx = thr_get_trx(thr);
527
538
 
528
 
        ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info,
529
 
                                    updated_extern, &undo_no, &table_id);
 
539
        ptr = trx_undo_rec_get_pars(
 
540
                node->undo_rec, &type, &node->cmpl_info,
 
541
                updated_extern, &undo_no, &table_id);
530
542
        node->rec_type = type;
531
543
 
532
544
        if (type == TRX_UNDO_UPD_DEL_REC && !(*updated_extern)) {
539
551
        node->table = NULL;
540
552
 
541
553
        if (type == TRX_UNDO_UPD_EXIST_REC
542
 
            && cmpl_info & UPD_NODE_NO_ORD_CHANGE && !(*updated_extern)) {
 
554
            && node->cmpl_info & UPD_NODE_NO_ORD_CHANGE
 
555
            && !(*updated_extern)) {
543
556
 
544
557
                /* Purge requires no changes to indexes: we may return */
545
558
 
589
602
 
590
603
        /* Read to the partial row the fields that occur in indexes */
591
604
 
592
 
        if (!(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
 
605
        if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
593
606
                ptr = trx_undo_rec_get_partial_row(
594
607
                        ptr, clust_index, &node->row,
595
608
                        type == TRX_UNDO_UPD_DEL_REC,
602
615
/***********************************************************//**
603
616
Fetches an undo log record and does the purge for the recorded operation.
604
617
If none left, or the current purge completed, returns the control to the
605
 
parent node, which is always a query thread node.
606
 
@return DB_SUCCESS if operation successfully completed, else error code */
607
 
static
608
 
ulint
 
618
parent node, which is always a query thread node. */
 
619
static __attribute__((nonnull))
 
620
void
609
621
row_purge(
610
622
/*======*/
611
623
        purge_node_t*   node,   /*!< in: row purge node */
612
624
        que_thr_t*      thr)    /*!< in: query thread */
613
625
{
614
 
        roll_ptr_t      roll_ptr;
615
 
        ibool           purge_needed;
616
626
        ibool           updated_extern;
617
 
        trx_t*          trx;
618
 
 
619
 
        ut_ad(node && thr);
620
 
 
621
 
        trx = thr_get_trx(thr);
622
 
 
623
 
        node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr,
624
 
                                                  &(node->reservation),
 
627
 
 
628
        ut_ad(node);
 
629
        ut_ad(thr);
 
630
 
 
631
        node->undo_rec = trx_purge_fetch_next_rec(&node->roll_ptr,
 
632
                                                  &node->reservation,
625
633
                                                  node->heap);
626
634
        if (!node->undo_rec) {
627
635
                /* Purge completed for this query thread */
628
636
 
629
637
                thr->run_node = que_node_get_parent(node);
630
638
 
631
 
                return(DB_SUCCESS);
632
 
        }
633
 
 
634
 
        node->roll_ptr = roll_ptr;
635
 
 
636
 
        if (node->undo_rec == &trx_purge_dummy_rec) {
637
 
                purge_needed = FALSE;
638
 
        } else {
639
 
                purge_needed = row_purge_parse_undo_rec(node, &updated_extern,
640
 
                                                        thr);
641
 
                /* If purge_needed == TRUE, we must also remember to unfreeze
642
 
                data dictionary! */
643
 
        }
644
 
 
645
 
        if (purge_needed) {
 
639
                return;
 
640
        }
 
641
 
 
642
        if (node->undo_rec != &trx_purge_dummy_rec
 
643
            && row_purge_parse_undo_rec(node, &updated_extern, thr)) {
646
644
                node->found_clust = FALSE;
647
645
 
648
646
                node->index = dict_table_get_next_index(
654
652
                } else if (updated_extern
655
653
                           || node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
656
654
 
657
 
                        row_purge_upd_exist_or_extern(node);
 
655
                        row_purge_upd_exist_or_extern(thr, node);
658
656
                }
659
657
 
660
658
                if (node->found_clust) {
661
659
                        btr_pcur_close(&(node->pcur));
662
660
                }
663
661
 
664
 
                row_mysql_unfreeze_data_dictionary(trx);
 
662
                row_mysql_unfreeze_data_dictionary(thr_get_trx(thr));
665
663
        }
666
664
 
667
665
        /* Do some cleanup */
669
667
        mem_heap_empty(node->heap);
670
668
 
671
669
        thr->run_node = node;
672
 
 
673
 
        return(DB_SUCCESS);
674
670
}
675
671
 
676
672
/***********************************************************//**
684
680
        que_thr_t*      thr)    /*!< in: query thread */
685
681
{
686
682
        purge_node_t*   node;
687
 
#ifdef UNIV_DEBUG
688
 
        ulint           err;
689
 
#endif /* UNIV_DEBUG */
690
683
 
691
684
        ut_ad(thr);
692
685
 
694
687
 
695
688
        ut_ad(que_node_get_type(node) == QUE_NODE_PURGE);
696
689
 
697
 
#ifdef UNIV_DEBUG
698
 
        err =
699
 
#endif /* UNIV_DEBUG */
700
690
        row_purge(node, thr);
701
691
 
702
 
        ut_ad(err == DB_SUCCESS);
703
 
 
704
692
        return(thr);
705
693
}