mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
Bug#54408: txn rollback after recovery: row0umod.c:673
dict_table_get_format(index->table) The REDUNDANT and COMPACT formats store a local 768-byte prefix of each externally stored column. No row_ext cache is needed, but we initialized one nevertheless. When the BLOB pointer was zero, we would ignore the locally stored prefix as well. This triggered an assertion failure in row_undo_mod_upd_exist_sec(). row_build(): Allow ext==NULL when a REDUNDANT or COMPACT table contains externally stored columns. row_undo_search_clust_to_pcur(), row_upd_store_row(): Invoke row_build() with ext==NULL on REDUNDANT and COMPACT tables. rb://382 approved by Jimmy Yang
This commit is contained in:
parent
c43070dabe
commit
c8e48de261
3 changed files with 40 additions and 3 deletions
|
@ -294,7 +294,13 @@ row_build(
|
|||
|
||||
ut_ad(dtuple_check_typed(row));
|
||||
|
||||
if (j) {
|
||||
if (!ext) {
|
||||
/* REDUNDANT and COMPACT formats store a local
|
||||
768-byte prefix of each externally stored
|
||||
column. No cache is needed. */
|
||||
ut_ad(dict_table_get_format(index->table)
|
||||
< DICT_TF_FORMAT_ZIP);
|
||||
} else if (j) {
|
||||
*ext = row_ext_create(j, ext_cols, row,
|
||||
dict_table_zip_size(index->table),
|
||||
heap);
|
||||
|
|
|
@ -199,8 +199,24 @@ row_undo_search_clust_to_pcur(
|
|||
|
||||
ret = FALSE;
|
||||
} else {
|
||||
row_ext_t** ext;
|
||||
|
||||
if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) {
|
||||
/* In DYNAMIC or COMPRESSED format, there is
|
||||
no prefix of externally stored columns in the
|
||||
clustered index record. Build a cache of
|
||||
column prefixes. */
|
||||
ext = &node->ext;
|
||||
} else {
|
||||
/* REDUNDANT and COMPACT formats store a local
|
||||
768-byte prefix of each externally stored
|
||||
column. No cache is needed. */
|
||||
ext = NULL;
|
||||
node->ext = NULL;
|
||||
}
|
||||
|
||||
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
|
||||
offsets, NULL, &node->ext, node->heap);
|
||||
offsets, NULL, ext, node->heap);
|
||||
if (node->update) {
|
||||
node->undo_row = dtuple_copy(node->row, node->heap);
|
||||
row_upd_replace(node->undo_row, &node->undo_ext,
|
||||
|
|
|
@ -1398,6 +1398,7 @@ row_upd_store_row(
|
|||
dict_index_t* clust_index;
|
||||
rec_t* rec;
|
||||
mem_heap_t* heap = NULL;
|
||||
row_ext_t** ext;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
const ulint* offsets;
|
||||
rec_offs_init(offsets_);
|
||||
|
@ -1414,8 +1415,22 @@ row_upd_store_row(
|
|||
|
||||
offsets = rec_get_offsets(rec, clust_index, offsets_,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) {
|
||||
/* In DYNAMIC or COMPRESSED format, there is no prefix
|
||||
of externally stored columns in the clustered index
|
||||
record. Build a cache of column prefixes. */
|
||||
ext = &node->ext;
|
||||
} else {
|
||||
/* REDUNDANT and COMPACT formats store a local
|
||||
768-byte prefix of each externally stored column.
|
||||
No cache is needed. */
|
||||
ext = NULL;
|
||||
node->ext = NULL;
|
||||
}
|
||||
|
||||
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
|
||||
NULL, &node->ext, node->heap);
|
||||
NULL, ext, node->heap);
|
||||
if (node->is_delete) {
|
||||
node->upd_row = NULL;
|
||||
node->upd_ext = NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue