/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the availability of the redo log space before the start of the operation is that we MUST not hold any synchonization objects when performing the check. If you make a change in this module make sure that no codepath is introduced where a call to log_free_check() is bypassed. */

/******************************************************************/ Creates a purge node to a query graph. @return own: purge node / UNIV_INTERN purge_node_t row_purge_node_create( /==================/ que_thr_t* parent, /!< in: parent node, i.e., a thr node / mem_heap_t heap) /!< in: memory heap where created / { purge_node_t node;

ut_ad(parent && heap);

node = mem_heap_alloc(heap, sizeof(purge_node_t));

node->common.type = QUE_NODE_PURGE;
node->common.parent = parent;

node->heap = mem_heap_create(256);

return(node);

}

/*********************************************************/ Repositions the pcur in the purge node on the clustered index record, if found. @return TRUE if the record was found / static ibool row_purge_reposition_pcur( /======================/ ulint mode, /!< in: latching mode / purge_node_t node, /!< in: row purge node / mtr_t mtr) /!< in: mtr */ { ibool found;

if (node->found_clust) {
	found = btr_pcur_restore_position(mode, &(node->pcur), mtr);

	return(found);
}

found = row_search_on_row_ref(&(node->pcur), mode, node->table,
				  node->ref, mtr);
node->found_clust = found;

if (found) {
	btr_pcur_store_position(&(node->pcur), mtr);
}

return(found);

}

/*********************************************************/ Removes a delete marked clustered index record if possible. @return TRUE if success, or if not found, or if modified after the delete marking / static ibool row_purge_remove_clust_if_poss_low( /===============================/ purge_node_t node, /!< in: row purge node / ulint mode) /!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE / { dict_index_t index; btr_pcur_t pcur; btr_cur_t* btr_cur; ibool success; ulint err; mtr_t mtr; rec_t* rec; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_);

index = dict_table_get_first_index(node->table);

pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);

log_free_check();
mtr_start(&mtr);

success = row_purge_reposition_pcur(mode, node, &mtr);

if (!success) {
	/* The record is already removed */

	btr_pcur_commit_specify_mtr(pcur, &mtr);

	return(TRUE);
}

rec = btr_pcur_get_rec(pcur);

if (node->roll_ptr != row_get_rec_roll_ptr(
	    rec, index, rec_get_offsets(rec, index, offsets_,
					ULINT_UNDEFINED, &heap)))
{
	if (UNIV_LIKELY_NULL(heap)) {
		mem_heap_free(heap);
	}
	/* Someone else has modified the record later: do not remove */
	btr_pcur_commit_specify_mtr(pcur, &mtr);

	return(TRUE);
}

if (UNIV_LIKELY_NULL(heap)) {
	mem_heap_free(heap);
}

if (mode == BTR_MODIFY_LEAF) {
	success = btr_cur_optimistic_delete(btr_cur, &mtr);
} else {
	ut_ad(mode == BTR_MODIFY_TREE);
	btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
				   RB_NONE, &mtr);

	if (err == DB_SUCCESS) {
		success = TRUE;
	} else if (err == DB_OUT_OF_FILE_SPACE) {
		success = FALSE;
	} else {
		ut_error;
	}
}

btr_pcur_commit_specify_mtr(pcur, &mtr);

return(success);

}

/*********************************************************/ Removes a clustered index record if it has not been modified after the delete marking. / static void row_purge_remove_clust_if_poss( /===========================/ purge_node_t node) /*!< in: row purge node */ { ibool success; ulint n_tries = 0;

/*	fputs("Purge: Removing clustered record\n", stderr); */

success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_LEAF);
if (success) {

	return;
}

retry: success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */

if (!success && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
	n_tries++;

	os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);

	goto retry;
}

ut_a(success);
InnoDB Row Purge Node Creation and Clustered Index Record Removal

原文地址: https://www.cveoy.top/t/topic/og7a 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录