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

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/trx/trx0undo.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 14:16:05 UTC
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: package-import@ubuntu.com-20120222141605-nxlu9yzc6attylc2
Tags: upstream-5.1.61
ImportĀ upstreamĀ versionĀ 5.1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1996, 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
36
36
#include "trx0rseg.h"
37
37
#include "trx0trx.h"
38
38
#include "srv0srv.h"
 
39
#include "srv0start.h"
39
40
#include "trx0rec.h"
40
41
#include "trx0purge.h"
41
42
 
997
998
}
998
999
 
999
1000
/********************************************************************//**
1000
 
Frees an undo log page when there is also the memory object for the undo
1001
 
log. */
1002
 
static
 
1001
Frees the last undo log page.
 
1002
The caller must hold the rollback segment mutex. */
 
1003
UNIV_INTERN
1003
1004
void
1004
 
trx_undo_free_page_in_rollback(
1005
 
/*===========================*/
1006
 
        trx_t*          trx __attribute__((unused)), /*!< in: transaction */
1007
 
        trx_undo_t*     undo,   /*!< in: undo log memory copy */
1008
 
        ulint           page_no,/*!< in: page number to free: must not be the
1009
 
                                header page */
1010
 
        mtr_t*          mtr)    /*!< in: mtr which does not have a latch to any
1011
 
                                undo log page; the caller must have reserved
1012
 
                                the rollback segment mutex */
 
1005
trx_undo_free_last_page_func(
 
1006
/*==========================*/
 
1007
#ifdef UNIV_DEBUG
 
1008
        const trx_t*    trx,    /*!< in: transaction */
 
1009
#endif /* UNIV_DEBUG */
 
1010
        trx_undo_t*     undo,   /*!< in/out: undo log memory copy */
 
1011
        mtr_t*          mtr)    /*!< in/out: mini-transaction which does not
 
1012
                                have a latch to any undo log page or which
 
1013
                                has allocated the undo log page */
1013
1014
{
1014
 
        ulint   last_page_no;
1015
 
 
1016
 
        ut_ad(undo->hdr_page_no != page_no);
1017
 
        ut_ad(mutex_own(&(trx->undo_mutex)));
1018
 
 
1019
 
        last_page_no = trx_undo_free_page(undo->rseg, FALSE, undo->space,
1020
 
                                          undo->hdr_page_no, page_no, mtr);
1021
 
 
1022
 
        undo->last_page_no = last_page_no;
 
1015
        ut_ad(mutex_own(&trx->undo_mutex));
 
1016
        ut_ad(undo->hdr_page_no != undo->last_page_no);
 
1017
        ut_ad(undo->size > 0);
 
1018
 
 
1019
        undo->last_page_no = trx_undo_free_page(
 
1020
                undo->rseg, FALSE, undo->space,
 
1021
                undo->hdr_page_no, undo->last_page_no, mtr);
 
1022
 
1023
1023
        undo->size--;
1024
1024
}
1025
1025
 
1055
1055
to free space from an undo log. */
1056
1056
UNIV_INTERN
1057
1057
void
1058
 
trx_undo_truncate_end(
1059
 
/*==================*/
1060
 
        trx_t*          trx,    /*!< in: transaction whose undo log it is */
 
1058
trx_undo_truncate_end_func(
 
1059
/*=======================*/
 
1060
#ifdef UNIV_DEBUG
 
1061
        const trx_t*    trx,    /*!< in: transaction whose undo log it is */
 
1062
#endif /* UNIV_DEBUG */
1061
1063
        trx_undo_t*     undo,   /*!< in: undo log */
1062
1064
        undo_no_t       limit)  /*!< in: all undo records with undo number
1063
1065
                                >= this value should be truncated */
1066
1068
        ulint           last_page_no;
1067
1069
        trx_undo_rec_t* rec;
1068
1070
        trx_undo_rec_t* trunc_here;
1069
 
        trx_rseg_t*     rseg;
1070
1071
        mtr_t           mtr;
1071
1072
 
1072
1073
        ut_ad(mutex_own(&(trx->undo_mutex)));
1073
1074
        ut_ad(mutex_own(&(trx->rseg->mutex)));
1074
1075
 
1075
 
        rseg = trx->rseg;
1076
 
 
1077
1076
        for (;;) {
1078
1077
                mtr_start(&mtr);
1079
1078
 
1086
1085
 
1087
1086
                rec = trx_undo_page_get_last_rec(undo_page, undo->hdr_page_no,
1088
1087
                                                 undo->hdr_offset);
1089
 
                for (;;) {
1090
 
                        if (rec == NULL) {
1091
 
                                if (last_page_no == undo->hdr_page_no) {
1092
 
 
1093
 
                                        goto function_exit;
1094
 
                                }
1095
 
 
1096
 
                                trx_undo_free_page_in_rollback(
1097
 
                                        trx, undo, last_page_no, &mtr);
1098
 
                                break;
1099
 
                        }
1100
 
 
 
1088
                while (rec) {
1101
1089
                        if (ut_dulint_cmp(trx_undo_rec_get_undo_no(rec), limit)
1102
1090
                            >= 0) {
1103
1091
                                /* Truncate at least this record off, maybe
1112
1100
                                                         undo->hdr_offset);
1113
1101
                }
1114
1102
 
 
1103
                if (last_page_no == undo->hdr_page_no) {
 
1104
 
 
1105
                        goto function_exit;
 
1106
                }
 
1107
 
 
1108
                ut_ad(last_page_no == undo->last_page_no);
 
1109
                trx_undo_free_last_page(trx, undo, &mtr);
 
1110
 
1115
1111
                mtr_commit(&mtr);
1116
1112
        }
1117
1113
 
1826
1822
 
1827
1823
        if (undo->size == 1
1828
1824
            && mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
1829
 
               < TRX_UNDO_PAGE_REUSE_LIMIT) {
1830
 
 
1831
 
                /* This is a heuristic to avoid the problem of all UNDO
1832
 
                slots ending up in one of the UNDO lists. Previously if
1833
 
                the server crashed with all the slots in one of the lists,
1834
 
                transactions that required the slots of a different type
1835
 
                would fail for lack of slots. */
1836
 
 
1837
 
                if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
1838
 
                    && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
1839
 
 
1840
 
                        state = TRX_UNDO_CACHED;
1841
 
                } else {
1842
 
                        state = TRX_UNDO_TO_FREE;
1843
 
                }
 
1825
               < TRX_UNDO_PAGE_REUSE_LIMIT
 
1826
            && UT_LIST_GET_LEN(rseg->update_undo_list) < 500
 
1827
            && UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
 
1828
 
 
1829
                state = TRX_UNDO_CACHED;
1844
1830
 
1845
1831
        } else if (undo->type == TRX_UNDO_INSERT) {
1846
1832
 
1868
1854
        mtr_t*          mtr)    /*!< in: mtr */
1869
1855
{
1870
1856
        trx_usegf_t*    seg_hdr;
1871
 
        trx_upagef_t*   page_hdr;
1872
1857
        trx_ulogf_t*    undo_header;
1873
1858
        page_t*         undo_page;
1874
1859
        ulint           offset;
1886
1871
                                      undo->hdr_page_no, mtr);
1887
1872
 
1888
1873
        seg_hdr = undo_page + TRX_UNDO_SEG_HDR;
1889
 
        page_hdr = undo_page + TRX_UNDO_PAGE_HDR;
1890
1874
 
1891
1875
        /*------------------------------*/
1892
1876
        undo->state = TRX_UNDO_PREPARED;
1938
1922
 
1939
1923
                UT_LIST_ADD_FIRST(undo_list, rseg->update_undo_cached, undo);
1940
1924
        } else {
1941
 
                ut_ad(undo->state == TRX_UNDO_TO_PURGE);
 
1925
                ut_ad(undo->state == TRX_UNDO_TO_PURGE
 
1926
                      || undo->state == TRX_UNDO_TO_FREE);
1942
1927
 
1943
1928
                trx_undo_mem_free(undo);
1944
1929
        }
1990
1975
 
1991
1976
        mutex_exit(&(rseg->mutex));
1992
1977
}
 
1978
 
 
1979
/********************************************************************//**
 
1980
At shutdown, frees the undo logs of a PREPARED transaction. */
 
1981
UNIV_INTERN
 
1982
void
 
1983
trx_undo_free_prepared(
 
1984
/*===================*/
 
1985
        trx_t*  trx)    /*!< in/out: PREPARED transaction */
 
1986
{
 
1987
        ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
 
1988
 
 
1989
        if (trx->update_undo) {
 
1990
                ut_a(trx->update_undo->state == TRX_UNDO_PREPARED);
 
1991
                UT_LIST_REMOVE(undo_list, trx->rseg->update_undo_list,
 
1992
                               trx->update_undo);
 
1993
                trx_undo_mem_free(trx->update_undo);
 
1994
        }
 
1995
        if (trx->insert_undo) {
 
1996
                ut_a(trx->insert_undo->state == TRX_UNDO_PREPARED);
 
1997
                UT_LIST_REMOVE(undo_list, trx->rseg->insert_undo_list,
 
1998
                               trx->insert_undo);
 
1999
                trx_undo_mem_free(trx->insert_undo);
 
2000
        }
 
2001
}
1993
2002
#endif /* !UNIV_HOTBACKUP */