diff options
Diffstat (limited to 'innobase/row/row0purge.c')
-rw-r--r-- | innobase/row/row0purge.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 60e057b816e..b64003f22d4 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -24,6 +24,7 @@ Created 3/14/1997 Heikki Tuuri #include "row0row.h" #include "row0upd.h" #include "row0vers.h" +#include "row0mysql.h" #include "log0log.h" /************************************************************************ @@ -453,7 +454,9 @@ static ibool row_purge_parse_undo_rec( /*=====================*/ - /* out: TRUE if purge operation required */ + /* out: TRUE if purge operation required: + NOTE that then the CALLER must unfreeze + data dictionary! */ purge_node_t* node, /* in: row undo node */ ibool* updated_extern, /* out: TRUE if an externally stored field @@ -462,6 +465,7 @@ row_purge_parse_undo_rec( { dict_index_t* clust_index; byte* ptr; + trx_t* trx; dulint undo_no; dulint table_id; dulint trx_id; @@ -471,6 +475,8 @@ row_purge_parse_undo_rec( ulint cmpl_info; ut_ad(node && thr); + + trx = thr_get_trx(thr); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info, updated_extern, &undo_no, &table_id); @@ -493,18 +499,21 @@ row_purge_parse_undo_rec( return(FALSE); } - mutex_enter(&(dict_sys->mutex)); + /* Prevent DROP TABLE etc. from running when we are doing the purge + for this row */ - node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + row_mysql_freeze_data_dictionary(trx); - rw_lock_x_lock(&(purge_sys->purge_is_running)); + mutex_enter(&(dict_sys->mutex)); - mutex_exit(&(dict_sys->mutex)); + node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); + mutex_exit(&(dict_sys->mutex)); + if (node->table == NULL) { /* The table has been dropped: no need to do purge */ - rw_lock_x_unlock(&(purge_sys->purge_is_running)); + row_mysql_unfreeze_data_dictionary(trx); return(FALSE); } @@ -514,7 +523,7 @@ row_purge_parse_undo_rec( if (clust_index == NULL) { /* The table was corrupt in the data dictionary */ - rw_lock_x_unlock(&(purge_sys->purge_is_running)); + row_mysql_unfreeze_data_dictionary(trx); return(FALSE); } @@ -552,9 +561,12 @@ row_purge( dulint roll_ptr; ibool purge_needed; ibool updated_extern; + trx_t* trx; ut_ad(node && thr); + trx = thr_get_trx(thr); + node->undo_rec = trx_purge_fetch_next_rec(&roll_ptr, &(node->reservation), node->heap); @@ -573,6 +585,8 @@ row_purge( } else { purge_needed = row_purge_parse_undo_rec(node, &updated_extern, thr); + /* If purge_needed == TRUE, we must also remember to unfreeze + data dictionary! */ } if (purge_needed) { @@ -594,7 +608,7 @@ row_purge( btr_pcur_close(&(node->pcur)); } - rw_lock_x_unlock(&(purge_sys->purge_is_running)); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ |