/***********************************************************//** Parses the row reference and other info in a modify undo log record. @return TRUE if purge operation required: NOTE that then the CALLER must unfreeze data dictionary! */ static ibool row_purge_parse_undo_rec( /*=====================*/ purge_node_t* node, /*!< in: row undo node */ ibool* updated_extern, /*!< out: TRUE if an externally stored field was updated */ que_thr_t* thr) /*!< in: query thread */ { dict_index_t* clust_index; byte* ptr; trx_t* trx; undo_no_t undo_no; table_id_t table_id; trx_id_t trx_id; roll_ptr_t roll_ptr; ulint info_bits; ulint type; ut_ad(node && thr); trx = thr_get_trx(thr); ptr = trx_undo_rec_get_pars( node->undo_rec, &type, &node->cmpl_info, updated_extern, &undo_no, &table_id); node->rec_type = type; if (type == TRX_UNDO_UPD_DEL_REC && !(*updated_extern)) { return(FALSE); } ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, &info_bits); node->table = NULL; if (type == TRX_UNDO_UPD_EXIST_REC && node->cmpl_info & UPD_NODE_NO_ORD_CHANGE && !(*updated_extern)) { /* Purge requires no changes to indexes: we may return */ return(FALSE); } /* Prevent DROP TABLE etc. from running when we are doing the purge for this row */ row_mysql_freeze_data_dictionary(trx); mutex_enter(&(dict_sys->mutex)); node->table = dict_table_get_on_id_low(table_id); mutex_exit(&(dict_sys->mutex)); if (node->table == NULL) { /* The table has been dropped: no need to do purge */ err_exit: row_mysql_unfreeze_data_dictionary(trx); return(FALSE); } if (node->table->ibd_file_missing) { /* We skip purge of missing .ibd files */ node->table = NULL; goto err_exit; } clust_index = dict_table_get_first_index(node->table); if (clust_index == NULL) { /* The table was corrupt in the data dictionary */ goto err_exit; } ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), node->heap); ptr = trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, roll_ptr, info_bits, trx, node->heap, &(node->update)); /* Read to the partial row the fields that occur in indexes */ if (!(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { ptr = trx_undo_rec_get_partial_row( ptr, clust_index, &node->row, type == TRX_UNDO_UPD_DEL_REC, node->heap); } return(TRUE); }
/*************************************************************** Parses the row reference and other info in a modify undo log record. */ static ibool row_purge_parse_undo_rec( /*=====================*/ /* out: TRUE if purge operation required */ purge_node_t* node, /* in: row undo node */ ibool* updated_extern, /* out: TRUE if an externally stored field was updated */ que_thr_t* thr) /* in: query thread */ { dict_index_t* clust_index; byte* ptr; dulint undo_no; dulint table_id; dulint trx_id; dulint roll_ptr; ulint info_bits; ulint type; ulint cmpl_info; ut_ad(node && thr); ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &cmpl_info, updated_extern, &undo_no, &table_id); node->rec_type = type; if (type == TRX_UNDO_UPD_DEL_REC && !(*updated_extern)) { return(FALSE); } ptr = trx_undo_update_rec_get_sys_cols(ptr, &trx_id, &roll_ptr, &info_bits); node->table = NULL; if (type == TRX_UNDO_UPD_EXIST_REC && cmpl_info & UPD_NODE_NO_ORD_CHANGE && !(*updated_extern)) { /* Purge requires no changes to indexes: we may return */ return(FALSE); } mutex_enter(&(dict_sys->mutex)); node->table = dict_table_get_on_id_low(table_id, thr_get_trx(thr)); rw_lock_x_lock(&(purge_sys->purge_is_running)); 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)); return(FALSE); } clust_index = dict_table_get_first_index(node->table); ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref), node->heap); ptr = trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id, roll_ptr, info_bits, node->heap, &(node->update)); /* Read to the partial row the fields that occur in indexes */ if (!cmpl_info & UPD_NODE_NO_ORD_CHANGE) { ptr = trx_undo_rec_get_partial_row(ptr, clust_index, &(node->row), node->heap); } return(TRUE); }