From 84b2f38d01bce437a8a87dbaf9c3a6c242231d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 14 Aug 2013 09:43:21 +0300 Subject: [PATCH] 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 --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/btr/btr0cur.c | 18 ++++++++++++------ storage/innodb_plugin/row/row0uins.c | 15 ++++++++------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 22d1067455e..3c63e25f6e1 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +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 * page/page0zip.c: diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 4392fc16a5b..2b98b416793 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -4320,6 +4320,10 @@ next_zip_page: } } } + + DBUG_EXECUTE_IF("btr_store_big_rec_extern", + error = DB_OUT_OF_FILE_SPACE; + goto func_exit;); } func_exit: @@ -4352,9 +4356,11 @@ func_exit: 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, - BTR_EXTERN_FIELD_REF_SIZE)); + BTR_EXTERN_FIELD_REF_SIZE) + || error != DB_SUCCESS); /* The column must not be disowned by this record. */ ut_a(!(field_ref[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG)); } @@ -4450,10 +4456,10 @@ btr_free_externally_stored_field( if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) { - /* In the rollback of uncommitted transactions, we may - encounter a clustered index record whose BLOBs have - not been written. There is nothing to free then. */ - ut_a(rb_ctx == RB_RECOVERY || rb_ctx == RB_RECOVERY_PURGE_REC); + /* In the rollback, we may encounter a clustered index + record with some unwritten off-page columns. There is + nothing to free then. */ + ut_a(rb_ctx != RB_NONE); return; } diff --git a/storage/innodb_plugin/row/row0uins.c b/storage/innodb_plugin/row/row0uins.c index 2bf91542bb7..aa12802d081 100644 --- a/storage/innodb_plugin/row/row0uins.c +++ b/storage/innodb_plugin/row/row0uins.c @@ -336,13 +336,14 @@ row_undo_ins( /* The database must have crashed after inserting a clustered index record but before writing all the externally stored columns of - that record. Because secondary index entries - are inserted after the clustered index record, - we may assume that the secondary index record - does not exist. However, this situation may - only occur during the rollback of incomplete - transactions. */ - ut_a(trx_is_recv(node->trx)); + that record, or a statement is being rolled + back because an error occurred while storing + off-page columns. + + Because secondary index entries are inserted + after the clustered index record, we may + assume that the secondary index record does + not exist. */ } else { log_free_check(); err = row_undo_ins_remove_sec(node->index, entry);