diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-07-20 08:56:09 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-07-20 08:56:09 +0300 |
commit | a481de30bb972f055cff088a84a211c1acd5be38 (patch) | |
tree | 680d500eddf7b51bd2086218a01a42b28efa1f51 /storage | |
parent | e8a2a751212a04e835b2b03408132ecbbab52410 (diff) | |
parent | 59fca5806af65c8379a993f9e604cb0b20a76e2b (diff) | |
download | mariadb-git-a481de30bb972f055cff088a84a211c1acd5be38.tar.gz |
Merge tag 'mariadb-5.5.57' into 5.5-galera
Diffstat (limited to 'storage')
39 files changed, 272 insertions, 230 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 872373bbeb6..d39d1187ce6 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1640,7 +1640,6 @@ int ha_archive::info(uint flag) stats.update_time= (ulong) file_stat.st_mtime; if (flag & HA_STATUS_CONST) { - stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length; stats.max_data_file_length= MAX_FILE_SIZE; stats.create_time= (ulong) file_stat.st_ctime; } diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index a5e1c045b7b..80a15ffe0d5 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -2560,14 +2560,8 @@ wait_until_unfixed: } } buf_pool_mutex_exit(buf_pool); - fprintf(stderr, - "innodb_change_buffering_debug evict %u %u\n", - (unsigned) space, (unsigned) offset); return(NULL); } else if (buf_flush_page_try(buf_pool, block)) { - fprintf(stderr, - "innodb_change_buffering_debug flush %u %u\n", - (unsigned) space, (unsigned) offset); guess = block; goto loop; } diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index fb35edc3be3..198df72a1d6 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -4250,6 +4250,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, } */ DBUG_PRINT("info", ("is quick repair: %d", (int) rep_quick)); + if (!rep_quick) + my_b_clear(&new_data_cache); /* Initialize pthread structures before goto err. */ mysql_mutex_init(key_SORT_INFO_mutex, &sort_info.mutex, MY_MUTEX_INIT_FAST); @@ -4608,7 +4610,7 @@ err: already or they were not yet started (if the error happend before creating the threads). */ - if (!rep_quick) + if (!rep_quick && my_b_inited(&new_data_cache)) end_io_cache(&new_data_cache); if (!got_error) { diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index bf2205f5a4c..e2e52546fc9 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1269,6 +1269,7 @@ static my_bool translog_set_lsn_for_files(uint32 from_file, uint32 to_file, mysql_file_close(fd, MYF(MY_WME)))) { translog_stop_writing(); + mysql_mutex_unlock(&log_descriptor.file_header_lock); DBUG_RETURN(1); } } @@ -2291,10 +2292,11 @@ static void translog_set_only_in_buffers(TRANSLOG_ADDRESS in_buffers) if (cmp_translog_addr(in_buffers, log_descriptor.in_buffers_only) > 0) { if (translog_status != TRANSLOG_OK) - DBUG_VOID_RETURN; + goto end; log_descriptor.in_buffers_only= in_buffers; DBUG_PRINT("info", ("set new in_buffers_only")); } +end: mysql_mutex_unlock(&log_descriptor.sent_to_disk_lock); DBUG_VOID_RETURN; } @@ -7814,8 +7816,24 @@ void translog_flush_buffers(TRANSLOG_ADDRESS *lsn, translog_force_current_buffer_to_finish(); translog_buffer_unlock(buffer); } - else if (log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE) + else { + if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE) + { + /* + In this case both last_lsn & prev_last_lsn are LSN_IMPOSSIBLE + otherwise it will go in the first IF because LSN_IMPOSSIBLE less + then any real LSN and cmp_translog_addr(*lsn, + log_descriptor.bc.buffer->prev_last_lsn) will be TRUE + */ + DBUG_ASSERT(log_descriptor.bc.buffer->prev_last_lsn == + LSN_IMPOSSIBLE); + DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing")); + translog_unlock(); + DBUG_VOID_RETURN; + } + + DBUG_ASSERT(log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE); /* fix lsn if it was horizon */ *lsn= log_descriptor.bc.buffer->prev_last_lsn; DBUG_PRINT("info", ("LSN to flush fixed to prev last lsn: (%lu,0x%lx)", @@ -7824,13 +7842,6 @@ void translog_flush_buffers(TRANSLOG_ADDRESS *lsn, TRANSLOG_BUFFERS_NO); translog_unlock(); } - else if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE) - { - DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing")); - translog_unlock(); - DBUG_VOID_RETURN; - } - /* flush buffers */ *sent_to_disk= translog_get_sent_to_disk(); if (cmp_translog_addr(*lsn, *sent_to_disk) > 0) diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 1a791d43034..bb9f5a03ad7 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -3474,6 +3474,7 @@ restart: lock_to_read[lock].unlock_lock, unlock_pin, FALSE)) { + pagecache_pthread_mutex_unlock(&pagecache->cache_lock); DBUG_ASSERT(0); return (uchar*) 0; } diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 5e42ebc8d5d..b2e8705b15e 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -887,9 +887,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) if (create_database_if_not_exists(name)) goto end; fn_format(filename, name, "", MARIA_NAME_IEXT, - (MY_UNPACK_FILENAME | - (flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) | - MY_APPEND_EXT); + MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | MY_APPEND_EXT); linkname_ptr= NULL; create_flag= MY_DELETE_OLD; tprint(tracef, "Table '%s' creating as '%s'\n", name, filename); diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index df97d6035d8..23e54966e2d 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2676,6 +2676,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, */ DBUG_PRINT("info", ("is quick repair: %d", rep_quick)); bzero((char*)&sort_info,sizeof(sort_info)); + if (!rep_quick) + my_b_clear(&new_data_cache); /* Initialize pthread structures before goto err. */ mysql_mutex_init(mi_key_mutex_MI_SORT_INFO_mutex, &sort_info.mutex, MY_MUTEX_INIT_FAST); @@ -3050,7 +3052,7 @@ err: already or they were not yet started (if the error happend before creating the threads). */ - if (!rep_quick) + if (!rep_quick && my_b_inited(&new_data_cache)) (void) end_io_cache(&new_data_cache); if (!got_error) { diff --git a/storage/myisam/mysql-test/storage_engine/parts/disabled.def b/storage/myisam/mysql-test/storage_engine/parts/disabled.def new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/storage/myisam/mysql-test/storage_engine/parts/disabled.def diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c index fb670df2329..76c2d9cd8ae 100644 --- a/storage/xtradb/btr/btr0btr.c +++ b/storage/xtradb/btr/btr0btr.c @@ -2958,7 +2958,7 @@ Removes a page from the level list of pages. /*************************************************************//** Removes a page from the level list of pages. */ -static __attribute__((nonnull)) +static void btr_level_list_remove_func( /*=======================*/ diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c index 5f6ae046dbf..73cfc62d960 100644 --- a/storage/xtradb/buf/buf0buf.c +++ b/storage/xtradb/buf/buf0buf.c @@ -2852,9 +2852,6 @@ wait_until_unfixed: } } //buf_pool_mutex_exit(buf_pool); - fprintf(stderr, - "innodb_change_buffering_debug evict %u %u\n", - (unsigned) space, (unsigned) offset); return(NULL); } else if (UNIV_UNLIKELY(buf_block_get_state(block) @@ -2875,9 +2872,6 @@ wait_until_unfixed: ut_ad(!mutex_own(&buf_pool->LRU_list_mutex)); if (buf_flush_page_try(buf_pool, block)) { - fprintf(stderr, - "innodb_change_buffering_debug flush %u %u\n", - (unsigned) space, (unsigned) offset); guess = block; goto loop; } diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index 1529c22bbb9..e9484a04176 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -115,8 +115,8 @@ dict_create_sys_tables_tuple( if (table->flags & (~DICT_TF_COMPACT & ~(~0U << DICT_TF_BITS))) { ut_a(table->flags & DICT_TF_COMPACT); ut_a(dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP); - ut_a(((ulonglong) table->flags & DICT_TF_ZSSIZE_MASK) - <= (ulonglong) (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT)); + ut_a((table->flags & DICT_TF_ZSSIZE_MASK) + <= (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT)); ut_a(!(table->flags & (~0U << DICT_TF2_BITS))); mach_write_to_4(ptr, table->flags & ~(~0U << DICT_TF_BITS)); } else { diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index 4477b34f7b4..433fcdc8ffe 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -249,8 +249,7 @@ fsp_fill_free_list( then we do not allocate more extents */ ulint space, /*!< in: space */ fsp_header_t* header, /*!< in/out: space header */ - mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in/out: mini-transaction */ /**********************************************************************//** Allocates a single free page from a segment. This function implements the intelligent allocation strategy which tries to minimize file space @@ -279,7 +278,7 @@ fseg_alloc_free_page_low( in which the page should be initialized. If init_mtr!=mtr, but the page is already latched in mtr, do not initialize the page. */ - __attribute__((warn_unused_result, nonnull)); + __attribute__((warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -1568,7 +1567,7 @@ Allocates a single free page from a space. The page is marked as used. @retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded (init_mtr == mtr, or the page was not previously freed in mtr) @retval block (not allocated or initialized) otherwise */ -static __attribute__((nonnull, warn_unused_result)) +static __attribute__((warn_unused_result)) buf_block_t* fsp_alloc_free_page( /*================*/ diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index c868fbbedea..9f05a8a751c 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -7423,29 +7423,7 @@ i_s_innodb_changed_pages_fill( while(log_online_bitmap_iterator_next(&i) && (!srv_max_changed_pages || - output_rows_num < srv_max_changed_pages) && - /* - There is no need to compare both start LSN and end LSN fields - with maximum value. It's enough to compare only start LSN. - Example: - - max_lsn = 100 - \\\\\\\\\\\\\\\\\\\\\\\\\|\\\\\\\\ - Query 1 - I------I I-------I I-------------I I----I - ////////////////// | - Query 2 - 1 2 3 4 - - Query 1: - SELECT * FROM INNODB_CHANGED_PAGES WHERE start_lsn < 100 - will select 1,2,3 bitmaps - Query 2: - SELECT * FROM INNODB_CHANGED_PAGES WHERE end_lsn < 100 - will select 1,2 bitmaps - - The condition start_lsn <= 100 will be false after reading - 1,2,3 bitmaps which suits for both cases. - */ - LOG_BITMAP_ITERATOR_START_LSN(i) <= max_lsn) + output_rows_num < srv_max_changed_pages)) { if (!LOG_BITMAP_ITERATOR_PAGE_CHANGED(i)) continue; diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h index 25f987cb8e1..97dd0ba4618 100644 --- a/storage/xtradb/include/btr0cur.h +++ b/storage/xtradb/include/btr0cur.h @@ -261,7 +261,7 @@ btr_cur_update_alloc_zip( FALSE=update-in-place */ mtr_t* mtr, /*!< in: mini-transaction */ trx_t* trx) /*!< in: NULL or transaction */ - __attribute__((nonnull (1, 2, 3, 6), warn_unused_result)); + __attribute__((warn_unused_result)); /*************************************************************//** Updates a record when the update causes no size changes in its fields. @return DB_SUCCESS or error number */ @@ -345,8 +345,7 @@ btr_cur_del_mark_set_clust_rec( const ulint* offsets,/*!< in: rec_get_offsets(rec) */ ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ - mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in: mtr */ /***********************************************************//** Sets a secondary index record delete mark to TRUE or FALSE. @return DB_SUCCESS, DB_LOCK_WAIT, or error number */ @@ -499,8 +498,7 @@ btr_cur_disown_inherited_fields( dict_index_t* index, /*!< in: index of the page */ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ - mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull(2,3,4,5,6))); + mtr_t* mtr); /*!< in/out: mini-transaction */ /** Operation code for btr_store_big_rec_extern_fields(). */ enum blob_op { @@ -545,7 +543,7 @@ btr_store_big_rec_extern_fields( mtr_t* btr_mtr, /*!< in: mtr containing the latches to the clustered index */ enum blob_op op) /*! in: operation code */ - __attribute__((nonnull, warn_unused_result)); + __attribute__((warn_unused_result)); /*******************************************************************//** Frees the space in an externally stored field to the file space @@ -621,8 +619,7 @@ btr_push_update_extern_fields( /*==========================*/ dtuple_t* tuple, /*!< in/out: data tuple */ const upd_t* update, /*!< in: update vector */ - mem_heap_t* heap) /*!< in: memory heap */ - __attribute__((nonnull)); + mem_heap_t* heap); /*!< in: memory heap */ /***********************************************************//** Sets a secondary index record's delete mark to the given value. This function is only used by the insert buffer merge mechanism. */ diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h index 39c0a66fb9a..bdffe402277 100644 --- a/storage/xtradb/include/btr0sea.h +++ b/storage/xtradb/include/btr0sea.h @@ -205,14 +205,14 @@ hash_table_t* btr_search_get_hash_table( /*======================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull,pure,warn_unused_result)); + __attribute__((warn_unused_result)); UNIV_INLINE rw_lock_t* btr_search_get_latch( /*=================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull,pure,warn_unused_result)); + __attribute__((warn_unused_result)); /*********************************************************************//** Returns the AHI partition number corresponding to a given index ID. */ @@ -229,8 +229,7 @@ UNIV_INLINE void btr_search_index_init( /*===============*/ - dict_index_t* index) /*!< in: index */ - __attribute__((nonnull)); + dict_index_t* index); /*!< in: index */ UNIV_INLINE void diff --git a/storage/xtradb/include/buf0buddy.ic b/storage/xtradb/include/buf0buddy.ic index d7053881caa..2b5e62e97b2 100644 --- a/storage/xtradb/include/buf0buddy.ic +++ b/storage/xtradb/include/buf0buddy.ic @@ -51,7 +51,7 @@ buf_buddy_alloc_low( buf_pool->mutex was temporarily released */ ibool have_page_hash_mutex) - __attribute__((malloc, nonnull)); + __attribute__((malloc)); /**********************************************************************//** Deallocate a block. */ diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index 23692c92c09..d584062a81f 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -274,8 +274,7 @@ buf_relocate( buf_page_t* bpage, /*!< in/out: control block being relocated; buf_page_get_state(bpage) must be BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */ - buf_page_t* dpage) /*!< in/out: destination control block */ - __attribute__((nonnull)); + buf_page_t* dpage); /*!< in/out: destination control block */ /*********************************************************************//** Gets the current size of buffer buf_pool in bytes. @return size in bytes */ diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index 3d05f40eb08..d8c8e39b1bf 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -605,7 +605,7 @@ ulint dict_index_is_clust( /*================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Check whether the index is unique. @return nonzero for unique index, zero for other indexes */ @@ -614,7 +614,7 @@ ulint dict_index_is_unique( /*=================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Check whether the index is the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -623,7 +623,7 @@ ulint dict_index_is_ibuf( /*===============*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Check whether the index is a secondary index or the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -632,7 +632,7 @@ ulint dict_index_is_sec_or_ibuf( /*======================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Gets the number of user-defined columns in a table in the dictionary @@ -643,7 +643,7 @@ ulint dict_table_get_n_user_cols( /*=======================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Gets the number of system columns in a table in the dictionary cache. @return number of system (e.g., ROW_ID) columns of a table */ @@ -662,7 +662,7 @@ ulint dict_table_get_n_cols( /*==================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth column of a table. @@ -1321,7 +1321,7 @@ ulint dict_index_is_corrupted( /*====================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -1332,7 +1332,7 @@ void dict_set_corrupted( /*===============*/ dict_index_t* index) /*!< in/out: index */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD; /**********************************************************************//** Flags an index corrupted in the data dictionary cache only. This diff --git a/storage/xtradb/include/dyn0dyn.h b/storage/xtradb/include/dyn0dyn.h index 62ed862e82c..e3517108a29 100644 --- a/storage/xtradb/include/dyn0dyn.h +++ b/storage/xtradb/include/dyn0dyn.h @@ -47,9 +47,8 @@ UNIV_INLINE dyn_array_t* dyn_array_create( /*=============*/ - dyn_array_t* arr) /*!< in/out memory buffer of + dyn_array_t* arr); /*!< in/out memory buffer of size sizeof(dyn_array_t) */ - __attribute__((nonnull)); /************************************************************//** Frees a dynamic array. */ UNIV_INLINE @@ -70,7 +69,7 @@ dyn_array_open( dyn_array_t* arr, /*!< in: dynamic array */ ulint size) /*!< in: size in bytes of the buffer; MUST be smaller than DYN_ARRAY_DATA_SIZE! */ - __attribute__((nonnull, warn_unused_result)); + __attribute__((warn_unused_result)); /*********************************************************************//** Closes the buffer returned by dyn_array_open. */ UNIV_INLINE @@ -78,8 +77,7 @@ void dyn_array_close( /*============*/ dyn_array_t* arr, /*!< in: dynamic array */ - const byte* ptr) /*!< in: end of used space */ - __attribute__((nonnull)); + const byte* ptr); /*!< in: end of used space */ /*********************************************************************//** Makes room on top of a dyn array and returns a pointer to the added element. The caller must copy the element to @@ -91,7 +89,7 @@ dyn_array_push( /*===========*/ dyn_array_t* arr, /*!< in/out: dynamic array */ ulint size) /*!< in: size in bytes of the element */ - __attribute__((nonnull, warn_unused_result)); + __attribute__((warn_unused_result)); /************************************************************//** Returns pointer to an element in dyn array. @return pointer to element */ @@ -102,7 +100,7 @@ dyn_array_get_element( const dyn_array_t* arr, /*!< in: dyn array */ ulint pos) /*!< in: position of element in bytes from array start */ - __attribute__((nonnull, warn_unused_result)); + __attribute__((warn_unused_result)); /************************************************************//** Returns the size of stored data in a dyn array. @return data size in bytes */ @@ -111,7 +109,7 @@ ulint dyn_array_get_data_size( /*====================*/ const dyn_array_t* arr) /*!< in: dyn array */ - __attribute__((nonnull, warn_unused_result, pure)); + __attribute__((warn_unused_result)); /************************************************************//** Gets the first block in a dyn array. @param arr dyn array @@ -145,7 +143,7 @@ ulint dyn_block_get_used( /*===============*/ const dyn_block_t* block) /*!< in: dyn array block */ - __attribute__((nonnull, warn_unused_result, pure)); + __attribute__((warn_unused_result)); /********************************************************************//** Gets pointer to the start of data in a dyn array block. @return pointer to data */ @@ -154,7 +152,7 @@ byte* dyn_block_get_data( /*===============*/ const dyn_block_t* block) /*!< in: dyn array block */ - __attribute__((nonnull, warn_unused_result, pure)); + __attribute__((warn_unused_result)); /********************************************************//** Pushes n bytes to a dyn array. */ UNIV_INLINE diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic index 2565a249271..137ad2b88c7 100644 --- a/storage/xtradb/include/dyn0dyn.ic +++ b/storage/xtradb/include/dyn0dyn.ic @@ -36,7 +36,7 @@ dyn_block_t* dyn_array_add_block( /*================*/ dyn_array_t* arr) /*!< in/out: dyn array */ - __attribute__((nonnull, warn_unused_result)); + __attribute__((warn_unused_result)); /********************************************************************//** Gets the number of used bytes in a dyn array block. diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h index 02d75001505..2462263dec2 100644 --- a/storage/xtradb/include/log0online.h +++ b/storage/xtradb/include/log0online.h @@ -37,19 +37,25 @@ log_online_bitmap_file_range_t; /** An iterator over changed page info */ typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t; -/*********************************************************************//** -Initializes the online log following subsytem. */ +/** Initialize the constant part of the log tracking subsystem */ +UNIV_INTERN +void +log_online_init(void); + +/** Initialize the dynamic part of the log tracking subsystem */ UNIV_INTERN void log_online_read_init(void); -/*=======================*/ -/*********************************************************************//** -Shuts down the online log following subsystem. */ +/** Shut down the dynamic part of the log tracking subsystem */ UNIV_INTERN void log_online_read_shutdown(void); -/*===========================*/ + +/** Shut down the constant part of the log tracking subsystem */ +UNIV_INTERN +void +log_online_shutdown(void); /*********************************************************************//** Reads and parses the redo log up to last checkpoint LSN to build the changed @@ -159,6 +165,8 @@ struct log_online_bitmap_file_range_struct { /** Struct for an iterator through all bits of changed pages bitmap blocks */ struct log_bitmap_iterator_struct { + ib_uint64_t max_lsn; /*!< End LSN of the + range */ ibool failed; /*!< Has the iteration stopped prematurely */ log_online_bitmap_file_range_t in_files; /*!< The bitmap files diff --git a/storage/xtradb/include/mach0data.h b/storage/xtradb/include/mach0data.h index 81c0866f367..d9a4a9170c7 100644 --- a/storage/xtradb/include/mach0data.h +++ b/storage/xtradb/include/mach0data.h @@ -51,7 +51,7 @@ ulint mach_read_from_1( /*=============*/ const byte* b) /*!< in: pointer to byte */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*******************************************************//** The following function is used to store data in two consecutive bytes. We store the most significant byte to the lower address. */ @@ -112,7 +112,7 @@ ulint mach_read_from_3( /*=============*/ const byte* b) /*!< in: pointer to 3 bytes */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*******************************************************//** The following function is used to store data in four consecutive bytes. We store the most significant byte to the lowest address. */ @@ -131,7 +131,7 @@ ulint mach_read_from_4( /*=============*/ const byte* b) /*!< in: pointer to four bytes */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*********************************************************//** Writes a ulint in a compressed form (1..5 bytes). @return stored size in bytes */ @@ -158,7 +158,7 @@ ulint mach_read_compressed( /*=================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*******************************************************//** The following function is used to store data in 6 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -177,7 +177,7 @@ ib_uint64_t mach_read_from_6( /*=============*/ const byte* b) /*!< in: pointer to 6 bytes */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*******************************************************//** The following function is used to store data in 7 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -196,7 +196,7 @@ ib_uint64_t mach_read_from_7( /*=============*/ const byte* b) /*!< in: pointer to 7 bytes */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*******************************************************//** The following function is used to store data in 8 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -241,7 +241,7 @@ ib_uint64_t mach_ull_read_compressed( /*=====================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*********************************************************//** Writes a 64-bit integer in a compressed form (1..11 bytes). @return size in bytes */ @@ -268,7 +268,7 @@ ib_uint64_t mach_ull_read_much_compressed( /*==========================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + __attribute__((warn_unused_result)); /*********************************************************//** Reads a ulint in a compressed form if the log record fully contains it. @return pointer to end of the stored field, NULL if not complete */ diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h index 031fccd300c..bb60ffbd9bb 100644 --- a/storage/xtradb/include/mtr0mtr.h +++ b/storage/xtradb/include/mtr0mtr.h @@ -205,8 +205,7 @@ UNIV_INTERN void mtr_commit( /*=======*/ - mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in/out: mini-transaction */ /**********************************************************//** Sets and returns a savepoint in mtr. @return savepoint */ @@ -311,7 +310,7 @@ mtr_memo_contains( mtr_t* mtr, /*!< in: mtr */ const void* object, /*!< in: object to search */ ulint type) /*!< in: type of object */ - __attribute__((warn_unused_result, nonnull)); + __attribute__((warn_unused_result)); /**********************************************************//** Checks if memo contains the given page. diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index 71da5ea6125..618d6f540ae 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -515,9 +515,10 @@ os_file_create_simple_no_error_handling_func( it would be enabled otherwise). */ ibool* success);/*!< out: TRUE if succeed, FALSE if error */ /****************************************************************//** -Tries to disable OS caching on an opened file descriptor. */ +Tries to disable OS caching on an opened file descriptor. +@return TRUE if operation is success and FALSE otherwise */ UNIV_INTERN -void +ibool os_file_set_nocache( /*================*/ int fd, /*!< in: file descriptor to alter */ diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h index ba1ee7a7d11..f7b9f9f06c8 100644 --- a/storage/xtradb/include/page0page.h +++ b/storage/xtradb/include/page0page.h @@ -231,8 +231,7 @@ ulint page_header_get_offs( /*=================*/ const page_t* page, /*!< in: page */ - ulint field) /*!< in: PAGE_FREE, ... */ - __attribute__((nonnull, pure)); + ulint field); /*!< in: PAGE_FREE, ... */ /*************************************************************//** Returns the pointer stored in the given header field, or NULL. */ @@ -792,8 +791,7 @@ page_copy_rec_list_end( buf_block_t* block, /*!< in: index page containing rec */ rec_t* rec, /*!< in: record on page */ dict_index_t* index, /*!< in: record descriptor */ - mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** Copies records from page to new_page, up to the given record, NOT including that record. Infimum and supremum records are not copied. @@ -808,8 +806,7 @@ page_copy_rec_list_start( buf_block_t* block, /*!< in: index page containing rec */ rec_t* rec, /*!< in: record on page */ dict_index_t* index, /*!< in: record descriptor */ - mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** Deletes records from a page from a given record onward, including that record. The infimum and supremum records are not deleted. */ @@ -852,8 +849,7 @@ page_move_rec_list_end( buf_block_t* block, /*!< in: index page from where to move */ rec_t* split_rec, /*!< in: first record to move */ dict_index_t* index, /*!< in: record descriptor */ - mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull(1, 2, 4, 5))); + mtr_t* mtr); /*!< in: mtr */ /*************************************************************//** Moves record list start to another page. Moved records do not include split_rec. @@ -877,8 +873,7 @@ page_dir_split_slot( page_t* page, /*!< in: index page */ page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be written, or NULL */ - ulint slot_no)/*!< in: the directory slot */ - __attribute__((nonnull(1))); + ulint slot_no);/*!< in: the directory slot */ /*************************************************************//** Tries to balance the given directory slot with too few records with the upper neighbor, so that there are at least the minimum number @@ -890,8 +885,7 @@ page_dir_balance_slot( /*==================*/ page_t* page, /*!< in/out: index page */ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ - ulint slot_no)/*!< in: the directory slot */ - __attribute__((nonnull(1))); + ulint slot_no);/*!< in: the directory slot */ /**********************************************************//** Parses a log record of a record list end or start deletion. @return end of log record or NULL */ diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h index a33407e78bc..abd62ab99a5 100644 --- a/storage/xtradb/include/page0zip.h +++ b/storage/xtradb/include/page0zip.h @@ -402,8 +402,7 @@ page_zip_reorganize( out: data, n_blobs, m_start, m_end, m_nonempty */ dict_index_t* index, /*!< in: index of the B-tree node */ - mtr_t* mtr) /*!< in: mini-transaction */ - __attribute__((nonnull)); + mtr_t* mtr); /*!< in: mini-transaction */ #ifndef UNIV_HOTBACKUP /**********************************************************************//** Copy the records of a page byte for byte. Do not copy the page header @@ -436,7 +435,7 @@ page_zip_parse_compress( byte* end_ptr,/*!< in: buffer end */ page_t* page, /*!< out: uncompressed page */ page_zip_des_t* page_zip)/*!< out: compressed page */ - __attribute__((nonnull(1,2))); + __attribute__((warn_unused_result)); /**********************************************************************//** Calculate the compressed page checksum. diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h index 7e76b4f40cb..239a02a83f8 100644 --- a/storage/xtradb/include/rem0rec.h +++ b/storage/xtradb/include/rem0rec.h @@ -626,8 +626,7 @@ rec_copy( /*=====*/ void* buf, /*!< in: buffer */ const rec_t* rec, /*!< in: physical record */ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ #ifndef UNIV_HOTBACKUP /**********************************************************//** Determines the size of a data tuple prefix in a temporary file. diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h index 16c069d5ae8..e23a71374c2 100644 --- a/storage/xtradb/include/row0upd.h +++ b/storage/xtradb/include/row0upd.h @@ -232,9 +232,8 @@ row_upd_index_replace_new_col_vals_index_pos( /*!< in: if TRUE, limit the replacement to ordering fields of index; note that this does not work for non-clustered indexes. */ - mem_heap_t* heap) /*!< in: memory heap for allocating and + mem_heap_t* heap); /*!< in: memory heap for allocating and copying the new values */ - __attribute__((nonnull)); /***********************************************************//** Replaces the new column values stored in the update vector to the index entry given. */ @@ -295,7 +294,7 @@ row_upd_changes_ord_field_binary_func( compile time */ const row_ext_t*ext) /*!< NULL, or prefixes of the externally stored columns in the old row */ - __attribute__((nonnull(1,2), warn_unused_result)); + __attribute__((warn_unused_result)); #ifdef UNIV_DEBUG # define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \ row_upd_changes_ord_field_binary_func(index,update,thr,row,ext) diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index 7be135f9778..5d0f85f1c18 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -90,7 +90,7 @@ trx_t* trx_create( /*=======*/ sess_t* sess) /*!< in: session */ - __attribute__((nonnull)); + __attribute__((warn_unused_result)); /********************************************************************//** Creates a transaction object for MySQL. @return own: transaction object */ @@ -119,7 +119,7 @@ void trx_free_prepared( /*==============*/ trx_t* trx) /*!< in, own: trx object */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD; /********************************************************************//** Frees a transaction object for MySQL. */ UNIV_INTERN diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 7c5fdff1533..3ecfe8d26e1 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 38.3 +#define PERCONA_INNODB_VERSION 38.8 #endif -#define INNODB_VERSION_STR "5.5.52-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) +#define INNODB_VERSION_STR "5.5.55-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) #define REFMAN "http://dev.mysql.com/doc/refman/" \ IB_TO_STR(MYSQL_MAJOR_VERSION) "." \ diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c index fa2c8b882bf..45739dffa5d 100644 --- a/storage/xtradb/log/log0online.c +++ b/storage/xtradb/log/log0online.c @@ -84,12 +84,14 @@ struct log_bitmap_struct { both the correct type and the tree does not mind its overwrite during rbt_next() tree traversal. */ - mutex_t mutex; /*!< mutex protecting all the fields.*/ }; /* The log parsing and bitmap output struct instance */ static struct log_bitmap_struct* log_bmp_sys; +/* Mutex protecting log_bmp_sys */ +static mutex_t log_bmp_sys_mutex; + /** File name stem for bitmap files. */ static const char* bmp_file_name_stem = "ib_modified_log_"; @@ -188,7 +190,7 @@ log_online_set_page_bit( byte search_page[MODIFIED_PAGE_BLOCK_SIZE]; byte *page_ptr; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); ut_a(space != ULINT_UNDEFINED); ut_a(page_no != ULINT_UNDEFINED); @@ -339,7 +341,7 @@ log_online_read_last_tracked_lsn(void) ib_uint64_t result; ib_uint64_t read_offset = log_bmp_sys->out.offset; - while (!checksum_ok && read_offset > 0 && !is_last_page) + while ((!checksum_ok || !is_last_page) && read_offset > 0) { read_offset -= MODIFIED_PAGE_BLOCK_SIZE; log_bmp_sys->out.offset = read_offset; @@ -609,12 +611,19 @@ log_online_is_bitmap_file( && (!strcmp(stem, bmp_file_name_stem))); } -/*********************************************************************//** -Initialize the online log following subsytem. */ +/** Initialize the constant part of the log tracking subsystem */ +UNIV_INTERN +void +log_online_init(void) +{ + mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys_mutex, + SYNC_LOG_ONLINE); +} + +/** Initialize the dynamic part of the log tracking subsystem */ UNIV_INTERN void log_online_read_init(void) -/*======================*/ { ibool success; ib_uint64_t tracking_start_lsn @@ -635,9 +644,6 @@ log_online_read_init(void) log_bmp_sys->read_buf = ut_align(log_bmp_sys->read_buf_ptr, OS_FILE_LOG_BLOCK_SIZE); - mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys->mutex, - SYNC_LOG_ONLINE); - /* Initialize bitmap file directory from srv_data_home and add a path separator if needed. */ srv_data_home_len = strlen(srv_data_home); @@ -720,6 +726,7 @@ log_online_read_init(void) ulint size_high; ib_uint64_t last_tracked_lsn; ib_uint64_t file_start_lsn; + ibool need_rotate; success = os_file_get_size(log_bmp_sys->out.file, &size_low, &size_high); @@ -742,7 +749,11 @@ log_online_read_init(void) } last_tracked_lsn = log_online_read_last_tracked_lsn(); + /* Do not rotate if we truncated the file to zero length - we + can just start writing there */ + need_rotate = (last_tracked_lsn != 0); if (!last_tracked_lsn) { + last_tracked_lsn = last_file_start_lsn; } @@ -754,7 +765,10 @@ log_online_read_init(void) } else { file_start_lsn = tracking_start_lsn; } - if (!log_online_rotate_bitmap_file(file_start_lsn)) { + + if (need_rotate + && !log_online_rotate_bitmap_file(file_start_lsn)) { + exit(1); } @@ -782,14 +796,18 @@ log_online_read_init(void) log_set_tracked_lsn(tracking_start_lsn); } -/*********************************************************************//** -Shut down the online log following subsystem. */ +/** Shut down the dynamic part of the log tracking subsystem */ UNIV_INTERN void log_online_read_shutdown(void) -/*==========================*/ { - ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list; + ib_rbt_node_t *free_list_node; + + mutex_enter(&log_bmp_sys_mutex); + + srv_track_changed_pages = FALSE; + + free_list_node = log_bmp_sys->page_free_list; if (log_bmp_sys->out.file != os_file_invalid) { os_file_close(log_bmp_sys->out.file); @@ -804,10 +822,21 @@ log_online_read_shutdown(void) free_list_node = next; } - mutex_free(&log_bmp_sys->mutex); - ut_free(log_bmp_sys->read_buf_ptr); ut_free(log_bmp_sys); + log_bmp_sys = NULL; + + srv_redo_log_thread_started = FALSE; + + mutex_exit(&log_bmp_sys_mutex); +} + +/** Shut down the constant part of the log tracking subsystem */ +UNIV_INTERN +void +log_online_shutdown(void) +{ + mutex_free(&log_bmp_sys_mutex); } /*********************************************************************//** @@ -858,7 +887,7 @@ log_online_parse_redo_log(void) ulint len = 0; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); while (ptr != end && log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) { @@ -950,7 +979,7 @@ log_online_add_to_parse_buf( ulint actual_data_len = (end_offset >= start_offset) ? end_offset - start_offset : 0; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); ut_memcpy(log_bmp_sys->parse_buf_end, log_block + start_offset, actual_data_len); @@ -976,7 +1005,7 @@ log_online_parse_redo_log_block( { ulint block_data_len; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); block_data_len = log_block_get_data_len(log_block); @@ -1004,7 +1033,7 @@ log_online_follow_log_seg( byte* log_block_end = log_bmp_sys->read_buf + (block_end_lsn - block_start_lsn); - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); mutex_enter(&log_sys->mutex); log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf, @@ -1068,7 +1097,7 @@ log_online_follow_log_group( ib_uint64_t block_start_lsn = contiguous_lsn; ib_uint64_t block_end_lsn; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); log_bmp_sys->next_parse_lsn = log_bmp_sys->start_lsn; log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf; @@ -1108,10 +1137,35 @@ log_online_write_bitmap_page( { ibool success; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); /* Simulate a write error */ - DBUG_EXECUTE_IF("bitmap_page_write_error", return FALSE;); + DBUG_EXECUTE_IF("bitmap_page_write_error", + { + ulint space_id + = mach_read_from_4(block + + MODIFIED_PAGE_SPACE_ID); + if (space_id > 0) { + fprintf(stderr, "InnoDB: Error: " + "simulating bitmap write " + "error in " + "log_online_write_bitmap_page " + "for space ID %lu\n", + space_id); + return FALSE; + } + }); + + /* A crash injection site that ensures last checkpoint LSN > last + tracked LSN, so that LSN tracking for this interval is tested. */ + DBUG_EXECUTE_IF("crash_before_bitmap_write", + { + ulint space_id + = mach_read_from_4(block + + MODIFIED_PAGE_SPACE_ID); + if (space_id > 0) + DBUG_SUICIDE(); + }); success = os_file_write(log_bmp_sys->out.name, log_bmp_sys->out.file, block, @@ -1161,7 +1215,7 @@ log_online_write_bitmap(void) const ib_rbt_node_t *last_bmp_tree_node; ibool success = TRUE; - ut_ad(mutex_own(&log_bmp_sys->mutex)); + ut_ad(mutex_own(&log_bmp_sys_mutex)); if (log_bmp_sys->out.offset >= srv_max_bitmap_file_size) { if (!log_online_rotate_bitmap_file(log_bmp_sys->start_lsn)) { @@ -1204,7 +1258,11 @@ log_online_write_bitmap(void) rbt_next(log_bmp_sys->modified_pages, bmp_tree_node); DBUG_EXECUTE_IF("bitmap_page_2_write_error", - DBUG_SET("+d,bitmap_page_write_error");); + if (bmp_tree_node) + { + DBUG_SET("+d,bitmap_page_write_error"); + DBUG_SET("-d,bitmap_page_2_write_error"); + }); } rbt_reset(log_bmp_sys->modified_pages); @@ -1225,11 +1283,16 @@ log_online_follow_redo_log(void) log_group_t* group; ibool result; - mutex_enter(&log_bmp_sys->mutex); + if (!srv_track_changed_pages) + return TRUE; + + DEBUG_SYNC_C("log_online_follow_redo_log"); + + mutex_enter(&log_bmp_sys_mutex); if (!srv_track_changed_pages) { - mutex_exit(&log_bmp_sys->mutex); - return FALSE; + mutex_exit(&log_bmp_sys_mutex); + return TRUE; } /* Grab the LSN of the last checkpoint, we will parse up to it */ @@ -1238,7 +1301,7 @@ log_online_follow_redo_log(void) mutex_exit(&(log_sys->mutex)); if (log_bmp_sys->end_lsn == log_bmp_sys->start_lsn) { - mutex_exit(&log_bmp_sys->mutex); + mutex_exit(&log_bmp_sys_mutex); return TRUE; } @@ -1253,15 +1316,11 @@ log_online_follow_redo_log(void) group = UT_LIST_GET_NEXT(log_groups, group); } - /* A crash injection site that ensures last checkpoint LSN > last - tracked LSN, so that LSN tracking for this interval is tested. */ - DBUG_EXECUTE_IF("crash_before_bitmap_write", DBUG_SUICIDE();); - result = log_online_write_bitmap(); log_bmp_sys->start_lsn = log_bmp_sys->end_lsn; log_set_tracked_lsn(log_bmp_sys->start_lsn); - mutex_exit(&log_bmp_sys->mutex); + mutex_exit(&log_bmp_sys_mutex); return result; } @@ -1608,6 +1667,8 @@ log_online_bitmap_iterator_init( { ut_a(i); + i->max_lsn = max_lsn; + if (UNIV_UNLIKELY(min_lsn > max_lsn)) { /* Empty range */ @@ -1716,6 +1777,9 @@ log_online_bitmap_iterator_next( return TRUE; } + if (i->end_lsn >= i->max_lsn && i->last_page_in_run) + return FALSE; + while (!checksum_ok) { while (i->in.size < MODIFIED_PAGE_BLOCK_SIZE @@ -1808,6 +1872,7 @@ log_online_purge_changed_page_bitmaps( log_online_bitmap_file_range_t bitmap_files; size_t i; ibool result = FALSE; + ibool log_bmp_sys_inited = FALSE; if (lsn == 0) { lsn = IB_ULONGLONG_MAX; @@ -1816,13 +1881,18 @@ log_online_purge_changed_page_bitmaps( if (srv_redo_log_thread_started) { /* User requests might happen with both enabled and disabled tracking */ - mutex_enter(&log_bmp_sys->mutex); + log_bmp_sys_inited = TRUE; + mutex_enter(&log_bmp_sys_mutex); + if (!srv_redo_log_thread_started) { + log_bmp_sys_inited = FALSE; + mutex_exit(&log_bmp_sys_mutex); + } } if (!log_online_setup_bitmap_file_range(&bitmap_files, 0, IB_ULONGLONG_MAX)) { - if (srv_redo_log_thread_started) { - mutex_exit(&log_bmp_sys->mutex); + if (log_bmp_sys_inited) { + mutex_exit(&log_bmp_sys_mutex); } return TRUE; } @@ -1858,7 +1928,7 @@ log_online_purge_changed_page_bitmaps( } } - if (srv_redo_log_thread_started) { + if (log_bmp_sys_inited) { if (lsn > log_bmp_sys->end_lsn) { ib_uint64_t new_file_lsn; if (lsn == IB_ULONGLONG_MAX) { @@ -1874,7 +1944,7 @@ log_online_purge_changed_page_bitmaps( } } - mutex_exit(&log_bmp_sys->mutex); + mutex_exit(&log_bmp_sys_mutex); } free(bitmap_files.files); diff --git a/storage/xtradb/mach/mach0data.c b/storage/xtradb/mach/mach0data.c index 00378f036c9..9669516244d 100644 --- a/storage/xtradb/mach/mach0data.c +++ b/storage/xtradb/mach/mach0data.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -55,7 +55,6 @@ mach_parse_compressed( if (flag < 0x80UL) { *val = flag; return(ptr + 1); - } /* Workaround GCC bug @@ -64,7 +63,11 @@ mach_parse_compressed( function, causing and out-of-bounds read if we are reading a short integer close to the end of buffer. */ #if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__) - asm volatile("": : :"memory"); +#define DEPLOY_FENCE +#endif + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); #endif if (flag < 0xC0UL) { @@ -75,8 +78,13 @@ mach_parse_compressed( *val = mach_read_from_2(ptr) & 0x7FFFUL; return(ptr + 2); + } - } else if (flag < 0xE0UL) { +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + + if (flag < 0xE0UL) { if (end_ptr < ptr + 3) { return(NULL); } @@ -84,7 +92,13 @@ mach_parse_compressed( *val = mach_read_from_3(ptr) & 0x3FFFFFUL; return(ptr + 3); - } else if (flag < 0xF0UL) { + } + +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif + + if (flag < 0xF0UL) { if (end_ptr < ptr + 4) { return(NULL); } @@ -92,14 +106,20 @@ mach_parse_compressed( *val = mach_read_from_4(ptr) & 0x1FFFFFFFUL; return(ptr + 4); - } else { - ut_ad(flag == 0xF0UL); + } - if (end_ptr < ptr + 5) { - return(NULL); - } +#ifdef DEPLOY_FENCE + __atomic_thread_fence(__ATOMIC_ACQUIRE); +#endif - *val = mach_read_from_4(ptr + 1); - return(ptr + 5); +#undef DEPLOY_FENCE + + ut_ad(flag == 0xF0UL); + + if (end_ptr < ptr + 5) { + return(NULL); } + + *val = mach_read_from_4(ptr + 1); + return(ptr + 5); } diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c index 396a0b43094..8e5cc9a6ba6 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -1058,50 +1058,15 @@ next_file: char* full_path; int ret; struct stat statinfo; -#ifdef HAVE_READDIR_R - char dirent_buf[sizeof(struct dirent) - + _POSIX_PATH_MAX + 100]; - /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as - the max file name len; but in most standards, the - length is NAME_MAX; we add 100 to be even safer */ -#endif next_file: -#ifdef HAVE_READDIR_R - ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent); - - if (ret != 0 -#ifdef UNIV_AIX - /* On AIX, only if we got non-NULL 'ent' (result) value and - a non-zero 'ret' (return) value, it indicates a failed - readdir_r() call. An NULL 'ent' with an non-zero 'ret' - would indicate the "end of the directory" is reached. */ - && ent != NULL -#endif - ) { - fprintf(stderr, - "InnoDB: cannot read directory %s, error %lu\n", - dirname, (ulong)ret); - - return(-1); - } - - if (ent == NULL) { - /* End of directory */ - - return(1); - } - - ut_a(strlen(ent->d_name) < _POSIX_PATH_MAX + 100 - 1); -#else ent = readdir(dir); if (ent == NULL) { return(1); } -#endif ut_a(strlen(ent->d_name) < OS_FILE_MAX_PATH); if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { @@ -1484,9 +1449,10 @@ os_file_create_simple_no_error_handling_func( } /****************************************************************//** -Tries to disable OS caching on an opened file descriptor. */ +Tries to disable OS caching on an opened file descriptor. +@return TRUE if operation is success and FALSE otherwise */ UNIV_INTERN -void +ibool os_file_set_nocache( /*================*/ int fd /*!< in: file descriptor to alter */ @@ -1507,6 +1473,7 @@ os_file_set_nocache( " InnoDB: Failed to set DIRECTIO_ON " "on file %s: %s: %s, continuing anyway\n", file_name, operation_name, strerror(errno_save)); + return FALSE; } #elif defined(O_DIRECT) if (fcntl(fd, F_SETFL, O_DIRECT) == -1) { @@ -1524,8 +1491,10 @@ os_file_set_nocache( "'Invalid argument' on Linux on tmpfs, " "see MySQL Bug#26662\n"); } + return FALSE; } #endif + return TRUE; } @@ -1824,7 +1793,11 @@ try_again: /* ALL_O_DIRECT: O_DIRECT also for transaction log file */ if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) { - os_file_set_nocache(file, name, mode_str); + /* Do fsync() on log files when setting O_DIRECT fails. + See log_io_complete() */ + if (!os_file_set_nocache(file, name, mode_str)) { + srv_unix_file_flush_method = SRV_UNIX_O_DIRECT; + } } #ifdef USE_FILE_LOCK diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c index cc181c7d333..232033a3f23 100644 --- a/storage/xtradb/rem/rem0rec.c +++ b/storage/xtradb/rem/rem0rec.c @@ -777,7 +777,7 @@ rec_get_nth_field_offs_old( /**********************************************************//** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. @return total size */ -UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2))) +UNIV_INLINE __attribute__((warn_unused_result)) ulint rec_get_converted_size_comp_prefix_low( /*===================================*/ diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c index 7409d5a5e1a..00a7decdce6 100644 --- a/storage/xtradb/row/row0merge.c +++ b/storage/xtradb/row/row0merge.c @@ -802,7 +802,7 @@ row_merge_write( /********************************************************************//** Read a merge record. @return pointer to next record, or NULL on I/O error or end of list */ -static __attribute__((nonnull)) +static __attribute__((warn_unused_result)) const byte* row_merge_read_rec( /*===============*/ @@ -1162,7 +1162,7 @@ row_merge_cmp( Reads clustered index of the table and create temporary files containing the index entries for the indexes to be built. @return DB_SUCCESS or error */ -static __attribute__((nonnull)) +static __attribute__((warn_unused_result)) ulint row_merge_read_clustered_index( /*===========================*/ diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c index 8ada79a2bbc..4186da884b6 100644 --- a/storage/xtradb/row/row0purge.c +++ b/storage/xtradb/row/row0purge.c @@ -742,7 +742,7 @@ err_exit: Fetches an undo log record and does the purge for the recorded operation. If none left, or the current purge completed, returns the control to the parent node, which is always a query thread node. */ -static __attribute__((nonnull)) +static void row_purge( /*======*/ diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c index 65bea0d0a6e..9e863765dc0 100644 --- a/storage/xtradb/srv/srv0srv.c +++ b/storage/xtradb/srv/srv0srv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved. @@ -3373,10 +3373,8 @@ srv_redo_log_follow_thread( } while (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE); - srv_track_changed_pages = FALSE; log_online_read_shutdown(); os_event_set(srv_redo_log_thread_finished_event); - srv_redo_log_thread_started = FALSE; /* Defensive, not required */ my_thread_end(); os_thread_exit(NULL); @@ -3555,6 +3553,7 @@ srv_master_thread( ib_uint64_t oldest_lsn; ib_time_t last_print_time; + my_thread_init(); #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Master thread starts, id %lu\n", os_thread_pf(os_thread_get_curr_id())); @@ -4263,6 +4262,7 @@ suspend_thread: os_event_wait(slot->event); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + my_thread_end(); os_thread_exit(NULL); } @@ -4288,6 +4288,7 @@ srv_purge_thread( ulint next_itr_time; ib_int64_t sig_count; + my_thread_init(); ut_a(srv_n_purge_threads == 1); #ifdef UNIV_PFS_THREAD @@ -4396,6 +4397,8 @@ srv_purge_thread( os_thread_pf(os_thread_get_curr_id())); #endif /* UNIV_DEBUG_THREAD_CREATION */ + my_thread_end(); + /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ os_thread_exit(NULL); diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c index e946472e6ee..d8710eab82c 100644 --- a/storage/xtradb/srv/srv0start.c +++ b/storage/xtradb/srv/srv0start.c @@ -1657,6 +1657,7 @@ innobase_start_or_create_for_mysql(void) fsp_init(); log_init(); + log_online_init(); lock_sys_create(srv_lock_table_size); @@ -2510,6 +2511,7 @@ innobase_shutdown_for_mysql(void) btr_search_disable(); ibuf_close(); + log_online_shutdown(); log_shutdown(); trx_sys_file_format_close(); trx_sys_close(); diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c index 2eeed9378cc..f2a3a2cc4c7 100644 --- a/storage/xtradb/trx/trx0roll.c +++ b/storage/xtradb/trx/trx0roll.c @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 2017, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -625,12 +626,15 @@ trx_rollback_or_clean_all_recovered( /*!< in: a dummy parameter required by os_thread_create */ { + my_thread_init(); + #ifdef UNIV_PFS_THREAD pfs_register_thread(trx_rollback_clean_thread_key); #endif /* UNIV_PFS_THREAD */ trx_rollback_or_clean_recovered(TRUE); + my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ |