From 0f37ccb30f9ca0855b4494a7c7c10d293e316c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 Jun 2011 09:57:15 +0300 Subject: Bug #12612184 BLOB debug code cleanup: Refactor the !rec_offs_any_extern relaxation in row_build(). trx_assert_active(trx_id): Assert that the given transaction is active. (In the 5.1 built-in InnoDB, there is no trx->is_recovered field.) trx_assert_recovered(trx_id): Assert that the given transaction is active and has been recovered after a crash. row_build(): Replace a bunch of code with an assertion that invokes trx_assert_active() or trx_assert_recovered() and row_get_rec_trx_id(). row_get_trx_id_offset(): Make the function inlined. Remove the unused parameter rec, and make all parameters const. row_get_rec_trx_id(), row_get_rec_roll_ptr(): Make all parameters const. rb:691 approved by Jimmy Yang --- storage/innobase/include/trx0sys.h | 10 +++++ storage/innobase/include/trx0sys.ic | 21 ++++++++++ storage/innobase/row/row0row.c | 46 ++++++++------------- storage/innodb_plugin/include/row0row.h | 26 ++++++------ storage/innodb_plugin/include/row0row.ic | 45 ++++++++++++++++----- storage/innodb_plugin/include/row0upd.ic | 4 +- storage/innodb_plugin/include/trx0sys.h | 11 ++++- storage/innodb_plugin/include/trx0sys.ic | 24 ++++++++++- storage/innodb_plugin/row/row0row.c | 69 ++++++-------------------------- 9 files changed, 146 insertions(+), 110 deletions(-) diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index bad3c9d570c..7ea981eb85c 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -256,6 +256,16 @@ trx_in_trx_list( /*============*/ /* out: TRUE if is in */ trx_t* in_trx);/* in: trx */ +#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG +/******************************************************** +Assert that a transaction is active. */ +UNIV_INLINE +ibool +trx_assert_active( +/*==============*/ + /* out: TRUE */ + dulint trx_id); /* in: transaction identifier */ +#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ /********************************************************************* Updates the offset information about the end of the MySQL binlog entry which corresponds to the transaction just being committed. In a MySQL diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index 1142fb60398..f5033c5778a 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -257,6 +257,27 @@ trx_get_on_id( return(NULL); } +#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG +/******************************************************** +Assert that a transaction is active. */ +UNIV_INLINE +ibool +trx_assert_active( +/*==============*/ + /* out: TRUE */ + dulint trx_id) /* in: transaction identifier */ +{ + trx_t* trx; + + mutex_enter(&kernel_mutex); + trx = trx_get_on_id(trx_id); + ut_a(trx); + mutex_exit(&kernel_mutex); + + return(TRUE); +} +#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ + /******************************************************************** Returns the minumum trx id in trx list. This is the smallest id for which the trx can possibly be active. (But, you must look at the trx->conc_state to diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index 751de98deba..171039e34ac 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -212,35 +212,23 @@ row_build( } #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG - if (UNIV_LIKELY_NULL(rec_offs_any_null_extern(rec, offsets))) { - /* This condition can occur during crash recovery before - trx_rollback_or_clean_all_without_sess() has completed - execution. - - This condition is possible if the server crashed - during an insert or update before - btr_store_big_rec_extern_fields() did mtr_commit() all - BLOB pointers to the clustered index record. - - Look up the transaction that holds the implicit lock - on this record, and assert that it was recovered (and - will soon be rolled back). */ - - ulint trx_id_pos = dict_index_get_sys_col_pos( - index, DATA_TRX_ID); - ulint len; - dulint trx_id = trx_read_trx_id( - rec_get_nth_field(rec, offsets, trx_id_pos, &len)); - trx_t* trx; - ut_a(len == 6); - - mutex_enter(&kernel_mutex); - trx = trx_get_on_id(trx_id); - ut_a(trx); - /* This field does not exist in this version of InnoDB. */ - /* ut_a(trx->is_recovered); */ - mutex_exit(&kernel_mutex); - } + /* This condition can occur during crash recovery before + trx_rollback_or_clean_all_without_sess() has completed + execution. + + This condition is possible if the server crashed + during an insert or update before + btr_store_big_rec_extern_fields() did mtr_commit() all + BLOB pointers to the clustered index record. + + If the record contains a null BLOB pointer, look up the + transaction that holds the implicit lock on this record, and + assert that it is active. (In this version of InnoDB, we + cannot assert that it was recovered, because there is no + trx->is_recovered field.) */ + + ut_a(!rec_offs_any_null_extern(rec, offsets) + || trx_assert_active(row_get_rec_trx_id(rec, index, offsets))); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ if (type != ROW_COPY_POINTERS) { diff --git a/storage/innodb_plugin/include/row0row.h b/storage/innodb_plugin/include/row0row.h index 723b7b53395..36fb26482ce 100644 --- a/storage/innodb_plugin/include/row0row.h +++ b/storage/innodb_plugin/include/row0row.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -38,16 +38,16 @@ Created 4/20/1996 Heikki Tuuri #include "btr0types.h" /*********************************************************************//** -Gets the offset of the trx id field, in bytes relative to the origin of +Gets the offset of the DB_TRX_ID field, in bytes relative to the origin of a clustered index record. @return offset of DATA_TRX_ID */ -UNIV_INTERN +UNIV_INLINE ulint row_get_trx_id_offset( /*==================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: record offsets */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ @@ -55,9 +55,10 @@ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Reads the roll pointer field from a clustered index record. @return value of the field */ @@ -65,9 +66,10 @@ UNIV_INLINE roll_ptr_t row_get_rec_roll_ptr( /*=================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets);/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + __attribute__((nonnull, warn_unused_result)); /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. diff --git a/storage/innodb_plugin/include/row0row.ic b/storage/innodb_plugin/include/row0row.ic index 05c007641af..0b9ca982af8 100644 --- a/storage/innodb_plugin/include/row0row.ic +++ b/storage/innodb_plugin/include/row0row.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -27,6 +27,33 @@ Created 4/20/1996 Heikki Tuuri #include "rem0rec.h" #include "trx0undo.h" +/*********************************************************************//** +Gets the offset of the DB_TRX_ID field, in bytes relative to the origin of +a clustered index record. +@return offset of DATA_TRX_ID */ +UNIV_INLINE +ulint +row_get_trx_id_offset( +/*==================*/ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: record offsets */ +{ + ulint pos; + ulint offset; + ulint len; + + ut_ad(dict_index_is_clust(index)); + ut_ad(rec_offs_validate(NULL, index, offsets)); + + pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); + + offset = rec_get_nth_field_offs(offsets, pos, &len); + + ut_ad(len == DATA_TRX_ID_LEN); + + return(offset); +} + /*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ @@ -34,9 +61,9 @@ UNIV_INLINE trx_id_t row_get_rec_trx_id( /*===============*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { ulint offset; @@ -46,7 +73,7 @@ row_get_rec_trx_id( offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } return(trx_read_trx_id(rec + offset)); @@ -59,9 +86,9 @@ UNIV_INLINE roll_ptr_t row_get_rec_roll_ptr( /*=================*/ - const rec_t* rec, /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ + const rec_t* rec, /*!< in: record */ + const dict_index_t* index, /*!< in: clustered index */ + const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ { ulint offset; @@ -71,7 +98,7 @@ row_get_rec_roll_ptr( offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } return(trx_read_roll_ptr(rec + offset + DATA_TRX_ID_LEN)); diff --git a/storage/innodb_plugin/include/row0upd.ic b/storage/innodb_plugin/include/row0upd.ic index 18e22f1eca9..0894ed373b0 100644 --- a/storage/innodb_plugin/include/row0upd.ic +++ b/storage/innodb_plugin/include/row0upd.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -171,7 +171,7 @@ row_upd_rec_sys_fields( ulint offset = index->trx_id_offset; if (!offset) { - offset = row_get_trx_id_offset(rec, index, offsets); + offset = row_get_trx_id_offset(index, offsets); } #if DATA_TRX_ID + 1 != DATA_ROLL_PTR diff --git a/storage/innodb_plugin/include/trx0sys.h b/storage/innodb_plugin/include/trx0sys.h index cbb89689748..ed62375797a 100644 --- a/storage/innodb_plugin/include/trx0sys.h +++ b/storage/innodb_plugin/include/trx0sys.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -284,6 +284,15 @@ ibool trx_in_trx_list( /*============*/ trx_t* in_trx);/*!< in: trx */ +/***********************************************************//** +Assert that a transaction has been recovered. +@return TRUE */ +UNIV_INLINE +ibool +trx_assert_recovered( +/*=================*/ + trx_id_t trx_id) /*!< in: transaction identifier */ + __attribute__((warn_unused_result)); /*****************************************************************//** Updates the offset information about the end of the MySQL binlog entry which corresponds to the transaction just being committed. In a MySQL diff --git a/storage/innodb_plugin/include/trx0sys.ic b/storage/innodb_plugin/include/trx0sys.ic index 820d31d0692..6246debac0a 100644 --- a/storage/innodb_plugin/include/trx0sys.ic +++ b/storage/innodb_plugin/include/trx0sys.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -277,6 +277,28 @@ trx_get_on_id( return(NULL); } +#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG +/***********************************************************//** +Assert that a transaction has been recovered. +@return TRUE */ +UNIV_INLINE +ibool +trx_assert_recovered( +/*=================*/ + trx_id_t trx_id) /*!< in: transaction identifier */ +{ + trx_t* trx; + + mutex_enter(&kernel_mutex); + trx = trx_get_on_id(trx_id); + ut_a(trx); + ut_a(trx->is_recovered); + mutex_exit(&kernel_mutex); + + return(TRUE); +} +#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ + /****************************************************************//** Returns the minumum trx id in trx list. This is the smallest id for which the trx can possibly be active. (But, you must look at the trx->conc_state to diff --git a/storage/innodb_plugin/row/row0row.c b/storage/innodb_plugin/row/row0row.c index 3b610d735b0..dd94132eebc 100644 --- a/storage/innodb_plugin/row/row0row.c +++ b/storage/innodb_plugin/row/row0row.c @@ -47,35 +47,6 @@ Created 4/20/1996 Heikki Tuuri #include "read0read.h" #include "ut0mem.h" -/*********************************************************************//** -Gets the offset of trx id field, in bytes relative to the origin of -a clustered index record. -@return offset of DATA_TRX_ID */ -UNIV_INTERN -ulint -row_get_trx_id_offset( -/*==================*/ - const rec_t* rec __attribute__((unused)), - /*!< in: record */ - dict_index_t* index, /*!< in: clustered index */ - const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ -{ - ulint pos; - ulint offset; - ulint len; - - ut_ad(dict_index_is_clust(index)); - ut_ad(rec_offs_validate(rec, index, offsets)); - - pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - - offset = rec_get_nth_field_offs(offsets, pos, &len); - - ut_ad(len == DATA_TRX_ID_LEN); - - return(offset); -} - /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. @@ -233,33 +204,19 @@ row_build( } #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG - if (UNIV_LIKELY_NULL(rec_offs_any_null_extern(rec, offsets))) { - /* This condition can occur during crash recovery before - trx_rollback_active() has completed execution. - - This condition is possible if the server crashed - during an insert or update before - btr_store_big_rec_extern_fields() did mtr_commit() all - BLOB pointers to the clustered index record. - - Look up the transaction that holds the implicit lock - on this record, and assert that it was recovered (and - will soon be rolled back). */ - - ulint trx_id_pos = dict_index_get_sys_col_pos( - index, DATA_TRX_ID); - ulint len; - trx_id_t trx_id = trx_read_trx_id( - rec_get_nth_field(rec, offsets, trx_id_pos, &len)); - trx_t* trx; - ut_a(len == 6); - - mutex_enter(&kernel_mutex); - trx = trx_get_on_id(trx_id); - ut_a(trx); - ut_a(trx->is_recovered); - mutex_exit(&kernel_mutex); - } + /* This condition can occur during crash recovery before + trx_rollback_active() has completed execution. + + This condition is possible if the server crashed + during an insert or update before + btr_store_big_rec_extern_fields() did mtr_commit() all + BLOB pointers to the clustered index record. + + If the record contains a null BLOB pointer, look up the + transaction that holds the implicit lock on this record, and + assert that it was recovered (and will soon be rolled back). */ + ut_a(!rec_offs_any_null_extern(rec, offsets) + || trx_assert_recovered(row_get_rec_trx_id(rec, index, offsets))); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ if (type != ROW_COPY_POINTERS) { -- cgit v1.2.1