Commit 85d668b4 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge mysql-5.1-innodb to mysql-5.5-innodb.

parents 0b099e87 91df7abd
drop table if exists t1,t2,t3,t4; drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest; drop database if exists mysqltest;
CREATE TABLE bug58912 (a BLOB, b TEXT, PRIMARY KEY(a(1))) ENGINE=InnoDB;
INSERT INTO bug58912 VALUES(REPEAT('a',8000),REPEAT('b',8000));
UPDATE bug58912 SET a=REPEAT('a',7999);
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb; create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
select id, code, name from t1 order by id; select id, code, name from t1 order by id;
...@@ -1670,10 +1673,10 @@ variable_value - @innodb_rows_deleted_orig ...@@ -1670,10 +1673,10 @@ variable_value - @innodb_rows_deleted_orig
71 71
SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted'; SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
variable_value - @innodb_rows_inserted_orig variable_value - @innodb_rows_inserted_orig
1065 1066
SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated'; SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
variable_value - @innodb_rows_updated_orig variable_value - @innodb_rows_updated_orig
865 866
SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits'; SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits';
variable_value - @innodb_row_lock_waits_orig variable_value - @innodb_row_lock_waits_orig
0 0
...@@ -3173,3 +3176,4 @@ Variable_name Value ...@@ -3173,3 +3176,4 @@ Variable_name Value
Handler_update 1 Handler_update 1
Variable_name Value Variable_name Value
Handler_delete 1 Handler_delete 1
DROP TABLE bug58912;
...@@ -49,6 +49,15 @@ drop table if exists t1,t2,t3,t4; ...@@ -49,6 +49,15 @@ drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest; drop database if exists mysqltest;
--enable_warnings --enable_warnings
# Bug#58912 InnoDB unnecessarily avoids update-in-place on column prefixes
CREATE TABLE bug58912 (a BLOB, b TEXT, PRIMARY KEY(a(1))) ENGINE=InnoDB;
INSERT INTO bug58912 VALUES(REPEAT('a',8000),REPEAT('b',8000));
UPDATE bug58912 SET a=REPEAT('a',7999);
# The above statements used to trigger a failure during purge when
# Bug#55284 was fixed while Bug#58912 was not. Defer the DROP TABLE,
# so that purge gets a chance to run (and a double free of the
# off-page column can be detected, if one is to occur.)
# #
# Small basic test with ignore # Small basic test with ignore
# #
...@@ -2548,6 +2557,9 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig; ...@@ -2548,6 +2557,9 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log -- enable_query_log
# Clean up after the Bug#55284/Bug#58912 test case.
DROP TABLE bug58912;
####################################################################### #######################################################################
# # # #
# Please, DO NOT TOUCH this file as well as the innodb.result file. # # Please, DO NOT TOUCH this file as well as the innodb.result file. #
......
...@@ -1874,7 +1874,8 @@ btr_cur_update_in_place( ...@@ -1874,7 +1874,8 @@ btr_cur_update_in_place(
NOT call it if index is secondary */ NOT call it if index is secondary */
if (!dict_index_is_clust(index) if (!dict_index_is_clust(index)
|| row_upd_changes_ord_field_binary(NULL, index, update)) { || row_upd_changes_ord_field_binary(NULL, NULL,
index, update)) {
/* Remove possible hash index pointer to this record */ /* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor); btr_search_update_hash_on_delete(cursor);
...@@ -2626,27 +2627,24 @@ ulint ...@@ -2626,27 +2627,24 @@ ulint
btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec(
/*===========================*/ /*===========================*/
ulint flags, /*!< in: undo logging and locking flags */ ulint flags, /*!< in: undo logging and locking flags */
btr_cur_t* cursor, /*!< in: cursor */ buf_block_t* block, /*!< in/out: buffer block of the record */
rec_t* rec, /*!< in/out: record */
dict_index_t* index, /*!< in: clustered index of the record */
const ulint* offsets,/*!< in: rec_get_offsets(rec) */
ibool val, /*!< in: value to set */ ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */ que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
{ {
dict_index_t* index;
buf_block_t* block;
roll_ptr_t roll_ptr; roll_ptr_t roll_ptr;
ulint err; ulint err;
rec_t* rec;
page_zip_des_t* page_zip; page_zip_des_t* page_zip;
trx_t* trx; trx_t* trx;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
rec_offs_init(offsets_);
rec = btr_cur_get_rec(cursor); ut_ad(dict_index_is_clust(index));
index = cursor->index; ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); ut_ad(buf_block_get_frame(block) == page_align(rec));
ut_ad(page_is_leaf(page_align(rec)));
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
if (btr_cur_print_record_ops && thr) { if (btr_cur_print_record_ops && thr) {
...@@ -2658,13 +2656,12 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2658,13 +2656,12 @@ btr_cur_del_mark_set_clust_rec(
ut_ad(dict_index_is_clust(index)); ut_ad(dict_index_is_clust(index));
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
err = lock_clust_rec_modify_check_and_lock(flags, err = lock_clust_rec_modify_check_and_lock(flags, block,
btr_cur_get_block(cursor),
rec, index, offsets, thr); rec, index, offsets, thr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
goto func_exit; return(err);
} }
err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr, err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr,
...@@ -2672,11 +2669,9 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2672,11 +2669,9 @@ btr_cur_del_mark_set_clust_rec(
&roll_ptr); &roll_ptr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
goto func_exit; return(err);
} }
block = btr_cur_get_block(cursor);
if (block->is_hashed) { if (block->is_hashed) {
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
} }
...@@ -2699,10 +2694,6 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2699,10 +2694,6 @@ btr_cur_del_mark_set_clust_rec(
btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
roll_ptr, mtr); roll_ptr, mtr);
func_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -3754,107 +3745,35 @@ btr_cur_set_ownership_of_extern_field( ...@@ -3754,107 +3745,35 @@ btr_cur_set_ownership_of_extern_field(
} }
/*******************************************************************//** /*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership Marks non-updated off-page fields as disowned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the must be transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed index tree. In purge only the owner of externally stored field is allowed
to free the field. to free the field. */
@return TRUE if BLOB ownership was transferred */
UNIV_INTERN UNIV_INTERN
ibool void
btr_cur_mark_extern_inherited_fields( btr_cur_disown_inherited_fields(
/*=================================*/ /*============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */ part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */ rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */ dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */ const upd_t* update, /*!< in: update vector */
mtr_t* mtr) /*!< in: mtr, or NULL if not logged */ mtr_t* mtr) /*!< in/out: mini-transaction */
{ {
ulint n;
ulint j;
ulint i; ulint i;
ibool change_ownership = FALSE;
ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)); ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
ut_ad(rec_offs_any_extern(offsets));
ut_ad(mtr);
if (!rec_offs_any_extern(offsets)) { for (i = 0; i < rec_offs_n_fields(offsets); i++) {
if (rec_offs_nth_extern(offsets, i)
return(FALSE); && !upd_get_field_by_field_no(update, i)) {
}
n = rec_offs_n_fields(offsets);
for (i = 0; i < n; i++) {
if (rec_offs_nth_extern(offsets, i)) {
/* Check it is not in updated fields */
if (update) {
for (j = 0; j < upd_get_n_fields(update);
j++) {
if (upd_get_nth_field(update, j)
->field_no == i) {
goto updated;
}
}
}
btr_cur_set_ownership_of_extern_field( btr_cur_set_ownership_of_extern_field(
page_zip, rec, index, offsets, i, FALSE, mtr); page_zip, rec, index, offsets, i, FALSE, mtr);
change_ownership = TRUE;
updated:
;
}
}
return(change_ownership);
}
/*******************************************************************//**
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
const upd_t* update) /*!< in: update vector */
{
ulint i;
for (i = 0; i < dtuple_get_n_fields(entry); i++) {
dfield_t* dfield = dtuple_get_nth_field(entry, i);
byte* data;
ulint len;
ulint j;
if (!dfield_is_ext(dfield)) {
continue;
}
/* Check if it is in updated fields */
for (j = 0; j < upd_get_n_fields(update); j++) {
if (upd_get_nth_field(update, j)->field_no == i) {
goto is_updated;
}
} }
data = dfield_get_data(dfield);
len = dfield_get_len(dfield);
data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN]
|= BTR_EXTERN_INHERITED_FLAG;
is_updated:
;
} }
} }
...@@ -3893,29 +3812,6 @@ btr_cur_unmark_extern_fields( ...@@ -3893,29 +3812,6 @@ btr_cur_unmark_extern_fields(
} }
} }
/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
dtuple_t* entry) /*!< in/out: clustered index entry */
{
ulint i;
for (i = 0; i < dtuple_get_n_fields(entry); i++) {
dfield_t* dfield = dtuple_get_nth_field(entry, i);
if (dfield_is_ext(dfield)) {
byte* data = dfield_get_data(dfield);
ulint len = dfield_get_len(dfield);
data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN]
&= ~BTR_EXTERN_OWNER_FLAG;
}
}
}
/*******************************************************************//** /*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must update vector. We use this function to remember which fields we must
......
...@@ -333,10 +333,14 @@ ulint ...@@ -333,10 +333,14 @@ ulint
btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec(
/*===========================*/ /*===========================*/
ulint flags, /*!< in: undo logging and locking flags */ ulint flags, /*!< in: undo logging and locking flags */
btr_cur_t* cursor, /*!< in: cursor */ buf_block_t* block, /*!< in/out: buffer block of the record */
rec_t* rec, /*!< in/out: record */
dict_index_t* index, /*!< in: clustered index of the record */
const ulint* offsets,/*!< in: rec_get_offsets(rec) */
ibool val, /*!< in: value to set */ ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */ que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
/***********************************************************//** /***********************************************************//**
Sets a secondary index record delete mark to TRUE or FALSE. Sets a secondary index record delete mark to TRUE or FALSE.
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */ @return DB_SUCCESS, DB_LOCK_WAIT, or error number */
...@@ -469,40 +473,22 @@ btr_estimate_number_of_different_key_vals( ...@@ -469,40 +473,22 @@ btr_estimate_number_of_different_key_vals(
/*======================================*/ /*======================================*/
dict_index_t* index); /*!< in: index */ dict_index_t* index); /*!< in: index */
/*******************************************************************//** /*******************************************************************//**
Marks not updated extern fields as not-owned by this record. The ownership Marks non-updated off-page fields as disowned by this record. The ownership
is transferred to the updated record which is inserted elsewhere in the must be transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed index tree. In purge only the owner of externally stored field is allowed
to free the field. to free the field. */
@return TRUE if BLOB ownership was transferred */
UNIV_INTERN UNIV_INTERN
ibool void
btr_cur_mark_extern_inherited_fields( btr_cur_disown_inherited_fields(
/*=================================*/ /*============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */ part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */ rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */ dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */ const upd_t* update, /*!< in: update vector */
mtr_t* mtr); /*!< in: mtr, or NULL if not logged */ mtr_t* mtr) /*!< in/out: mini-transaction */
/*******************************************************************//** __attribute__((nonnull(2,3,4,5,6)));
The complement of the previous function: in an update entry may inherit
some externally stored fields from a record. We must mark them as inherited
in entry, so that they are not freed in a rollback. */
UNIV_INTERN
void
btr_cur_mark_dtuple_inherited_extern(
/*=================================*/
dtuple_t* entry, /*!< in/out: updated entry to be
inserted to clustered index */
const upd_t* update); /*!< in: update vector */
/*******************************************************************//**
Marks all extern fields in a dtuple as owned by the record. */
UNIV_INTERN
void
btr_cur_unmark_dtuple_extern_fields(
/*================================*/
dtuple_t* entry); /*!< in/out: clustered index entry */
/*******************************************************************//** /*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand. them in rec. The extern flags in rec will have to be set beforehand.
......
...@@ -154,14 +154,19 @@ dfield_dup( ...@@ -154,14 +154,19 @@ dfield_dup(
dfield_t* field, /*!< in/out: data field */ dfield_t* field, /*!< in/out: data field */
mem_heap_t* heap); /*!< in: memory heap where allocated */ mem_heap_t* heap); /*!< in: memory heap where allocated */
/*********************************************************************//** /*********************************************************************//**
Tests if data length and content is equal for two dfields. Tests if two data fields are equal.
@return TRUE if equal */ If len==0, tests the data length and content for equality.
If len>0, tests the first len bytes of the content for equality.
@return TRUE if both fields are NULL or if they are equal */
UNIV_INLINE UNIV_INLINE
ibool ibool
dfield_datas_are_binary_equal( dfield_datas_are_binary_equal(
/*==========================*/ /*==========================*/
const dfield_t* field1, /*!< in: field */ const dfield_t* field1, /*!< in: field */
const dfield_t* field2);/*!< in: field */ const dfield_t* field2, /*!< in: field */
ulint len) /*!< in: maximum prefix to compare,
or 0 to compare the whole field length */
__attribute__((nonnull, warn_unused_result));
/*********************************************************************//** /*********************************************************************//**
Tests if dfield data length and content is equal to the given. Tests if dfield data length and content is equal to the given.
@return TRUE if equal */ @return TRUE if equal */
......
...@@ -229,20 +229,30 @@ dfield_dup( ...@@ -229,20 +229,30 @@ dfield_dup(
} }
/*********************************************************************//** /*********************************************************************//**
Tests if data length and content is equal for two dfields. Tests if two data fields are equal.
@return TRUE if equal */ If len==0, tests the data length and content for equality.
If len>0, tests the first len bytes of the content for equality.
@return TRUE if both fields are NULL or if they are equal */
UNIV_INLINE UNIV_INLINE
ibool ibool
dfield_datas_are_binary_equal( dfield_datas_are_binary_equal(
/*==========================*/ /*==========================*/
const dfield_t* field1, /*!< in: field */ const dfield_t* field1, /*!< in: field */
const dfield_t* field2) /*!< in: field */ const dfield_t* field2, /*!< in: field */
ulint len) /*!< in: maximum prefix to compare,
or 0 to compare the whole field length */
{ {
ulint len; ulint len2 = len;
len = field1->len; if (field1->len == UNIV_SQL_NULL || len == 0 || field1->len < len) {
len = field1->len;
}
if (field2->len == UNIV_SQL_NULL || len2 == 0 || field2->len < len2) {
len2 = field2->len;
}
return(len == field2->len return(len == len2
&& (len == UNIV_SQL_NULL && (len == UNIV_SQL_NULL
|| !memcmp(field1->data, field2->data, len))); || !memcmp(field1->data, field2->data, len)));
} }
......
...@@ -286,10 +286,13 @@ row_upd_changes_ord_field_binary( ...@@ -286,10 +286,13 @@ row_upd_changes_ord_field_binary(
row and the data values in update are not row and the data values in update are not
known when this function is called, e.g., at known when this function is called, e.g., at
compile time */ compile time */
const row_ext_t*ext, /*!< NULL, or prefixes of the externally
stored columns in the old row */
dict_index_t* index, /*!< in: index of the record */ dict_index_t* index, /*!< in: index of the record */
const upd_t* update);/*!< in: update vector for the row; NOTE: the const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index field numbers in this MUST be clustered index
positions! */ positions! */
__attribute__((nonnull(3,4), warn_unused_result));
/***********************************************************//** /***********************************************************//**
Checks if an update vector changes an ordering field of an index record. Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering This function is fast if the update vector is short or the number of ordering
...@@ -462,11 +465,16 @@ struct upd_node_struct{ ...@@ -462,11 +465,16 @@ struct upd_node_struct{
#define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be
inserted, old record is already delete inserted, old record is already delete
marked */ marked */
#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered #define UPD_NODE_INSERT_BLOB 4 /* clustered index record should be
inserted, old record is already
delete-marked; non-updated BLOBs
should be inherited by the new record
and disowned by the old record */
#define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered
index record was changed, or this is index record was changed, or this is
a delete operation: should update a delete operation: should update
all the secondary index records */ all the secondary index records */
#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be #define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be
looked at and updated if an ordering looked at and updated if an ordering
field changed */ field changed */
......
...@@ -515,7 +515,7 @@ row_purge_upd_exist_or_extern( ...@@ -515,7 +515,7 @@ row_purge_upd_exist_or_extern(
while (node->index != NULL) { while (node->index != NULL) {
index = node->index; index = node->index;
if (row_upd_changes_ord_field_binary(NULL, node->index, if (row_upd_changes_ord_field_binary(NULL, NULL, node->index,
node->update)) { node->update)) {
/* Build the older version of the index entry */ /* Build the older version of the index entry */
entry = row_build_index_entry(node->row, NULL, entry = row_build_index_entry(node->row, NULL,
......
...@@ -693,19 +693,18 @@ row_undo_mod_upd_exist_sec( ...@@ -693,19 +693,18 @@ row_undo_mod_upd_exist_sec(
while (node->index != NULL) { while (node->index != NULL) {
index = node->index; index = node->index;
if (row_upd_changes_ord_field_binary(node->row, node->index, if (row_upd_changes_ord_field_binary(
node->update)) { node->row, node->ext, node->index, node->update)) {
/* Build the newest version of the index entry */ /* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, node->ext, entry = row_build_index_entry(node->row, node->ext,
index, heap); index, heap);
if (UNIV_UNLIKELY(!entry)) { if (UNIV_UNLIKELY(!entry)) {
/* The server must have crashed in /* The server must have crashed in
row_upd_clust_rec_by_insert(), in row_upd_clust_rec_by_insert() before
row_ins_index_entry_low() before the updated externally stored columns (BLOBs)
btr_store_big_rec_extern_fields() of the new clustered index entry were
has written the externally stored columns written. */
(BLOBs) of the new clustered index entry. */
/* The table must be in DYNAMIC or COMPRESSED /* The table must be in DYNAMIC or COMPRESSED
format. REDUNDANT and COMPACT formats format. REDUNDANT and COMPACT formats
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment