Commit 300ac936 authored by Marko Mäkelä's avatar Marko Mäkelä

Bug#16971045 ASSERTION FAILURES ON ROLLBACK OF AN INSERT AFTER A

FAILED BLOB WRITE

btr_store_big_rec_extern_fields(): Relax a debug assertion so that
some BLOB pointers may remain zero if an error occurs.

btr_free_externally_stored_field(), row_undo_ins(): Allow the BLOB
pointer to be zero on any rollback.

rb#3059 approved by Jimmy Yang, Kevin Lewis
parent 8757f395
2013-08-14 The InnoDB Team
* btr/btr0cur.c, row/row0uins.c:
Fix Bug#16971045 ASSERTION FAILURES ON ROLLBACK OF AN INSERT AFTER
A FAILED BLOB WRITE
2013-05-15 The InnoDB Team 2013-05-15 The InnoDB Team
* page/page0zip.c: * page/page0zip.c:
......
...@@ -4320,6 +4320,10 @@ btr_store_big_rec_extern_fields( ...@@ -4320,6 +4320,10 @@ btr_store_big_rec_extern_fields(
} }
} }
} }
DBUG_EXECUTE_IF("btr_store_big_rec_extern",
error = DB_OUT_OF_FILE_SPACE;
goto func_exit;);
} }
func_exit: func_exit:
...@@ -4352,9 +4356,11 @@ btr_store_big_rec_extern_fields( ...@@ -4352,9 +4356,11 @@ btr_store_big_rec_extern_fields(
field_ref = btr_rec_get_field_ref(rec, offsets, i); field_ref = btr_rec_get_field_ref(rec, offsets, i);
/* The pointer must not be zero. */ /* The pointer must not be zero if the operation
succeeded. */
ut_a(0 != memcmp(field_ref, field_ref_zero, ut_a(0 != memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE)); BTR_EXTERN_FIELD_REF_SIZE)
|| error != DB_SUCCESS);
/* The column must not be disowned by this record. */ /* The column must not be disowned by this record. */
ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
} }
...@@ -4450,10 +4456,10 @@ btr_free_externally_stored_field( ...@@ -4450,10 +4456,10 @@ btr_free_externally_stored_field(
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero, if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
BTR_EXTERN_FIELD_REF_SIZE))) { BTR_EXTERN_FIELD_REF_SIZE))) {
/* In the rollback of uncommitted transactions, we may /* In the rollback, we may encounter a clustered index
encounter a clustered index record whose BLOBs have record with some unwritten off-page columns. There is
not been written. There is nothing to free then. */ nothing to free then. */
ut_a(rb_ctx == RB_RECOVERY || rb_ctx == RB_RECOVERY_PURGE_REC); ut_a(rb_ctx != RB_NONE);
return; return;
} }
......
...@@ -336,13 +336,14 @@ row_undo_ins( ...@@ -336,13 +336,14 @@ row_undo_ins(
/* The database must have crashed after /* The database must have crashed after
inserting a clustered index record but before inserting a clustered index record but before
writing all the externally stored columns of writing all the externally stored columns of
that record. Because secondary index entries that record, or a statement is being rolled
are inserted after the clustered index record, back because an error occurred while storing
we may assume that the secondary index record off-page columns.
does not exist. However, this situation may
only occur during the rollback of incomplete Because secondary index entries are inserted
transactions. */ after the clustered index record, we may
ut_a(trx_is_recv(node->trx)); assume that the secondary index record does
not exist. */
} else { } else {
log_free_check(); log_free_check();
err = row_undo_ins_remove_sec(node->index, entry); err = row_undo_ins_remove_sec(node->index, entry);
......
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