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

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/trx/trx0rec.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) 1996, 2010, 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
1097
1097
#endif /* !UNIV_HOTBACKUP */
1098
1098
 
1099
1099
/***********************************************************************//**
1100
 
Erases the unused undo log page end. */
1101
 
static
1102
 
void
 
1100
Erases the unused undo log page end.
 
1101
@return TRUE if the page contained something, FALSE if it was empty */
 
1102
static __attribute__((nonnull))
 
1103
ibool
1103
1104
trx_undo_erase_page_end(
1104
1105
/*====================*/
1105
 
        page_t* undo_page,      /*!< in: undo page whose end to erase */
1106
 
        mtr_t*  mtr)            /*!< in: mtr */
 
1106
        page_t* undo_page,      /*!< in/out: undo page whose end to erase */
 
1107
        mtr_t*  mtr)            /*!< in/out: mini-transaction */
1107
1108
{
1108
1109
        ulint   first_free;
1109
1110
 
1113
1114
               (UNIV_PAGE_SIZE - FIL_PAGE_DATA_END) - first_free);
1114
1115
 
1115
1116
        mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
 
1117
        return(first_free != TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
1116
1118
}
1117
1119
 
1118
1120
/***********************************************************//**
1180
1182
        mem_heap_t*     heap            = NULL;
1181
1183
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1182
1184
        ulint*          offsets         = offsets_;
 
1185
#ifdef UNIV_DEBUG
 
1186
        int             loop_count      = 0;
 
1187
#endif /* UNIV_DEBUG */
1183
1188
        rec_offs_init(offsets_);
1184
1189
 
1185
1190
        ut_a(dict_index_is_clust(index));
1242
1247
 
1243
1248
        mtr_start(&mtr);
1244
1249
 
1245
 
        for (;;) {
 
1250
        do {
1246
1251
                buf_block_t*    undo_block;
1247
1252
                page_t*         undo_page;
1248
1253
                ulint           offset;
1271
1276
                        version the replicate page constructed using the log
1272
1277
                        records stays identical to the original page */
1273
1278
 
1274
 
                        trx_undo_erase_page_end(undo_page, &mtr);
 
1279
                        if (!trx_undo_erase_page_end(undo_page, &mtr)) {
 
1280
                                /* The record did not fit on an empty
 
1281
                                undo page. Discard the freshly allocated
 
1282
                                page and return an error. */
 
1283
 
 
1284
                                /* When we remove a page from an undo
 
1285
                                log, this is analogous to a
 
1286
                                pessimistic insert in a B-tree, and we
 
1287
                                must reserve the counterpart of the
 
1288
                                tree latch, which is the rseg
 
1289
                                mutex. We must commit the mini-transaction
 
1290
                                first, because it may be holding lower-level
 
1291
                                latches, such as SYNC_FSP and SYNC_FSP_PAGE. */
 
1292
 
 
1293
                                mtr_commit(&mtr);
 
1294
                                mtr_start(&mtr);
 
1295
 
 
1296
                                mutex_enter(&rseg->mutex);
 
1297
                                trx_undo_free_last_page(trx, undo, &mtr);
 
1298
                                mutex_exit(&rseg->mutex);
 
1299
 
 
1300
                                err = DB_TOO_BIG_RECORD;
 
1301
                                goto err_exit;
 
1302
                        }
 
1303
 
1275
1304
                        mtr_commit(&mtr);
1276
1305
                } else {
1277
1306
                        /* Success */
1291
1320
                        *roll_ptr = trx_undo_build_roll_ptr(
1292
1321
                                op_type == TRX_UNDO_INSERT_OP,
1293
1322
                                rseg->id, page_no, offset);
1294
 
                        if (UNIV_LIKELY_NULL(heap)) {
1295
 
                                mem_heap_free(heap);
1296
 
                        }
1297
 
                        return(DB_SUCCESS);
 
1323
                        err = DB_SUCCESS;
 
1324
                        goto func_exit;
1298
1325
                }
1299
1326
 
1300
1327
                ut_ad(page_no == undo->last_page_no);
1301
1328
 
1302
1329
                /* We have to extend the undo log by one page */
1303
1330
 
 
1331
                ut_ad(++loop_count < 2);
1304
1332
                mtr_start(&mtr);
1305
1333
 
1306
1334
                /* When we add a page to an undo log, this is analogous to
1312
1340
                page_no = trx_undo_add_page(trx, undo, &mtr);
1313
1341
 
1314
1342
                mutex_exit(&(rseg->mutex));
1315
 
 
1316
 
                if (UNIV_UNLIKELY(page_no == FIL_NULL)) {
1317
 
                        /* Did not succeed: out of space */
1318
 
 
1319
 
                        mutex_exit(&(trx->undo_mutex));
1320
 
                        mtr_commit(&mtr);
1321
 
                        if (UNIV_LIKELY_NULL(heap)) {
1322
 
                                mem_heap_free(heap);
1323
 
                        }
1324
 
                        return(DB_OUT_OF_FILE_SPACE);
1325
 
                }
 
1343
        } while (UNIV_LIKELY(page_no != FIL_NULL));
 
1344
 
 
1345
        /* Did not succeed: out of space */
 
1346
        err = DB_OUT_OF_FILE_SPACE;
 
1347
 
 
1348
err_exit:
 
1349
        mutex_exit(&trx->undo_mutex);
 
1350
        mtr_commit(&mtr);
 
1351
func_exit:
 
1352
        if (UNIV_LIKELY_NULL(heap)) {
 
1353
                mem_heap_free(heap);
1326
1354
        }
 
1355
        return(err);
1327
1356
}
1328
1357
 
1329
1358
/*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/
1577
1606
                return(DB_ERROR);
1578
1607
        }
1579
1608
 
 
1609
# if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
 
1610
        ut_a(!rec_offs_any_null_extern(rec, offsets));
 
1611
# endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
 
1612
 
1580
1613
        if (row_upd_changes_field_size_or_external(index, offsets, update)) {
1581
1614
                ulint   n_ext;
1582
1615