diff options
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 11 | ||||
-rw-r--r-- | storage/innobase/include/os0proc.h | 17 | ||||
-rw-r--r-- | storage/innobase/include/ut0new.h | 52 | ||||
-rw-r--r-- | storage/innobase/os/os0proc.cc | 146 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 17 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 5 |
6 files changed, 40 insertions, 208 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 0721ce2508b..c3cff2e561d 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1380,6 +1380,8 @@ inline bool buf_pool_t::chunk_t::create(size_t bytes) /* Align a pointer to the first frame. Note that when opt_large_page_size is smaller than srv_page_size, + (with max srv_page_size at 64k don't think any hardware + makes this true), we may allocate one fewer block than requested. When it is bigger, we may allocate more blocks than requested. */ static_assert(sizeof(byte*) == sizeof(ulint), "pointer size"); @@ -1526,8 +1528,7 @@ bool buf_pool_t::create() for (auto i= chunk->size; i--; block++) buf_block_free_mutexes(block); - allocator.deallocate_large_dodump(chunk->mem, &chunk->mem_pfx, - chunk->mem_size()); + allocator.deallocate_large_dodump(chunk->mem, &chunk->mem_pfx); } ut_free(chunks); chunks= nullptr; @@ -1653,8 +1654,7 @@ void buf_pool_t::close() for (auto i= chunk->size; i--; block++) buf_block_free_mutexes(block); - allocator.deallocate_large_dodump(chunk->mem, &chunk->mem_pfx, - chunk->mem_size()); + allocator.deallocate_large_dodump(chunk->mem, &chunk->mem_pfx); } for (ulint i= BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; ++i) @@ -2279,8 +2279,7 @@ withdraw_retry: } allocator.deallocate_large_dodump( - chunk->mem, &chunk->mem_pfx, - chunk->mem_size()); + chunk->mem, &chunk->mem_pfx); sum_freed += chunk->size; ++chunk; } diff --git a/storage/innobase/include/os0proc.h b/storage/innobase/include/os0proc.h index d8952a56cc9..2a507e013fe 100644 --- a/storage/innobase/include/os0proc.h +++ b/storage/innobase/include/os0proc.h @@ -39,7 +39,7 @@ typedef void* os_process_t; typedef unsigned long int os_process_id_t; /** The total amount of memory currently allocated from the operating -system with os_mem_alloc_large(). */ +system with allocate_large(). */ extern Atomic_counter<ulint> os_total_large_mem_allocated; /** Converts the current process id to a number. @@ -47,19 +47,4 @@ extern Atomic_counter<ulint> os_total_large_mem_allocated; ulint os_proc_get_number(void); -/** Allocates large pages memory. -@param[in,out] n Number of bytes to allocate -@return allocated memory */ -void* -os_mem_alloc_large( - ulint* n); - -/** Frees large pages memory. -@param[in] ptr pointer returned by os_mem_alloc_large() -@param[in] size size returned by os_mem_alloc_large() */ -void -os_mem_free_large( - void *ptr, - ulint size); - #endif diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h index e4ef9712e0f..c35808a56e2 100644 --- a/storage/innobase/include/ut0new.h +++ b/storage/innobase/include/ut0new.h @@ -128,14 +128,16 @@ InnoDB: #include <stdlib.h> /* malloc() */ #include <string.h> /* strlen(), strrchr(), strncmp() */ +#include <my_sys.h> /* my_large_free/malloc() */ + #include "my_global.h" /* needed for headers from mysql/psi/ */ #include "mysql/psi/mysql_memory.h" /* PSI_MEMORY_CALL() */ #include "mysql/psi/psi_memory.h" /* PSI_memory_key, PSI_memory_info */ -#include "os0proc.h" /* os_mem_alloc_large() */ #include "os0thread.h" /* os_thread_sleep() */ +#include "os0proc.h" /* os_total_large_mem_allocated */ #include "ut0ut.h" /* ut_strcmp_functor, ut_basename_noext() */ #define OUT_OF_MEMORY_MSG \ @@ -622,7 +624,7 @@ public: ulint n_bytes = n_elements * sizeof(T); pointer ptr = reinterpret_cast<pointer>( - os_mem_alloc_large(&n_bytes)); + my_large_malloc(&n_bytes, MYF(0))); if (ptr == NULL) { return NULL; @@ -637,6 +639,8 @@ public: pfx->m_size = n_bytes; } + os_total_large_mem_allocated += n_bytes; + return(ptr); } @@ -655,40 +659,26 @@ public: void deallocate_large( pointer ptr, - const ut_new_pfx_t* -#ifdef UNIV_PFS_MEMORY - pfx -#endif - , - size_t size) + const ut_new_pfx_t* pfx) { + size_t size = pfx->m_size; #ifdef UNIV_PFS_MEMORY if (pfx) { deallocate_trace(pfx); } #endif /* UNIV_PFS_MEMORY */ + os_total_large_mem_allocated -= size; - os_mem_free_large(ptr, size); + my_large_free(ptr, size); } void deallocate_large_dodump( pointer ptr, - const ut_new_pfx_t* -#ifdef UNIV_PFS_MEMORY - pfx -#endif - , - size_t size) + const ut_new_pfx_t* pfx) { - ut_dodump(ptr, size); - deallocate_large(ptr, -#ifdef UNIV_PFS_MEMORY - pfx, -#else - NULL, -#endif - size); + ut_dodump(ptr, pfx->m_size); + deallocate_large(ptr, pfx); } #ifdef UNIV_PFS_MEMORY @@ -941,9 +931,6 @@ ut_delete_array( #define ut_free(ptr) ut_allocator<byte>(PSI_NOT_INSTRUMENTED).deallocate( \ reinterpret_cast<byte*>(ptr)) -#define ut_free_dodump(ptr, size) ut_allocator<byte>(PSI_NOT_INSTRUMENTED).deallocate_large_dodump( \ - reinterpret_cast<byte*>(ptr), NULL, size) - #else /* UNIV_PFS_MEMORY */ /* Fallbacks when memory tracing is disabled at compile time. */ @@ -968,9 +955,13 @@ ut_delete_array( static inline void *ut_malloc_dontdump(size_t n_bytes, ...) { - void *ptr = os_mem_alloc_large(&n_bytes); + void *ptr = my_large_malloc(&n_bytes, MYF(0)); ut_dontdump(ptr, n_bytes, true); + + if (ptr) { + os_total_large_mem_allocated += n_bytes; + } return ptr; } @@ -982,12 +973,13 @@ static inline void *ut_malloc_dontdump(size_t n_bytes, ...) #define ut_free(ptr) ::free(ptr) +#endif /* UNIV_PFS_MEMORY */ + static inline void ut_free_dodump(void *ptr, size_t size) { ut_dodump(ptr, size); - os_mem_free_large(ptr, size); + os_total_large_mem_allocated -= size; + my_large_free(ptr, size); } -#endif /* UNIV_PFS_MEMORY */ - #endif /* ut0new_h */ diff --git a/storage/innobase/os/os0proc.cc b/storage/innobase/os/os0proc.cc index 32067297a24..8cea535ff2a 100644 --- a/storage/innobase/os/os0proc.cc +++ b/storage/innobase/os/os0proc.cc @@ -26,17 +26,6 @@ Created 9/30/1995 Heikki Tuuri *******************************************************/ #include "univ.i" -#ifdef HAVE_LINUX_LARGE_PAGES -# include "mysqld.h" -#endif - -/* FreeBSD for example has only MAP_ANON, Linux has MAP_ANONYMOUS and -MAP_ANON but MAP_ANON is marked as deprecated */ -#if defined(MAP_ANONYMOUS) -#define OS_MAP_ANON MAP_ANONYMOUS -#elif defined(MAP_ANON) -#define OS_MAP_ANON MAP_ANON -#endif /** The total amount of memory currently allocated from the operating system with os_mem_alloc_large(). */ @@ -54,138 +43,3 @@ os_proc_get_number(void) return(static_cast<ulint>(getpid())); #endif } - -/** Allocates large pages memory. -@param[in,out] n Number of bytes to allocate -@return allocated memory */ -void* -os_mem_alloc_large( - ulint* n) -{ - void* ptr; - ulint size; -#ifdef HAVE_LINUX_LARGE_PAGES - int shmid; - struct shmid_ds buf; - - if (!my_use_large_pages || !opt_large_page_size) { - goto skip; - } - - /* Align block size to opt_large_page_size */ - ut_ad(ut_is_2pow(opt_large_page_size)); - size = ut_2pow_round(*n + opt_large_page_size - 1, - ulint(opt_large_page_size)); - - shmid = shmget(IPC_PRIVATE, (size_t) size, SHM_HUGETLB | SHM_R | SHM_W); - if (shmid < 0) { - ib::warn() << "Failed to allocate " << size - << " bytes. errno " << errno; - ptr = NULL; - } else { - ptr = shmat(shmid, NULL, 0); - if (ptr == (void*)-1) { - ib::warn() << "Failed to attach shared memory segment," - " errno " << errno; - ptr = NULL; - } - - /* Remove the shared memory segment so that it will be - automatically freed after memory is detached or - process exits */ - shmctl(shmid, IPC_RMID, &buf); - } - - if (ptr) { - *n = size; - os_total_large_mem_allocated += size; - UNIV_MEM_ALLOC(ptr, size); - return(ptr); - } - - ib::warn() << "Using conventional memory pool"; -skip: -#endif /* HAVE_LINUX_LARGE_PAGES */ - -#ifdef _WIN32 - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - - /* Align block size to system page size */ - ut_ad(ut_is_2pow(system_info.dwPageSize)); - size = *n = ut_2pow_round<ulint>(*n + (system_info.dwPageSize - 1), - system_info.dwPageSize); - ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, - PAGE_READWRITE); - if (!ptr) { - ib::info() << "VirtualAlloc(" << size << " bytes) failed;" - " Windows error " << GetLastError(); - } else { - os_total_large_mem_allocated += size; - UNIV_MEM_ALLOC(ptr, size); - } -#else - size = getpagesize(); - /* Align block size to system page size */ - ut_ad(ut_is_2pow(size)); - size = *n = ut_2pow_round(*n + (size - 1), size); - ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | OS_MAP_ANON, -1, 0); - if (UNIV_UNLIKELY(ptr == (void*) -1)) { - ib::error() << "mmap(" << size << " bytes) failed;" - " errno " << errno; - ptr = NULL; - } else { - os_total_large_mem_allocated += size; - UNIV_MEM_ALLOC(ptr, size); - } -#endif - return(ptr); -} - -/** Frees large pages memory. -@param[in] ptr pointer returned by os_mem_alloc_large() -@param[in] size size returned by os_mem_alloc_large() */ -void -os_mem_free_large( - void *ptr, - ulint size) -{ - ut_a(os_total_large_mem_allocated >= size); - - // We could have manually poisoned that memory for ASAN. - // And we must unpoison it by ourself as specified in documentation - // for __asan_poison_memory_region() in sanitizer/asan_interface.h - // munmap() doesn't do it for us automatically. - UNIV_MEM_ALLOC(ptr, size); - -#ifdef HAVE_LINUX_LARGE_PAGES - if (my_use_large_pages && opt_large_page_size && !shmdt(ptr)) { - os_total_large_mem_allocated -= size; - return; - } -#endif /* HAVE_LINUX_LARGE_PAGES */ -#ifdef _WIN32 - /* When RELEASE memory, the size parameter must be 0. - Do not use MEM_RELEASE with MEM_DECOMMIT. */ - if (!VirtualFree(ptr, 0, MEM_RELEASE)) { - ib::error() << "VirtualFree(" << ptr << ", " << size - << ") failed; Windows error " << GetLastError(); - } else { - os_total_large_mem_allocated -= size; - } -#elif !defined OS_MAP_ANON - ut_free(ptr); -#else -# if defined(UNIV_SOLARIS) - if (munmap(static_cast<caddr_t>(ptr), size)) { -# else - if (munmap(ptr, size)) { -# endif /* UNIV_SOLARIS */ - ib::error() << "munmap(" << ptr << ", " << size << ") failed;" - " errno " << errno; - } else { - os_total_large_mem_allocated -= size; - } -#endif -} diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index f7e9cb18e5e..693e81e4341 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -211,11 +211,13 @@ struct row_log_t { row_log_buf_t tail; /*!< writer context; protected by mutex and index->lock S-latch, or by index->lock X-latch only */ + size_t crypt_tail_size; /*!< size of crypt_tail_size*/ byte* crypt_tail; /*!< writer context; temporary buffer used in encryption, decryption or NULL*/ row_log_buf_t head; /*!< reader context; protected by MDL only; modifiable by row_log_apply_ops() */ + size_t crypt_head_size; /*!< size of crypt_tail_size*/ byte* crypt_head; /*!< reader context; temporary buffer used in encryption, decryption or NULL */ @@ -314,8 +316,7 @@ row_log_block_free( DBUG_ENTER("row_log_block_free"); if (log_buf.block != NULL) { ut_allocator<byte>(mem_key_row_log_buf).deallocate_large( - log_buf.block, &log_buf.block_pfx, - log_buf.size); + log_buf.block, &log_buf.block_pfx); log_buf.block = NULL; } DBUG_VOID_RETURN; @@ -3243,9 +3244,11 @@ row_log_allocate( index->online_log = log; if (log_tmp_is_encrypted()) { - ulint size = srv_sort_buf_size; - log->crypt_head = static_cast<byte *>(os_mem_alloc_large(&size)); - log->crypt_tail = static_cast<byte *>(os_mem_alloc_large(&size)); + log->crypt_head_size = log->crypt_tail_size = srv_sort_buf_size; + log->crypt_head = static_cast<byte *>( + my_large_malloc(&log->crypt_head_size, MYF(MY_WME))); + log->crypt_tail = static_cast<byte *>( + my_large_malloc(&log->crypt_tail_size, MYF(MY_WME))); if (!log->crypt_head || !log->crypt_tail) { row_log_free(log); @@ -3277,11 +3280,11 @@ row_log_free( row_merge_file_destroy_low(log->fd); if (log->crypt_head) { - os_mem_free_large(log->crypt_head, srv_sort_buf_size); + my_large_free(log->crypt_head, log->crypt_head_size); } if (log->crypt_tail) { - os_mem_free_large(log->crypt_tail, srv_sort_buf_size); + my_large_free(log->crypt_tail, log->crypt_tail_size); } mutex_free(&log->mutex); diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 1c3f52e1b4a..e4943195fb1 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4745,11 +4745,10 @@ func_exit: ut_free(merge_files); - alloc.deallocate_large(block, &block_pfx, block_size); + alloc.deallocate_large(block, &block_pfx); if (crypt_block) { - alloc.deallocate_large(crypt_block, &crypt_pfx, - block_size); + alloc.deallocate_large(crypt_block, &crypt_pfx); } DICT_TF2_FLAG_UNSET(new_table, DICT_TF2_FTS_ADD_DOC_ID); |