diff options
author | Marko Mäkelä <marko.makela@oracle.com> | 2012-08-16 18:47:26 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@oracle.com> | 2012-08-16 18:47:26 +0300 |
commit | 82d2bc3df441adda634f43f1b90a1cdf2dc5b6bc (patch) | |
tree | 8e80bc79e0cffd77c9c243cd834f68775eb03b20 | |
parent | 37d22846c1ebdebab98580ac693deb72ab68c28a (diff) | |
parent | a5ddcaab7492ff2a2150adb64d5921eecefc24b2 (diff) | |
download | mariadb-git-82d2bc3df441adda634f43f1b90a1cdf2dc5b6bc.tar.gz |
Merge mysql-5.1 to mysql-5.5.
-rw-r--r-- | storage/innobase/btr/btr0btr.c | 21 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.c | 39 | ||||
-rw-r--r-- | storage/innobase/page/page0page.c | 21 |
3 files changed, 48 insertions, 33 deletions
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index b714219e304..c9dc9e20072 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1844,6 +1844,7 @@ btr_root_raise_and_insert( root = btr_cur_get_page(cursor); root_block = btr_cur_get_block(cursor); root_page_zip = buf_block_get_page_zip(root_block); + ut_ad(page_get_n_recs(root) > 0); #ifdef UNIV_ZIP_DEBUG ut_a(!root_page_zip || page_zip_validate(root_page_zip, root)); #endif /* UNIV_ZIP_DEBUG */ @@ -2324,12 +2325,20 @@ btr_insert_on_non_leaf_level_func( BTR_CONT_MODIFY_TREE, &cursor, 0, file, line, mtr); - err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG - | BTR_KEEP_SYS_FLAG - | BTR_NO_UNDO_LOG_FLAG, - &cursor, tuple, &rec, - &dummy_big_rec, 0, NULL, mtr); - ut_a(err == DB_SUCCESS); + ut_ad(cursor.flag == BTR_CUR_BINARY); + + err = btr_cur_optimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG + | BTR_NO_UNDO_LOG_FLAG, &cursor, tuple, &rec, + &dummy_big_rec, 0, NULL, mtr); + + if (err == DB_FAIL) { + err = btr_cur_pessimistic_insert( + BTR_NO_LOCKING_FLAG | BTR_KEEP_SYS_FLAG + | BTR_NO_UNDO_LOG_FLAG, + &cursor, tuple, &rec, &dummy_big_rec, 0, NULL, mtr); + ut_a(err == DB_SUCCESS); + } } /**************************************************************//** diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 9c61e0cf763..ce43cba8525 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -1323,7 +1323,12 @@ fail_err: if (UNIV_UNLIKELY(reorg)) { ut_a(zip_size); - ut_a(*rec); + /* It's possible for rec to be NULL if the + page is compressed. This is because a + reorganized page may become incompressible. */ + if (!*rec) { + goto fail; + } } } @@ -1459,20 +1464,9 @@ btr_cur_pessimistic_insert( ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor), MTR_MEMO_PAGE_X_FIX)); - /* Try first an optimistic insert; reset the cursor flag: we do not - assume anything of how it was positioned */ - cursor->flag = BTR_CUR_BINARY; - err = btr_cur_optimistic_insert(flags, cursor, entry, rec, - big_rec, n_ext, thr, mtr); - if (err != DB_FAIL) { - - return(err); - } - - /* Retry with a pessimistic insert. Check locks and write to undo log, - if specified */ + /* Check locks and write to undo log, if specified */ err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, mtr, &dummy_inh); @@ -2076,8 +2070,12 @@ any_extern: goto err_exit; } - max_size = old_rec_size - + page_get_max_insert_size_after_reorganize(page, 1); + /* We do not attempt to reorganize if the page is compressed. + This is because the page may fail to compress after reorganization. */ + max_size = page_zip + ? page_get_max_insert_size(page, 1) + : (old_rec_size + + page_get_max_insert_size_after_reorganize(page, 1)); if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT) && (max_size >= new_rec_size)) @@ -2433,7 +2431,12 @@ make_external: err = DB_SUCCESS; goto return_after_reservations; } else { - ut_a(optim_err != DB_UNDERFLOW); + /* If the page is compressed and it initially + compresses very well, and there is a subsequent insert + of a badly-compressing record, it is possible for + btr_cur_optimistic_update() to return DB_UNDERFLOW and + btr_cur_insert_if_possible() to return FALSE. */ + ut_a(page_zip || optim_err != DB_UNDERFLOW); /* Out of space: reset the free bits. */ if (!dict_index_is_clust(index) @@ -2462,7 +2465,9 @@ make_external: was_first = page_cur_is_before_first(page_cursor); /* Lock checks and undo logging were already performed by - btr_cur_upd_lock_and_undo(). */ + btr_cur_upd_lock_and_undo(). We do not try + btr_cur_optimistic_insert() because + btr_cur_insert_if_possible() already failed above. */ err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c index 5f0380cb55f..946ec0e1c43 100644 --- a/storage/innobase/page/page0page.c +++ b/storage/innobase/page/page0page.c @@ -781,12 +781,18 @@ page_copy_rec_list_start( if (UNIV_LIKELY_NULL(new_page_zip)) { mtr_set_log_mode(mtr, log_mode); + DBUG_EXECUTE_IF("page_copy_rec_list_start_compress_fail", + goto zip_reorganize;); + if (UNIV_UNLIKELY (!page_zip_compress(new_page_zip, new_page, index, mtr))) { + ulint ret_pos; +#ifndef DBUG_OFF +zip_reorganize: +#endif /* DBUG_OFF */ /* Before trying to reorganize the page, store the number of preceding records on the page. */ - ulint ret_pos - = page_rec_get_n_recs_before(ret); + ret_pos = page_rec_get_n_recs_before(ret); /* Before copying, "ret" was the predecessor of the predefined supremum record. If it was the predefined infimum record, then it would @@ -807,15 +813,10 @@ page_copy_rec_list_start( btr_blob_dbg_add(new_page, index, "copy_start_reorg_fail"); return(NULL); - } else { - /* The page was reorganized: - Seek to ret_pos. */ - ret = new_page + PAGE_NEW_INFIMUM; - - do { - ret = rec_get_next_ptr(ret, TRUE); - } while (--ret_pos); } + + /* The page was reorganized: Seek to ret_pos. */ + ret = page_rec_get_nth(new_page, ret_pos); } } |