1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-25004 Refactorings

* Avoid some pessimization
  * Slightly smaller upgrade dataset
  * Simplify vers_row_same_trx() and its caller
This commit is contained in:
Marko Mäkelä
2022-12-27 00:02:02 +03:00
committed by Aleksey Midenkov
parent e056efdd6c
commit 72e2d1d220
4 changed files with 59 additions and 67 deletions

View File

@ -12,7 +12,7 @@
# Examples # Examples
# #
# export OLD_BINDIR="/home/midenok/src/mariadb/10.3b/build" # export OLD_BINDIR="/home/midenok/src/mariadb/10.3b/build"
# mtr innodb_fts.versioning,orig_stopword,prepare # ./mtr innodb_fts.versioning,prepare
# #
if ($MTR_COMBINATION_PREPARE) if ($MTR_COMBINATION_PREPARE)
@ -56,11 +56,16 @@ if ($MTR_COMBINATION_PREPARE)
--exec mkdir -p $std_dir --exec mkdir -p $std_dir
--exec cp -af $datadir/ibdata1 $datadir/test/*.frm $std_dir --exec cp -af $datadir/ibdata1 $datadir/test/*.frm $std_dir
# zero out the doublewrite buffer
--exec dd if=/dev/zero of=$std_dir/ibdata1 bs=16k seek=64 count=128 conv=notrunc
--exec gzip -9f $std_dir/ibdata1 $std_dir/*.frm --exec gzip -9f $std_dir/ibdata1 $std_dir/*.frm
} }
if ($MTR_COMBINATION_UPGRADE) if ($MTR_COMBINATION_UPGRADE)
{ {
--disable_query_log
call mtr.add_suppression("InnoDB: Table `mysql`.\`innodb_(table|index)_stats`");
--enable_query_log
--source include/shutdown_mysqld.inc --source include/shutdown_mysqld.inc
--exec rm -f $datadir/test/*.ibd $datadir/ib* --exec rm -f $datadir/test/*.ibd $datadir/ib*
--exec cp -af $std_dir/ibdata1.gz $datadir --exec cp -af $std_dir/ibdata1.gz $datadir

View File

@ -2059,39 +2059,48 @@ row_ins_dupl_error_with_rec(
return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
} }
/** @return true if history row was inserted by this transaction /** Determine whether a history row was inserted by this transaction
(row TRX_ID is the same as current TRX_ID). */ (row TRX_ID is the same as current TRX_ID).
static @param index secondary index
dberr_t vers_row_same_trx(dict_index_t* index, const rec_t* rec, @param rec secondary index record
que_thr_t* thr, bool *same_trx) @param trx transaction
@return error code
@retval DB_SUCCESS on success
@retval DB_FOREIGN_DUPLICATE_KEY if a history row was inserted by trx */
static dberr_t vers_row_same_trx(dict_index_t* index, const rec_t* rec,
const trx_t& trx)
{ {
mtr_t mtr; mtr_t mtr;
dberr_t ret= DB_SUCCESS; dberr_t ret= DB_SUCCESS;
ulint trx_id_len;
const byte *trx_id_bytes;
trx_id_t trx_id;
dict_index_t *clust_index= dict_table_get_first_index(index->table); dict_index_t *clust_index= dict_table_get_first_index(index->table);
ut_ad(index != clust_index); ut_ad(index != clust_index);
mtr.start(); mtr.start();
rec_t *clust_rec= if (const rec_t *clust_rec=
row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr); row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr))
{
rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs *clust_offs= offsets_; rec_offs *clust_offs= offsets_;
rec_offs_init(offsets_); rec_offs_init(offsets_);
mem_heap_t *heap= NULL; mem_heap_t *heap= NULL;
if (clust_rec)
{
clust_offs= clust_offs=
rec_get_offsets(clust_rec, clust_index, clust_offs, rec_get_offsets(clust_rec, clust_index, clust_offs,
clust_index->n_core_fields, ULINT_UNDEFINED, &heap); clust_index->n_core_fields, ULINT_UNDEFINED, &heap);
if (!clust_index->vers_history_row(clust_rec, clust_offs)) if (clust_index->vers_history_row(clust_rec, clust_offs))
{ {
*same_trx= false; ulint trx_id_len;
goto end; const byte *trx_id= rec_get_nth_field(clust_rec, clust_offs,
clust_index->n_uniq, &trx_id_len);
ut_ad(trx_id_len == DATA_TRX_ID_LEN);
if (trx.id == trx_read_trx_id(trx_id))
ret= DB_FOREIGN_DUPLICATE_KEY;
} }
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
} }
else else
{ {
@ -2099,21 +2108,8 @@ dberr_t vers_row_same_trx(dict_index_t* index, const rec_t* rec,
" of table " << index->table->name << " is out of sync"; " of table " << index->table->name << " is out of sync";
ut_ad("secondary index is out of sync" == 0); ut_ad("secondary index is out of sync" == 0);
ret= DB_TABLE_CORRUPT; ret= DB_TABLE_CORRUPT;
goto end;
} }
trx_id_bytes= rec_get_nth_field(clust_rec, clust_offs,
clust_index->n_uniq, &trx_id_len);
ut_ad(trx_id_len == DATA_TRX_ID_LEN);
trx_id= trx_read_trx_id(trx_id_bytes);
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
*same_trx= thr_get_trx(thr)->id == trx_id;
end:
mtr.commit(); mtr.commit();
return ret; return ret;
} }
@ -2141,9 +2137,6 @@ row_ins_scan_sec_index_for_duplicate(
ulint n_fields_cmp; ulint n_fields_cmp;
btr_pcur_t pcur; btr_pcur_t pcur;
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
dberr_t err2;
bool same_trx;
ulint allow_duplicates;
rec_offs offsets_[REC_OFFS_SEC_INDEX_SIZE]; rec_offs offsets_[REC_OFFS_SEC_INDEX_SIZE];
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
DBUG_ENTER("row_ins_scan_sec_index_for_duplicate"); DBUG_ENTER("row_ins_scan_sec_index_for_duplicate");
@ -2181,7 +2174,7 @@ row_ins_scan_sec_index_for_duplicate(
: BTR_SEARCH_LEAF, : BTR_SEARCH_LEAF,
&pcur, mtr); &pcur, mtr);
allow_duplicates = thr_get_trx(thr)->duplicates; trx_t* const trx = thr_get_trx(thr);
/* Scan index records and check if there is a duplicate */ /* Scan index records and check if there is a duplicate */
@ -2202,7 +2195,7 @@ row_ins_scan_sec_index_for_duplicate(
if (flags & BTR_NO_LOCKING_FLAG) { if (flags & BTR_NO_LOCKING_FLAG) {
/* Set no locks when applying log /* Set no locks when applying log
in online table rebuild. */ in online table rebuild. */
} else if (allow_duplicates) { } else if (trx->duplicates) {
/* If the SQL-query will update or replace /* If the SQL-query will update or replace
duplicate key we will take X-lock for duplicate key we will take X-lock for
@ -2239,22 +2232,16 @@ row_ins_scan_sec_index_for_duplicate(
err = DB_DUPLICATE_KEY; err = DB_DUPLICATE_KEY;
thr_get_trx(thr)->error_info = index; trx->error_info = index;
if (index->table->versioned()) { if (!index->table->versioned()) {
err2 = vers_row_same_trx(index, rec, } else if (dberr_t e =
thr, &same_trx); vers_row_same_trx(index, rec,
if (err2 != DB_SUCCESS) { *trx)) {
err = err2; err = e;
goto end_scan; goto end_scan;
} }
if (same_trx) {
err = DB_FOREIGN_DUPLICATE_KEY;
goto end_scan;
}
}
/* If the duplicate is on hidden FTS_DOC_ID, /* If the duplicate is on hidden FTS_DOC_ID,
state so in the error log */ state so in the error log */
if (index == index->table->fts_doc_id_index if (index == index->table->fts_doc_id_index

View File

@ -455,9 +455,10 @@ row_merge_buf_redundant_convert(
@param[in] new_table new table @param[in] new_table new table
@param[in,out] psort_info parallel sort info @param[in,out] psort_info parallel sort info
@param[in,out] row table row @param[in,out] row table row
@param[in] history_row row is historical in a system-versioned table
@param[in] ext cache of externally stored @param[in] ext cache of externally stored
column prefixes, or NULL column prefixes, or NULL
@param[in] history_fts row is historical in a system-versioned table
on which a FTS_DOC_ID_INDEX(FTS_DOC_ID) exists
@param[in,out] doc_id Doc ID if we are creating @param[in,out] doc_id Doc ID if we are creating
FTS index FTS index
@param[in,out] conv_heap memory heap where to allocate data when @param[in,out] conv_heap memory heap where to allocate data when
@ -478,8 +479,8 @@ row_merge_buf_add(
const dict_table_t* new_table, const dict_table_t* new_table,
fts_psort_t* psort_info, fts_psort_t* psort_info,
dtuple_t* row, dtuple_t* row,
const bool history_row,
const row_ext_t* ext, const row_ext_t* ext,
const bool history_fts,
doc_id_t* doc_id, doc_id_t* doc_id,
mem_heap_t* conv_heap, mem_heap_t* conv_heap,
dberr_t* err, dberr_t* err,
@ -542,7 +543,7 @@ error:
: NULL; : NULL;
/* Process the Doc ID column */ /* Process the Doc ID column */
if (!v_col && index->table->fts && (*doc_id || history_row) if (!v_col && (history_fts || *doc_id)
&& col->ind == index->table->fts->doc_col) { && col->ind == index->table->fts->doc_col) {
fts_write_doc_id((byte*) &write_doc_id, *doc_id); fts_write_doc_id((byte*) &write_doc_id, *doc_id);
@ -594,7 +595,7 @@ error:
/* Tokenize and process data for FTS */ /* Tokenize and process data for FTS */
if (!history_row && (index->type & DICT_FTS)) { if (!history_fts && (index->type & DICT_FTS)) {
fts_doc_item_t* doc_item; fts_doc_item_t* doc_item;
byte* value; byte* value;
void* ptr; void* ptr;
@ -1707,7 +1708,6 @@ row_merge_read_clustered_index(
char new_sys_trx_end[8]; char new_sys_trx_end[8];
byte any_autoinc_data[8] = {0}; byte any_autoinc_data[8] = {0};
bool vers_update_trt = false; bool vers_update_trt = false;
bool history_row = false;
DBUG_ENTER("row_merge_read_clustered_index"); DBUG_ENTER("row_merge_read_clustered_index");
@ -1897,6 +1897,7 @@ row_merge_read_clustered_index(
dtuple_t* row; dtuple_t* row;
row_ext_t* ext; row_ext_t* ext;
page_cur_t* cur = btr_pcur_get_page_cur(&pcur); page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
bool history_row, history_fts = false;
page_cur_move_to_next(cur); page_cur_move_to_next(cur);
@ -2135,11 +2136,10 @@ end_of_index:
row_heap); row_heap);
ut_ad(row); ut_ad(row);
if (new_table->versioned()) { history_row = new_table->versioned()
const dfield_t* dfield = dtuple_get_nth_field( && dtuple_get_nth_field(row, new_table->vers_end)
row, new_table->vers_end); ->vers_history_row();
history_row = dfield->vers_history_row(); history_fts = history_row && new_table->fts;
}
for (ulint i = 0; i < n_nonnull; i++) { for (ulint i = 0; i < n_nonnull; i++) {
dfield_t* field = &row->fields[nonnull[i]]; dfield_t* field = &row->fields[nonnull[i]];
@ -2170,7 +2170,7 @@ end_of_index:
} }
/* Get the next Doc ID */ /* Get the next Doc ID */
if (add_doc_id && !history_row) { if (add_doc_id && !history_fts) {
doc_id++; doc_id++;
} else { } else {
doc_id = 0; doc_id = 0;
@ -2329,7 +2329,7 @@ write_buffers:
if (UNIV_LIKELY if (UNIV_LIKELY
(row && (rows_added = row_merge_buf_add( (row && (rows_added = row_merge_buf_add(
buf, fts_index, old_table, new_table, buf, fts_index, old_table, new_table,
psort_info, row, history_row, ext, psort_info, row, ext, history_fts,
&doc_id, conv_heap, &err, &doc_id, conv_heap, &err,
&v_heap, eval_table, trx)))) { &v_heap, eval_table, trx)))) {
@ -2662,8 +2662,8 @@ write_buffers:
if (UNIV_UNLIKELY if (UNIV_UNLIKELY
(!(rows_added = row_merge_buf_add( (!(rows_added = row_merge_buf_add(
buf, fts_index, old_table, buf, fts_index, old_table,
new_table, psort_info, row, new_table, psort_info,
history_row, ext, &doc_id, row, ext, history_fts, &doc_id,
conv_heap, &err, &v_heap, conv_heap, &err, &v_heap,
eval_table, trx)))) { eval_table, trx)))) {
/* An empty buffer should have enough /* An empty buffer should have enough