diff options
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 43 | ||||
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 41 | ||||
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 199 | ||||
-rw-r--r-- | storage/innobase/ibuf/ibuf0ibuf.cc | 14 | ||||
-rw-r--r-- | storage/innobase/include/buf0buf.h | 11 | ||||
-rw-r--r-- | storage/innobase/include/fil0crypt.h | 11 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 64 |
8 files changed, 142 insertions, 245 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 7133f3cfd7e..d1e008d8be4 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -525,9 +525,13 @@ decompress_with_slot: + dst_frame)) { /* Verify encryption checksum before we even try to decrypt. */ - if (!fil_space_verify_crypt_checksum( - dst_frame, bpage->size, bpage->id.space(), - bpage->id.page_no())) { + if (!fil_space_verify_crypt_checksum(dst_frame, bpage->size)) { + ib::error() << "Encrypted page " << bpage->id + << " in file " << space->chain.start->name + << " looks corrupted; key_version=" + << mach_read_from_4( + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + + dst_frame); decrypt_failed: /* Mark page encrypted in case it should be. */ if (space->crypt_data->type @@ -733,23 +737,6 @@ buf_block_alloc( } #endif /* !UNIV_INNOCHECKSUM */ -/** Checks if a page contains only zeroes. -@param[in] read_buf database page -@param[in] page_size page size -@return true if page is filled with zeroes */ -bool -buf_page_is_zeroes( - const byte* read_buf, - const page_size_t& page_size) -{ - for (ulint i = 0; i < page_size.logical(); i++) { - if (read_buf[i] != 0) { - return(false); - } - } - return(true); -} - /** Checks if the page is in crc32 checksum format. @param[in] read_buf database page @param[in] checksum_field1 new checksum field @@ -5891,18 +5878,14 @@ or decrypt/decompress just failed. @retval DB_DECRYPTION_FAILED if page post encryption checksum matches but after decryption normal page checksum does not match. @retval DB_TABLESPACE_DELETED if accessed tablespace is not found */ -static -dberr_t -buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) +static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) { ut_ad(space->pending_io()); byte* dst_frame = (bpage->zip.data) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - bool still_encrypted = false; dberr_t err = DB_SUCCESS; bool corrupted = false; - fil_space_crypt_t* crypt_data = space->crypt_data; /* In buf_decrypt_after_read we have either decrypted the page if page post encryption checksum matches and used key_id is found @@ -5910,12 +5893,12 @@ buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) not decrypted and it could be either encrypted and corrupted or corrupted or good page. If we decrypted, there page could still be corrupted if used key does not match. */ - still_encrypted = crypt_data - && crypt_data->type != CRYPT_SCHEME_UNENCRYPTED + const bool still_encrypted = mach_read_from_4( + dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + && space->crypt_data + && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED && !bpage->encrypted - && fil_space_verify_crypt_checksum( - dst_frame, bpage->size, - bpage->id.space(), bpage->id.page_no()); + && fil_space_verify_crypt_checksum(dst_frame, bpage->size); if (!still_encrypted) { /* If traditional checksums match, we assume that page is diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 099a3752f7f..785ec21a7bf 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -335,6 +335,20 @@ too_small: goto start_again; } +/** Check if a page is all zeroes. +@param[in] read_buf database page +@param[in] page_size page frame size +@return whether the page is all zeroes */ +static bool buf_page_is_zeroes(const byte* read_buf, size_t page_size) +{ + for (ulint i = 0; i < page_size; i++) { + if (read_buf[i] != 0) { + return false; + } + } + return true; +} + /** At database startup initializes the doublewrite buffer memory structure if we already have a doublewrite buffer created in the data files. If we are @@ -570,7 +584,7 @@ buf_dblwr_process() } const page_size_t page_size(space->flags); - ut_ad(!buf_page_is_zeroes(page, page_size)); + ut_ad(!buf_page_is_zeroes(page, page_size.physical())); /* We want to ensure that for partial reads the unread portion of the page is NUL. */ @@ -594,7 +608,9 @@ buf_dblwr_process() } const bool is_all_zero = buf_page_is_zeroes( - read_buf, page_size); + read_buf, page_size.physical()); + const bool expect_encrypted = space->crypt_data + && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; if (is_all_zero) { /* We will check if the copy in the @@ -610,10 +626,13 @@ buf_dblwr_process() goto bad; } - if (fil_space_verify_crypt_checksum( - read_buf, page_size, space_id, page_no) - || !buf_page_is_corrupted( - true, read_buf, page_size, space)) { + if (expect_encrypted && mach_read_from_4( + read_buf + + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + ? fil_space_verify_crypt_checksum(read_buf, + page_size) + : !buf_page_is_corrupted(true, read_buf, + page_size, space)) { /* The page is good; there is no need to consult the doublewrite buffer. */ continue; @@ -632,9 +651,11 @@ bad: && page_size.is_compressed())) { goto bad_doublewrite; } - if (!fil_space_verify_crypt_checksum(page, page_size, - space_id, page_no) - && buf_page_is_corrupted(true, page, page_size, space)) { + + if (expect_encrypted && mach_read_from_4( + page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) + ? !fil_space_verify_crypt_checksum(page, page_size) + : buf_page_is_corrupted(true, page, page_size, space)) { if (!is_all_zero) { bad_doublewrite: ib::warn() << "A doublewrite copy of page " diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 637cf6f6173..e5c2b91cfdf 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -615,8 +615,7 @@ fil_encrypt_buf( // store the post-encryption checksum after the key-version mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum); - ut_ad(fil_space_verify_crypt_checksum(dst_frame, page_size, - space, offset)); + ut_ad(fil_space_verify_crypt_checksum(dst_frame, page_size)); srv_stats.pages_encrypted.inc(); @@ -2526,164 +2525,78 @@ encrypted, or corrupted. @param[in,out] page page frame (checksum is temporarily modified) @param[in] page_size page size -@param[in] space tablespace identifier -@param[in] offset page number -@return true if page is encrypted AND OK, false otherwise */ -UNIV_INTERN +@return whether the encrypted page is OK */ bool -fil_space_verify_crypt_checksum( - byte* page, - const page_size_t& page_size, - ulint space, - ulint offset) +fil_space_verify_crypt_checksum(const byte* page, const page_size_t& page_size) { - uint key_version = mach_read_from_4(page+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); - - /* If page is not encrypted, return false */ - if (key_version == 0) { - return false; - } - - /* Read stored post encryption checksum. */ - uint32_t checksum = mach_read_from_4( - page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4); - - /* Declare empty pages non-corrupted */ - if (checksum == 0 - && *reinterpret_cast<const ib_uint64_t*>(page + FIL_PAGE_LSN) == 0 - && buf_page_is_zeroes(page, page_size)) { - return(true); - } + ut_ad(mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)); /* Compressed and encrypted pages do not have checksum. Assume not corrupted. Page verification happens after decompression in buf_page_io_complete() using buf_page_is_corrupted(). */ - if (mach_read_from_2(page+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { - return (true); + if (mach_read_from_2(page + FIL_PAGE_TYPE) + == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) { + return true; } - uint32_t cchecksum1, cchecksum2; - - /* Calculate checksums */ - if (page_size.is_compressed()) { - cchecksum1 = page_zip_calc_checksum( - page, page_size.physical(), - SRV_CHECKSUM_ALGORITHM_CRC32); - - cchecksum2 = (cchecksum1 == checksum) - ? 0 - : page_zip_calc_checksum( - page, page_size.physical(), - SRV_CHECKSUM_ALGORITHM_INNODB); - } else { - cchecksum1 = buf_calc_page_crc32(page); - cchecksum2 = (cchecksum1 == checksum) - ? 0 - : buf_calc_page_new_checksum(page); - } + /* Read stored post encryption checksum. */ + const ib_uint32_t checksum = mach_read_from_4( + page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4); /* If stored checksum matches one of the calculated checksums page is not corrupted. */ + srv_checksum_algorithm_t algorithm = srv_checksum_algorithm_t( + srv_checksum_algorithm); - bool encrypted = (checksum == cchecksum1 || checksum == cchecksum2 - || checksum == BUF_NO_CHECKSUM_MAGIC); - - /* MySQL 5.6 and MariaDB 10.0 and 10.1 will write an LSN to the - first page of each system tablespace file at - FIL_PAGE_FILE_FLUSH_LSN offset. On other pages and in other files, - the field might have been uninitialized until MySQL 5.5. In MySQL 5.7 - (and MariaDB Server 10.2.2) WL#7990 stopped writing the field for other - than page 0 of the system tablespace. - - Starting from MariaDB 10.1 the field has been repurposed for - encryption key_version. - - Starting with MySQL 5.7 (and MariaDB Server 10.2), the - field has been repurposed for SPATIAL INDEX pages for - FIL_RTREE_SPLIT_SEQ_NUM. - - Note that FIL_PAGE_FILE_FLUSH_LSN is not included in the InnoDB page - checksum. - - Thus, FIL_PAGE_FILE_FLUSH_LSN could contain any value. While the - field would usually be 0 for pages that are not encrypted, we cannot - assume that a nonzero value means that the page is encrypted. - Therefore we must validate the page both as encrypted and unencrypted - when FIL_PAGE_FILE_FLUSH_LSN does not contain 0. - */ - - uint32_t checksum1 = mach_read_from_4(page + FIL_PAGE_SPACE_OR_CHKSUM); - uint32_t checksum2; + switch (algorithm) { + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + if (page_size.is_compressed()) { + return checksum == page_zip_calc_checksum( + page, page_size.physical(), + SRV_CHECKSUM_ALGORITHM_CRC32); + } - bool valid = false; + return checksum == buf_calc_page_crc32(page) +#ifdef INNODB_BUG_ENDIAN_CRC32 + || checksum == buf_calc_page_crc32(page, true) +#endif + ; + case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: + if (page_size.is_compressed()) { + return checksum == page_zip_calc_checksum( + page, page_size.physical(), + SRV_CHECKSUM_ALGORITHM_INNODB); + } + return checksum == buf_calc_page_new_checksum(page); + case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: + return checksum == BUF_NO_CHECKSUM_MAGIC; + case SRV_CHECKSUM_ALGORITHM_NONE: + return true; + case SRV_CHECKSUM_ALGORITHM_INNODB: + case SRV_CHECKSUM_ALGORITHM_CRC32: + if (checksum == BUF_NO_CHECKSUM_MAGIC) { + return true; + } + if (page_size.is_compressed()) { + if (checksum == page_zip_calc_checksum( + page, page_size.physical(), algorithm)) { + return true; + } - if (page_size.is_compressed()) { - valid = checksum1 == cchecksum1; - checksum2 = checksum1; - } else { - checksum2 = mach_read_from_4( - page + srv_page_size - FIL_PAGE_END_LSN_OLD_CHKSUM); - - srv_checksum_algorithm_t algorithm = - static_cast<srv_checksum_algorithm_t>( - srv_checksum_algorithm); - switch (algorithm) { - case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: - valid = buf_page_is_checksum_valid_crc32( - page, checksum1, checksum2); - break; - case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB: - valid = buf_page_is_checksum_valid_innodb( - page, checksum1, checksum2); - break; - case SRV_CHECKSUM_ALGORITHM_STRICT_NONE: - case SRV_CHECKSUM_ALGORITHM_CRC32: - case SRV_CHECKSUM_ALGORITHM_INNODB: - case SRV_CHECKSUM_ALGORITHM_NONE: - /* never supported - innodb_checksum_algorithm=none or strict_none - for encrypted pages. */ - valid = buf_page_is_checksum_valid_crc32( - page, checksum1, checksum2) - || buf_page_is_checksum_valid_innodb( - page, checksum1, checksum2); - break; + algorithm = algorithm == SRV_CHECKSUM_ALGORITHM_INNODB + ? SRV_CHECKSUM_ALGORITHM_CRC32 + : SRV_CHECKSUM_ALGORITHM_INNODB; + return checksum == page_zip_calc_checksum( + page, page_size.physical(), algorithm); } - } - if (encrypted && valid) { - /* If page is encrypted and traditional checksums match, - page could be still encrypted, or not encrypted and valid or - corrupted. */ -#ifdef UNIV_INNOCHECKSUM - fprintf(log_file ? log_file : stderr, - "Page " ULINTPF ":" ULINTPF " may be corrupted." - " Post encryption checksum %u" - " stored [%u:%u] key_version %u\n", - space, offset, checksum, checksum1, checksum2, - key_version); -#else /* UNIV_INNOCHECKSUM */ - ib::error() - << " Page " << space << ":" << offset - << " may be corrupted."; - ib::info() - << "If encrypted: stored checksum" << checksum - << " calculated checksum [" << cchecksum1 << ":" << cchecksum2 - << "] key_version " << key_version; - ib::info() - << "If unencrypted: stored checksum [" << checksum1 - << ":" << checksum2 << "] calculated crc32 [" - << buf_calc_page_crc32(page) -# ifdef INNODB_BUG_ENDIAN_CRC32 - << ":" << buf_calc_page_crc32(page, true) -# endif /* INNODB_BUG_ENDIAN_CRC32 */ - << "] innodb [" - << buf_calc_page_old_checksum(page) << ":" - << buf_calc_page_new_checksum(page) << "] LSN " - << mach_read_from_4(page + FIL_PAGE_LSN); + return checksum == buf_calc_page_crc32(page) +#ifdef INNODB_BUG_ENDIAN_CRC32 + || checksum == buf_calc_page_crc32(page, true) #endif - encrypted = false; + || checksum == buf_calc_page_new_checksum(page); } - return(encrypted); + ut_ad(!"unhandled innodb_checksum_algorithm"); + return false; } diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 9ed1efd35ff..261fbb05c63 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -4927,6 +4927,20 @@ ibuf_print( mutex_exit(&ibuf_mutex); } +/** Check if a page is all zeroes. +@param[in] read_buf database page +@param[in] size page size +@return whether the page is all zeroes */ +static bool buf_page_is_zeroes(const byte* read_buf, const page_size_t& size) +{ + for (ulint i = 0; i < size.physical(); i++) { + if (read_buf[i] != 0) { + return false; + } + } + return true; +} + /** Check the insert buffer bitmaps on IMPORT TABLESPACE. @param[in] trx transaction @param[in,out] space tablespace being imported diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 86a433d36e3..1be2063bf60 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -748,15 +748,6 @@ buf_page_is_checksum_valid_none( ulint checksum_field2) MY_ATTRIBUTE((nonnull(1), warn_unused_result)); -/** Checks if a page contains only zeroes. -@param[in] read_buf database page -@param[in] page_size page size -@return true if page is filled with zeroes */ -bool -buf_page_is_zeroes( - const byte* read_buf, - const page_size_t& page_size); - /** Check if a page is corrupt. @param[in] check_lsn whether the LSN should be checked @param[in] read_buf database page @@ -775,9 +766,7 @@ buf_page_is_corrupted( #endif MY_ATTRIBUTE((warn_unused_result)); - #ifndef UNIV_INNOCHECKSUM - /**********************************************************************//** Gets the space id, page offset, and byte offset within page of a pointer pointing to a buffer frame containing a file page. */ diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 5238213135f..77445fb8a0e 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -1,6 +1,6 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -488,16 +488,9 @@ encrypted, or corrupted. @param[in,out] page page frame (checksum is temporarily modified) @param[in] page_size page size -@param[in] space tablespace identifier -@param[in] offset page number @return true if page is encrypted AND OK, false otherwise */ -UNIV_INTERN bool -fil_space_verify_crypt_checksum( - byte* page, - const page_size_t& page_size, - ulint space, - ulint offset) +fil_space_verify_crypt_checksum(const byte* page, const page_size_t& page_size) MY_ATTRIBUTE((warn_unused_result)); #endif /* fil0crypt_h */ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 1fdd2ac9b94..5a4321e5fe7 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3433,9 +3433,7 @@ not_encrypted: } } else { if (!fil_space_verify_crypt_checksum( - src, callback.get_page_size(), - block->page.id.space(), - block->page.id.page_no())) { + src, callback.get_page_size())) { goto page_corrupted; } diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 15d6ab8e76e..f5a690ce2f2 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -115,14 +115,12 @@ public: @param[in,out] row_heap memory heap @param[in] pcur cluster index scanning cursor @param[in,out] scan_mtr mini-transaction for pcur - @param[out] mtr_committed whether scan_mtr got committed @return DB_SUCCESS if successful, else error number */ - dberr_t insert( + inline dberr_t insert( trx_id_t trx_id, mem_heap_t* row_heap, btr_pcur_t* pcur, - mtr_t* scan_mtr, - bool* mtr_committed) + mtr_t* scan_mtr) { big_rec_t* big_rec; rec_t* rec; @@ -150,11 +148,10 @@ public: ut_ad(dtuple); if (log_sys.check_flush_or_checkpoint) { - if (!(*mtr_committed)) { + if (scan_mtr->is_active()) { btr_pcur_move_to_prev_on_page(pcur); btr_pcur_store_position(pcur, scan_mtr); - mtr_commit(scan_mtr); - *mtr_committed = true; + scan_mtr->commit(); } log_free_check(); @@ -1589,7 +1586,6 @@ row_mtuple_cmp( @param[in,out] sp_heap heap for tuples @param[in,out] pcur cluster index cursor @param[in,out] mtr mini transaction -@param[in,out] mtr_committed whether scan_mtr got committed @return DB_SUCCESS or error number */ static dberr_t @@ -1600,8 +1596,7 @@ row_merge_spatial_rows( mem_heap_t* row_heap, mem_heap_t* sp_heap, btr_pcur_t* pcur, - mtr_t* mtr, - bool* mtr_committed) + mtr_t* mtr) { dberr_t err = DB_SUCCESS; @@ -1612,9 +1607,7 @@ row_merge_spatial_rows( ut_ad(sp_heap != NULL); for (ulint j = 0; j < num_spatial; j++) { - err = sp_tuples[j]->insert( - trx_id, row_heap, - pcur, mtr, mtr_committed); + err = sp_tuples[j]->insert(trx_id, row_heap, pcur, mtr); if (err != DB_SUCCESS) { return(err); @@ -1718,7 +1711,7 @@ row_merge_read_clustered_index( bool allow_not_null) { dict_index_t* clust_index; /* Clustered index */ - mem_heap_t* row_heap; /* Heap memory to create + mem_heap_t* row_heap = NULL;/* Heap memory to create clustered index tuples */ row_merge_buf_t** merge_buf; /* Temporary list for records*/ mem_heap_t* v_heap = NULL; /* Heap memory to process large @@ -1933,6 +1926,13 @@ row_merge_read_clustered_index( /* Scan the clustered index. */ for (;;) { + /* Do not continue if table pages are still encrypted */ + if (!old_table->is_readable() || !new_table->is_readable()) { + err = DB_DECRYPTION_FAILED; + trx->error_key_num = 0; + goto func_exit; + } + const rec_t* rec; trx_id_t rec_trx_id; ulint* offsets; @@ -1942,16 +1942,6 @@ row_merge_read_clustered_index( mem_heap_empty(row_heap); - /* Do not continue if table pages are still encrypted */ - if (!old_table->is_readable() || - !new_table->is_readable()) { - err = DB_DECRYPTION_FAILED; - trx->error_key_num = 0; - goto func_exit; - } - - mem_heap_empty(row_heap); - page_cur_move_to_next(cur); stage->n_pk_recs_inc(); @@ -1975,18 +1965,15 @@ row_merge_read_clustered_index( } /* Insert the cached spatial index rows. */ - bool mtr_committed = false; - err = row_merge_spatial_rows( trx->id, sp_tuples, num_spatial, - row_heap, sp_heap, &pcur, - &mtr, &mtr_committed); + row_heap, sp_heap, &pcur, &mtr); if (err != DB_SUCCESS) { goto func_exit; } - if (mtr_committed) { + if (!mtr.is_active()) { goto scan_next; } @@ -2029,7 +2016,9 @@ end_of_index: row = NULL; mtr_commit(&mtr); mem_heap_free(row_heap); + row_heap = NULL; ut_free(nonnull); + nonnull = NULL; goto write_buffers; } } else { @@ -2475,8 +2464,6 @@ write_buffers: /* Temporary File is not used. so insert sorted block to the index */ if (row != NULL) { - bool mtr_committed = false; - /* We have to do insert the cached spatial index rows, since after the mtr_commit, the cluster @@ -2487,8 +2474,7 @@ write_buffers: trx->id, sp_tuples, num_spatial, row_heap, sp_heap, - &pcur, &mtr, - &mtr_committed); + &pcur, &mtr); if (err != DB_SUCCESS) { goto func_exit; @@ -2503,13 +2489,13 @@ write_buffers: current row will be invalid, and we must reread it on the next loop iteration. */ - if (!mtr_committed) { + if (mtr.is_active()) { btr_pcur_move_to_prev_on_page( &pcur); btr_pcur_store_position( &pcur, &mtr); - mtr_commit(&mtr); + mtr.commit(); } } @@ -2666,7 +2652,7 @@ write_buffers: buf->n_tuples, path)) { err = DB_OUT_OF_MEMORY; trx->error_key_num = i; - goto func_exit; + break; } /* Ensure that duplicates in the @@ -2748,12 +2734,12 @@ write_buffers: } func_exit: - /* row_merge_spatial_rows may have committed - the mtr before an error occurs. */ if (mtr.is_active()) { mtr_commit(&mtr); } - mem_heap_free(row_heap); + if (row_heap) { + mem_heap_free(row_heap); + } ut_free(nonnull); all_done: |