diff --git a/handler/i_s.cc b/handler/i_s.cc index 01a21180f63..c37a26935da 100644 --- a/handler/i_s.cc +++ b/handler/i_s.cc @@ -1033,6 +1033,14 @@ static ST_FIELD_INFO i_s_zip_fields_info[] = STRUCT_FLD(old_name, "Currently in Use"), STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + {STRUCT_FLD(field_name, "free"), + STRUCT_FLD(field_length, 21), + STRUCT_FLD(field_type, MYSQL_TYPE_LONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, "Currently Available"), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + END_OF_ST_FIELD_INFO }; @@ -1096,6 +1104,9 @@ i_s_zip_fill_low( table->field[4]->store(0); } table->field[5]->store(buf_buddy_used[x]); + table->field[6]->store(UNIV_LIKELY(x < BUF_BUDDY_SIZES) + ? UT_LIST_GET_LEN(buf_pool->zip_free[x]) + : 0); if (schema_table_store_record(thd, table)) { status = 1; diff --git a/ibuf/ibuf0ibuf.c b/ibuf/ibuf0ibuf.c index 00c804247ba..118857e7e0e 100644 --- a/ibuf/ibuf0ibuf.c +++ b/ibuf/ibuf0ibuf.c @@ -955,8 +955,8 @@ UNIV_INTERN void ibuf_update_free_bits_zip( /*======================*/ - const buf_block_t* block, /* in: index page */ - mtr_t* mtr) /* in/out: mtr */ + buf_block_t* block, /* in/out: index page */ + mtr_t* mtr) /* in/out: mtr */ { page_t* bitmap_page; ulint space; @@ -974,6 +974,16 @@ ibuf_update_free_bits_zip( bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr); after = ibuf_index_page_calc_free_zip(zip_size, block); + + if (after == 0) { + /* We move the page to the front of the buffer pool LRU list: + the purpose of this is to prevent those pages to which we + cannot make inserts using the insert buffer from slipping + out of the buffer pool */ + + buf_page_make_young(&block->page); + } + ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size, IBUF_BITMAP_FREE, after, mtr); } diff --git a/include/db0err.h b/include/db0err.h index e031c54140a..bbf57ce1bb2 100644 --- a/include/db0err.h +++ b/include/db0err.h @@ -25,7 +25,7 @@ enum db_err { DB_MISSING_HISTORY, /* required history data has been deleted due to lack of space in rollback segment */ - DB_CLUSTER_NOT_FOUND, + DB_CLUSTER_NOT_FOUND = 30, DB_TABLE_NOT_FOUND, DB_MUST_GET_MORE_FILE_SPACE, /* the database has to be stopped and restarted with more file space */ @@ -67,23 +67,23 @@ enum db_err { preconfigured undo slots, this can only happen when there are too many concurrent transactions */ - DB_PRIMARY_KEY_IS_NULL, /* a column in the PRIMARY KEY - was found to be NULL */ - DB_TABLE_ZIP_NO_IBD, /* trying to create a compressed - table in the system tablespace */ - DB_UNSUPPORTED, /* when InnoDB sees any artefact or a feature that it can't recoginize or work with e.g., FT indexes created by a later version of the engine. */ + DB_PRIMARY_KEY_IS_NULL, /* a column in the PRIMARY KEY + was found to be NULL */ + DB_TABLE_ZIP_NO_IBD, /* trying to create a compressed + table in the system tablespace */ + /* The following are partial failure codes */ - DB_FAIL, + DB_FAIL = 1000, DB_OVERFLOW, DB_UNDERFLOW, DB_STRONG_FAIL, DB_ZIP_OVERFLOW, - DB_RECORD_NOT_FOUND, + DB_RECORD_NOT_FOUND = 1500, DB_END_OF_INDEX }; diff --git a/include/ibuf0ibuf.h b/include/ibuf0ibuf.h index b7b54a77a65..3c76532f130 100644 --- a/include/ibuf0ibuf.h +++ b/include/ibuf0ibuf.h @@ -110,8 +110,8 @@ UNIV_INTERN void ibuf_update_free_bits_zip( /*======================*/ - const buf_block_t* block, /* in: index page */ - mtr_t* mtr); /* in/out: mtr */ + buf_block_t* block, /* in/out: index page */ + mtr_t* mtr); /* in/out: mtr */ /************************************************************************** Updates the free bits for the two pages to reflect the present state. Does this in the mtr given, which means that the latching order rules virtually diff --git a/page/page0zip.c b/page/page0zip.c index 1fd005f4924..692e791b23d 100644 --- a/page/page0zip.c +++ b/page/page0zip.c @@ -658,10 +658,19 @@ page_zip_set_alloc( strm->opaque = heap; } -#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG +#if 0 || defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG +# define PAGE_ZIP_COMPRESS_DBG +#endif + +#ifdef PAGE_ZIP_COMPRESS_DBG /* Set this variable in a debugger to enable excessive logging in page_zip_compress(). */ UNIV_INTERN ibool page_zip_compress_dbg; +/* Set this variable in a debugger to enable +binary logging of the data passed to deflate(). +When this variable is nonzero, it will act +as a log file name generator. */ +UNIV_INTERN unsigned page_zip_compress_log; /************************************************************************** Wrapper for deflate(). Log the operation if page_zip_compress_dbg is set. */ @@ -669,6 +678,7 @@ static ibool page_zip_compress_deflate( /*======================*/ + FILE* logfile,/* in: log file, or NULL */ z_streamp strm, /* in/out: compressed stream for deflate() */ int flush) /* in: deflate() flushing method */ { @@ -676,6 +686,9 @@ page_zip_compress_deflate( if (UNIV_UNLIKELY(page_zip_compress_dbg)) { ut_print_buf(stderr, strm->next_in, strm->avail_in); } + if (UNIV_LIKELY_NULL(logfile)) { + fwrite(strm->next_in, 1, strm->avail_in, logfile); + } status = deflate(strm, flush); if (UNIV_UNLIKELY(page_zip_compress_dbg)) { fprintf(stderr, " -> %d\n", status); @@ -685,8 +698,13 @@ page_zip_compress_deflate( /* Redefine deflate(). */ # undef deflate -# define deflate page_zip_compress_deflate -#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ +# define deflate(strm, flush) page_zip_compress_deflate(logfile, strm, flush) +# define FILE_LOGFILE FILE* logfile, +# define LOGFILE logfile, +#else /* PAGE_ZIP_COMPRESS_DBG */ +# define FILE_LOGFILE +# define LOGFILE +#endif /* PAGE_ZIP_COMPRESS_DBG */ /************************************************************************** Compress the records of a node pointer page. */ @@ -695,6 +713,7 @@ int page_zip_compress_node_ptrs( /*========================*/ /* out: Z_OK, or a zlib error code */ + FILE_LOGFILE z_stream* c_stream, /* in/out: compressed page stream */ const rec_t** recs, /* in: dense page directory sorted by address */ @@ -759,6 +778,7 @@ int page_zip_compress_sec( /*==================*/ /* out: Z_OK, or a zlib error code */ + FILE_LOGFILE z_stream* c_stream, /* in/out: compressed page stream */ const rec_t** recs, /* in: dense page directory sorted by address */ @@ -803,6 +823,7 @@ int page_zip_compress_clust_ext( /*========================*/ /* out: Z_OK, or a zlib error code */ + FILE_LOGFILE z_stream* c_stream, /* in/out: compressed page stream */ const rec_t* rec, /* in: record */ const ulint* offsets, /* in: rec_get_offsets(rec) */ @@ -929,6 +950,7 @@ int page_zip_compress_clust( /*====================*/ /* out: Z_OK, or a zlib error code */ + FILE_LOGFILE z_stream* c_stream, /* in/out: compressed page stream */ const rec_t** recs, /* in: dense page directory sorted by address */ @@ -986,6 +1008,7 @@ page_zip_compress_clust( ut_ad(dict_index_is_clust(index)); err = page_zip_compress_clust_ext( + LOGFILE c_stream, rec, offsets, trx_id_col, deleted, storage, &externs, n_blobs); @@ -1081,6 +1104,9 @@ page_zip_compress( ulint* offsets = NULL; ulint n_blobs = 0; byte* storage;/* storage of uncompressed columns */ +#ifdef PAGE_ZIP_COMPRESS_DBG + FILE* logfile = NULL; +#endif ut_a(page_is_comp(page)); ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX); @@ -1113,18 +1139,41 @@ page_zip_compress( /* The dense directory excludes the infimum and supremum records. */ n_dense = page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW; -#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG +#ifdef PAGE_ZIP_COMPRESS_DBG if (UNIV_UNLIKELY(page_zip_compress_dbg)) { fprintf(stderr, "compress %p %p %lu %lu %lu\n", (void*) page_zip, (void*) page, page_is_leaf(page), n_fields, n_dense); } -#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ + if (UNIV_UNLIKELY(page_zip_compress_log)) { + /* Create a log file for every compression attempt. */ + char logfilename[9]; + ut_snprintf(logfilename, sizeof logfilename, + "%08x", page_zip_compress_log++); + logfile = fopen(logfilename, "wb"); + + if (logfile) { + /* Write the uncompressed page to the log. */ + fwrite(page, 1, UNIV_PAGE_SIZE, logfile); + /* Record the compressed size as zero. + This will be overwritten at successful exit. */ + putc(0, logfile); + putc(0, logfile); + putc(0, logfile); + putc(0, logfile); + } + } +#endif /* PAGE_ZIP_COMPRESS_DBG */ page_zip_compress_count[page_zip->ssize]++; if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE >= page_zip_get_size(page_zip))) { +#ifdef PAGE_ZIP_COMPRESS_DBG + if (logfile) { + fclose(logfile); + } +#endif /* PAGE_ZIP_COMPRESS_DBG */ return(FALSE); } @@ -1208,20 +1257,23 @@ page_zip_compress( if (UNIV_UNLIKELY(!n_dense)) { } else if (!page_is_leaf(page)) { /* This is a node pointer page. */ - err = page_zip_compress_node_ptrs(&c_stream, recs, n_dense, + err = page_zip_compress_node_ptrs(LOGFILE + &c_stream, recs, n_dense, index, storage, heap); if (UNIV_UNLIKELY(err != Z_OK)) { goto zlib_error; } } else if (UNIV_LIKELY(trx_id_col == ULINT_UNDEFINED)) { /* This is a leaf page in a secondary index. */ - err = page_zip_compress_sec(&c_stream, recs, n_dense); + err = page_zip_compress_sec(LOGFILE + &c_stream, recs, n_dense); if (UNIV_UNLIKELY(err != Z_OK)) { goto zlib_error; } } else { /* This is a leaf page in a clustered index. */ - err = page_zip_compress_clust(&c_stream, recs, n_dense, + err = page_zip_compress_clust(LOGFILE + &c_stream, recs, n_dense, index, &n_blobs, trx_id_col, buf_end - PAGE_ZIP_DIR_SLOT_SIZE * page_get_n_recs(page), @@ -1248,6 +1300,11 @@ page_zip_compress( zlib_error: deflateEnd(&c_stream); mem_heap_free(heap); +#ifdef PAGE_ZIP_COMPRESS_DBG + if (logfile) { + fclose(logfile); + } +#endif /* PAGE_ZIP_COMPRESS_DBG */ return(FALSE); } @@ -1295,6 +1352,16 @@ zlib_error: UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip)); +#ifdef PAGE_ZIP_COMPRESS_DBG + if (logfile) { + /* Record the compressed size of the block. */ + byte sz[4]; + mach_write_to_4(sz, c_stream.total_out); + fseek(logfile, UNIV_PAGE_SIZE, SEEK_SET); + fwrite(sz, 1, sizeof sz, logfile); + fclose(logfile); + } +#endif /* PAGE_ZIP_COMPRESS_DBG */ return(TRUE); }