From ffc0bc3eaf9ea45341462ebf16f8b70f2e2b74ea Mon Sep 17 00:00:00 2001 From: marko <Unknown> Date: Thu, 18 Jan 2007 14:02:56 +0000 Subject: [PATCH] branches/zip: Free buffer blocks that are no longer needed for BLOB storage. btr_blob_free(): New function to commit a mini-transaction and to free an uncompressed BLOB block, or the entire block. btr_store_big_rec_extern_fields(): Replace the existing code with btr_blob_free(). The old code may have contained a race condition. btr_free_externally_stored_field(): Completely free the buffer blocks allocated for the freed BLOB. --- btr/btr0cur.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/btr/btr0cur.c b/btr/btr0cur.c index 1235fb8d04..a10255d717 100644 --- a/btr/btr0cur.c +++ b/btr/btr0cur.c @@ -3581,6 +3581,48 @@ btr_blob_get_next_page_no( return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO)); } +/*********************************************************************** +Deallocate a buffer block that was reserved for a BLOB part. */ +static +void +btr_blob_free( +/*==========*/ + buf_block_t* block, /* in: buffer block */ + ibool all, /* in: TRUE=remove also the compressed page + if there is one */ + mtr_t* mtr) /* in: mini-transaction to commit */ +{ + ulint space = buf_block_get_space(block); + ulint page_no = buf_block_get_page_no(block); + + ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + + mtr_commit(mtr); + + mutex_enter(&buf_pool->mutex); + mutex_enter(&block->mutex); + + /* Only free the block if it is still allocated to + the same file page. */ + + if (buf_block_get_state(block) + == BUF_BLOCK_FILE_PAGE + && buf_block_get_space(block) == space + && buf_block_get_page_no(block) == page_no) { + + if (!buf_LRU_free_block(&block->page, all) + && all && block->page.zip.data) { + /* Attempt to deallocate the uncompressed page + if the whole block cannot be deallocted. */ + + buf_LRU_free_block(&block->page, FALSE); + } + } + + mutex_exit(&buf_pool->mutex); + mutex_exit(&block->mutex); +} + /*********************************************************************** Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec. The extern flags in rec will have to be set beforehand. @@ -3838,15 +3880,9 @@ btr_store_big_rec_extern_fields( next_zip_page: prev_page_no = page_no; - mtr_commit(&mtr); - - /* Release the uncompressed page frame - to save memory. */ - mutex_enter(&buf_pool->mutex); - mutex_enter(&block->mutex); - buf_LRU_free_block(&block->page, FALSE); - mutex_exit(&buf_pool->mutex); - mutex_exit(&block->mutex); + /* Commit mtr and release the + uncompressed page frame to save memory. */ + btr_blob_free(block, FALSE, &mtr); if (err == Z_STREAM_END) { break; @@ -4100,7 +4136,8 @@ btr_free_externally_stored_field( } } - mtr_commit(&mtr); + /* Commit mtr and release the BLOB block to save memory. */ + btr_blob_free(ext_block, TRUE, &mtr); } } -- 2.30.9