3658 Marko Mäkelä 2011-06-28
Bug#12595087 - 61191: Question about page_zip_available (clean up page0zip.c)
page_zip_dir_elems(): New function, refactored from page_zip_dir_size().
page_zip_dir_size(): Use page_zip_dir_elems()
page_zip_dir_start_offs(): New function: Gets an offset to the
compressed page trailer (the dense page directory), including deleted
records (the free list)
page_zip_dir_start_low(page_zip, n_dense): Constness-preserving
wrapper macro for page_zip_dir_start_offs().
page_zip_dir_start(page_zip): Constness-preserving
wrapper macro for page_zip_dir_start_offs().
page_zip_decompress_node_ptrs(), page_zip_decompress_clust(): Replace
a formula with a fully equivalent page_zip_dir_start_low() call.
page_zip_write_rec(), page_zip_parse_write_node_ptr(),
page_zip_write_node_ptr(), page_zip_write_trx_id_and_roll_ptr(),
page_zip_clear_rec(): Replace a formula with an almost equivalent
page_zip_dir_start() call.
It is OK to replace page_dir_get_n_heap(page) with
page_dir_get_n_heap(page_zip->data), because
ut_ad(page_zip_header_cmp(page_zip, page)) or
page_zip_validate(page_zip, page) asserts that the
page headers are identical.
rb:687 approved by Jimmy Yang
modified:
storage/innodb_plugin/page/page0zip.c
3657 Dmitry Shulga 2011-06-23
Fixed Bug#11756013 (formerly known as bug#47870):
BOGUS "THE TABLE MYSQL.PROC IS MISSING,..."
There was a race condition between loading a stored routine
(function/procedure/trigger) specified by fully qualified name
SCHEMA_NAME.PROC_NAME and dropping the stored routine database.
The problem was that there is a window for race condition when one server
thread tries to load a stored routine being executed and the other thread
tries to drop the stored routine schema.
This condition race window exists in implementation of function
mysql_change_db() called by db_load_routine() during loading of stored
routine to cache. Function mysql_change_db() calls check_db_dir_existence()
that might failed because specified database was dropped during concurrent
execution of DROP SCHEMA statement. db_load_routine() calls mysql_change_db()
with flag 'force_switch' set to 'true' value so when referenced db is not found
then my_error() is not called and function mysql_change_db() returns ok.
This shadows information about schema opening error in db_load_routine().
Then db_load_routine() makes attempt to parse stored routine that is failed.
This makes to return error to sp_cache_routines_and_add_tables_aux() but since
during error generation a call to my_error wasn't made and hence
THD::main_da wasn't set we set the generic "mysql.proc table corrupt" error
when running sp_cache_routines_and_add_tables_aux().
The fix is to install an error handler inside db_load_routine() for
the mysql_op_change_db() call, and check later if the ER_BAD_DB_ERROR
was caught.
@ sql/sql_db.cc
Added synchronization point "before_db_dir_check" to emulate a race condition during
processing of CALL/DROP SCHEMA.
modified:
mysql-test/r/sp_sync.result
mysql-test/t/sp_sync.test
sql/sp.cc
sql/sql_db.cc
=== modified file 'storage/innodb_plugin/page/page0zip.c'
--- a/storage/innodb_plugin/page/page0zip.c revid:dmitry.shulga@stripped
+++ b/storage/innodb_plugin/page/page0zip.c revid:marko.makela@oracle.com-20110628085709-kckbvih1mvibntaq
@@ -151,6 +151,20 @@ page_zip_empty_size(
#endif /* !UNIV_HOTBACKUP */
/*************************************************************//**
+Gets the number of elements in the dense page directory,
+including deleted records (the free list).
+@return number of elements in the dense page directory */
+UNIV_INLINE
+ulint
+page_zip_dir_elems(
+/*===============*/
+ const page_zip_des_t* page_zip) /*!< in: compressed page */
+{
+ /* Exclude the page infimum and supremum from the record count. */
+ return(page_dir_get_n_heap(page_zip->data) - PAGE_HEAP_NO_USER_LOW);
+}
+
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
including deleted records (the free list).
@return length of dense page directory, in bytes */
@@ -160,14 +174,42 @@ page_zip_dir_size(
/*==============*/
const page_zip_des_t* page_zip) /*!< in: compressed page */
{
- /* Exclude the page infimum and supremum from the record count. */
- ulint size = PAGE_ZIP_DIR_SLOT_SIZE
- * (page_dir_get_n_heap(page_zip->data)
- - PAGE_HEAP_NO_USER_LOW);
- return(size);
+ return(PAGE_ZIP_DIR_SLOT_SIZE * page_zip_dir_elems(page_zip));
}
/*************************************************************//**
+Gets an offset to the compressed page trailer (the dense page directory),
+including deleted records (the free list).
+@return offset of the dense page directory */
+UNIV_INLINE
+ulint
+page_zip_dir_start_offs(
+/*====================*/
+ const page_zip_des_t* page_zip, /*!< in: compressed page */
+ ulint n_dense) /*!< in: directory size */
+{
+ ut_ad(n_dense * PAGE_ZIP_DIR_SLOT_SIZE < page_zip_get_size(page_zip));
+
+ return(page_zip_get_size(page_zip) - n_dense * PAGE_ZIP_DIR_SLOT_SIZE);
+}
+
+/*************************************************************//**
+Gets a pointer to the compressed page trailer (the dense page directory),
+including deleted records (the free list).
+@param[in] page_zip compressed page
+@param[in] n_dense number of entries in the directory
+@return pointer to the dense page directory */
+#define page_zip_dir_start_low(page_zip, n_dense) \
+ ((page_zip)->data + page_zip_dir_start_offs(page_zip, n_dense))
+/*************************************************************//**
+Gets a pointer to the compressed page trailer (the dense page directory),
+including deleted records (the free list).
+@param[in] page_zip compressed page
+@return pointer to the dense page directory */
+#define page_zip_dir_start(page_zip) \
+ page_zip_dir_start_low(page_zip, page_zip_dir_elems(page_zip))
+
+/*************************************************************//**
Gets the size of the compressed page trailer (the dense page directory),
only including user records (excluding the free list).
@return length of dense page directory comprising existing records, in bytes */
@@ -2242,8 +2284,7 @@ zlib_done:
}
/* Restore the uncompressed columns in heap_no order. */
- storage = page_zip->data + page_zip_get_size(page_zip)
- - n_dense * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage = page_zip_dir_start_low(page_zip, n_dense);
for (slot = 0; slot < n_dense; slot++) {
rec_t* rec = recs[slot];
@@ -2728,8 +2769,7 @@ zlib_done:
return(FALSE);
}
- storage = page_zip->data + page_zip_get_size(page_zip)
- - n_dense * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage = page_zip_dir_start_low(page_zip, n_dense);
externs = storage - n_dense
* (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
@@ -3457,9 +3497,7 @@ page_zip_write_rec(
}
/* Write the data bytes. Store the uncompressed bytes separately. */
- storage = page_zip->data + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage = page_zip_dir_start(page_zip);
if (page_is_leaf(page)) {
ulint len;
@@ -3755,9 +3793,7 @@ corrupt:
field = page + offset;
storage = page_zip->data + z_offset;
- storage_end = page_zip->data + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage_end = page_zip_dir_start(page_zip);
heap_no = 1 + (storage_end - storage) / REC_NODE_PTR_SIZE;
@@ -3793,7 +3829,9 @@ page_zip_write_node_ptr(
{
byte* field;
byte* storage;
+#ifdef UNIV_DEBUG
page_t* page = page_align(rec);
+#endif /* UNIV_DEBUG */
ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
ut_ad(page_simple_validate_new(page));
@@ -3810,9 +3848,7 @@ page_zip_write_node_ptr(
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, size);
- storage = page_zip->data + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE
+ storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1) * REC_NODE_PTR_SIZE;
field = rec + size - REC_NODE_PTR_SIZE;
@@ -3861,7 +3897,9 @@ page_zip_write_trx_id_and_roll_ptr(
{
byte* field;
byte* storage;
+#ifdef UNIV_DEBUG
page_t* page = page_align(rec);
+#endif /* UNIV_DEBUG */
ulint len;
ut_ad(PAGE_ZIP_MATCH(rec, page_zip));
@@ -3879,9 +3917,7 @@ page_zip_write_trx_id_and_roll_ptr(
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
- storage = page_zip->data + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE
+ storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1)
* (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
@@ -3948,11 +3984,7 @@ page_zip_clear_rec(
/* Clear node_ptr. On the compressed page,
there is an array of node_ptr immediately before the
dense page directory, at the very end of the page. */
- storage = page_zip->data
- + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page)
- - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage = page_zip_dir_start(page_zip);
ut_ad(dict_index_get_n_unique_in_tree(index) ==
rec_offs_n_fields(offsets) - 1);
field = rec_get_nth_field(rec, offsets,
@@ -3972,11 +4004,7 @@ page_zip_clear_rec(
= dict_col_get_clust_pos(
dict_table_get_sys_col(
index->table, DATA_TRX_ID), index);
- storage = page_zip->data
- + page_zip_get_size(page_zip)
- - (page_dir_get_n_heap(page)
- - PAGE_HEAP_NO_USER_LOW)
- * PAGE_ZIP_DIR_SLOT_SIZE;
+ storage = page_zip_dir_start(page_zip);
field = rec_get_nth_field(rec, offsets, trx_id_pos, &len);
ut_ad(len == DATA_TRX_ID_LEN);
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-5.1 branch (marko.makela:3657 to 3658) Bug#12595087 | marko.makela | 29 Jun |