diff --git a/VERSION b/VERSION index 283afc0001caf..a46cc7020c5f8 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=11 -MYSQL_VERSION_PATCH=12 +MYSQL_VERSION_PATCH=13 SERVER_MATURITY=stable diff --git a/include/my_sys.h b/include/my_sys.h index 5eca29b3274c6..23799f661c4f6 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -177,7 +177,9 @@ extern my_bool my_use_large_pages; int my_init_large_pages(void); uchar *my_large_malloc(size_t *size, myf my_flags); -#if defined _WIN32 || defined HAVE_MMAP +#ifdef _WIN32 +/* On Windows, use my_virtual_mem_reserve() and my_virtual_mem_commit(). */ +#else char *my_large_virtual_alloc(size_t *size); #endif void my_large_free(void *ptr, size_t size); diff --git a/include/my_virtual_mem.h b/include/my_virtual_mem.h index 56b2f03b32904..8f9f6660e3b6d 100644 --- a/include/my_virtual_mem.h +++ b/include/my_virtual_mem.h @@ -24,7 +24,9 @@ extern "C" { #endif +# ifdef _WIN32 char *my_virtual_mem_reserve(size_t *size); +# endif char *my_virtual_mem_commit(char *ptr, size_t size); void my_virtual_mem_decommit(char *ptr, size_t size); void my_virtual_mem_release(char *ptr, size_t size); diff --git a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result index 5db74a7163630..66b36f18bc83c 100644 --- a/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result +++ b/mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result @@ -12,12 +12,19 @@ select @@innodb_buffer_pool_size; 10485760 create table t1 (id int primary key, val int not null) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +create table t2 (id int primary key, val int not null) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=$kbs; SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR INSERT INTO t1 SELECT seq*4,seq*4 FROM seq_1_to_262144; +SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR +INSERT INTO t2 SELECT seq*4,seq*4 FROM seq_1_to_16384; set global innodb_buffer_pool_size = 7340032; select count(val) from t1; count(val) 262144 +select count(val) from t2; +count(val) +16384 set global innodb_adaptive_hash_index=OFF; set global innodb_buffer_pool_size = 24117248; set global innodb_buffer_pool_size = 26214400; @@ -29,7 +36,10 @@ select @@innodb_buffer_pool_size; select count(val) from t1; count(val) 262144 -drop table t1; +select count(val) from t2; +count(val) +16384 +drop table t1,t2; SET GLOBAL innodb_max_purge_lag_wait = 0; SET @save_pct= @@GLOBAL.innodb_max_dirty_pages_pct; SET @save_pct_lwm= @@GLOBAL.innodb_max_dirty_pages_pct_lwm; diff --git a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test index 612a0c1be6432..4cbbdba997495 100644 --- a/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test +++ b/mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test @@ -21,6 +21,7 @@ set global innodb_buffer_pool_size = 9437184; set global innodb_buffer_pool_size = 10485760; select @@innodb_buffer_pool_size; +let $kbs=`SELECT CAST(@@innodb_page_size / 1024 AS INT)`; # fill buffer pool --disable_query_log @@ -29,9 +30,13 @@ SET GLOBAL innodb_read_only_compressed=OFF; --enable_query_log create table t1 (id int primary key, val int not null) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +evalp create table t2 (id int primary key, val int not null) +ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=$kbs; SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR INSERT INTO t1 SELECT seq*4,seq*4 FROM seq_1_to_262144; +SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR +INSERT INTO t2 SELECT seq*4,seq*4 FROM seq_1_to_16384; --disable_query_log SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed; @@ -42,6 +47,7 @@ SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed; set global innodb_buffer_pool_size = 7340032; select count(val) from t1; +select count(val) from t2; set global innodb_adaptive_hash_index=OFF; @@ -52,8 +58,9 @@ set global innodb_buffer_pool_size = 26214400; select @@innodb_buffer_pool_size; select count(val) from t1; +select count(val) from t2; -drop table t1; +drop table t1,t2; SET GLOBAL innodb_max_purge_lag_wait = 0; SET @save_pct= @@GLOBAL.innodb_max_dirty_pages_pct; @@ -66,8 +73,6 @@ SELECT variable_value = 0 FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY'; --source include/wait_condition.inc -# this may occasionally be aborted on a heavily loaded builder ---error 0,ER_WRONG_USAGE SET GLOBAL innodb_buffer_pool_size = @old_innodb_buffer_pool_size; SET GLOBAL innodb_adaptive_hash_index = @old_innodb_adaptive_hash_index; SET GLOBAL innodb_max_dirty_pages_pct = @save_pct; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_ssl_stop.test b/mysql-test/suite/rpl/t/rpl_semi_sync_ssl_stop.test index cab9caf8ac432..e9d6e241f84ab 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_ssl_stop.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_ssl_stop.test @@ -49,8 +49,8 @@ SET @@GLOBAL.rpl_semi_sync_slave_enabled= 1; --connection master --echo # Verify Semi-Sync is active ---let $status_var= Rpl_semi_sync_master_status ---let $status_var_value= ON +--let $status_var= Rpl_semi_sync_master_clients +--let $status_var_value= 1 --source include/wait_for_status_var.inc SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'; @@ -67,7 +67,7 @@ STOP SLAVE; --echo # MDEV-36663: Verifying dump thread connection is killed.. # Prior to MDEV-36663 fixes, this would time out and # Rpl_semi_sync_master_clients would remain 1. ---let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.PROCESSLIST WHERE COMMAND = 'Binlog Dump' +--let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.PROCESSLIST WHERE USER = 'replssl' --source include/wait_condition.inc --let $n_master_clients= query_get_value(SHOW STATUS LIKE 'Rpl_semi_sync_master_clients', Value, 1) diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c index 240c8e84fc771..22561ddc5640b 100644 --- a/mysys/my_largepage.c +++ b/mysys/my_largepage.c @@ -423,7 +423,7 @@ uchar *my_large_malloc(size_t *size, myf my_flags) DBUG_RETURN(ptr); } -#ifdef _WIN32 +#ifndef _WIN32 /** Special large pages allocator, with possibility to commit to allocating more memory later. @@ -434,37 +434,10 @@ char *my_large_virtual_alloc(size_t *size) char *ptr; DBUG_ENTER("my_large_virtual_alloc"); - if (my_use_large_pages) - { - size_t s= *size; - s= MY_ALIGN(s, (size_t) my_large_page_size); - ptr= VirtualAlloc(NULL, s, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, - PAGE_READWRITE); - if (ptr) - { - *size= s; - DBUG_RETURN(ptr); - } - } - - DBUG_RETURN(VirtualAlloc(NULL, *size, MEM_RESERVE, PAGE_READWRITE)); -} -#elif defined HAVE_MMAP -/** - Special large pages allocator, with possibility to commit to allocating - more memory later. - Every implementation returns a zero filled buffer here. -*/ -char *my_large_mmap(size_t *size, int prot) -{ - char *ptr; - DBUG_ENTER("my_large_virtual_alloc"); - if (my_use_large_pages) { size_t large_page_size; int page_i= 0; - prot= PROT_READ | PROT_WRITE; while ((large_page_size= my_next_large_page_size(*size, &page_i)) != 0) { @@ -488,7 +461,7 @@ char *my_large_mmap(size_t *size, int prot) OS_MAP_ANON; size_t aligned_size= MY_ALIGN(*size, (size_t) large_page_size); - ptr= mmap(NULL, aligned_size, prot, mapflag, -1, 0); + ptr= mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, mapflag, -1, 0); if (ptr == (void*) -1) { ptr= NULL; @@ -511,10 +484,7 @@ char *my_large_mmap(size_t *size, int prot) } } - ptr= mmap(NULL, *size, prot, -# ifdef MAP_NORESERVE - MAP_NORESERVE | -# endif + ptr= mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, -1, 0); if (ptr == MAP_FAILED) { @@ -524,16 +494,6 @@ char *my_large_mmap(size_t *size, int prot) DBUG_RETURN(ptr); } - -/** - Special large pages allocator, with possibility to commit to allocating - more memory later. - Every implementation returns a zero filled buffer here. -*/ -char *my_large_virtual_alloc(size_t *size) -{ - return my_large_mmap(size, PROT_READ | PROT_WRITE); -} #endif /** diff --git a/mysys/my_virtual_mem.c b/mysys/my_virtual_mem.c index 47e3a29788a7c..649d8c693ff21 100644 --- a/mysys/my_virtual_mem.c +++ b/mysys/my_virtual_mem.c @@ -34,13 +34,9 @@ We try to respect use_large_pages setting, on Windows and Linux */ -#ifndef _WIN32 -char *my_large_mmap(size_t *size, int prot); -#endif - +#ifdef _WIN32 char *my_virtual_mem_reserve(size_t *size) { -#ifdef _WIN32 DWORD flags= my_use_large_pages ? MEM_LARGE_PAGES | MEM_RESERVE | MEM_COMMIT : MEM_RESERVE; @@ -53,10 +49,8 @@ char *my_virtual_mem_reserve(size_t *size) my_error(EE_OUTOFMEMORY, MYF(ME_BELL + ME_ERROR_LOG), *size); } return ptr; -#else - return my_large_mmap(size, PROT_NONE); -#endif } +#endif #if defined _WIN32 && !defined DBUG_OFF static my_bool is_memory_committed(char *ptr, size_t size) @@ -88,7 +82,7 @@ char *my_virtual_mem_commit(char *ptr, size_t size) } #else if (my_use_large_pages) - /* my_large_mmap() already created a read/write mapping. */; + /* my_large_virtual_alloc() already created a read/write mapping. */; else { # ifdef _AIX diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 75256526a3218..4bfea0f310027 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -276,7 +276,7 @@ ATTRIBUTE_COLD void btr_search_enable(bool resize) } btr_search_x_lock_all(); - ulint hash_size = buf_pool.curr_size() / sizeof(void *) / 64; + ulint hash_size = buf_pool.curr_pool_size() / sizeof(void *) / 64; if (btr_search_sys.parts[0].heap) { ut_ad(btr_search_enabled); diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc index 6da47d8430775..a56f9047eea10 100644 --- a/storage/innobase/buf/buf0buddy.cc +++ b/storage/innobase/buf/buf0buddy.cc @@ -637,7 +637,7 @@ void buf_buddy_free_low(void* buf, ulint i) noexcept buf_buddy_add_to_free(reinterpret_cast(buf), i); } -/** Reallocate a ROW_FORMAT=COMPRESSED page frame during buf_pool_t::resize(). +/** Reallocate a ROW_FORMAT=COMPRESSED page frame during buf_pool_t::shrink(). @param bpage page descriptor covering a ROW_FORMAT=COMPRESSED page @param block uncompressed block for storage @return block @@ -672,10 +672,9 @@ buf_block_t *buf_buddy_shrink(buf_page_t *bpage, buf_block_t *block) noexcept bpage->zip.data= static_cast(dst); buf_pool.buddy_stat[i].relocated++; - for (;;) + while (i < BUF_BUDDY_SIZES) { MEM_UNDEFINED(src, BUF_BUDDY_LOW << i); - ut_ad(i < BUF_BUDDY_SIZES); /* Try to combine adjacent blocks. */ buf_buddy_free_t *buddy= reinterpret_cast (buf_buddy_get(static_cast(src), BUF_BUDDY_LOW << i)); @@ -684,20 +683,16 @@ buf_block_t *buf_buddy_shrink(buf_page_t *bpage, buf_block_t *block) noexcept { ut_ad(!buf_pool.contains_zip(src, BUF_BUDDY_LOW_SHIFT + i)); buf_buddy_add_to_free(static_cast(src), i); - break; + return block; } /* The buddy is free: recombine */ buf_buddy_remove_from_free(buddy, i); i++; src= ut_align_down(src, BUF_BUDDY_LOW << i); - if (i == BUF_BUDDY_SIZES) - { - buf_buddy_block_free(src); - break; - } } + buf_buddy_block_free(src); return block; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 261a796141d8a..f9769f3fb18a1 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1336,7 +1336,11 @@ bool buf_pool_t::create() noexcept retry: { NUMA_MEMPOLICY_INTERLEAVE_IN_SCOPE; +#ifdef _WIN32 memory_unaligned= my_virtual_mem_reserve(&size); +#else + memory_unaligned= my_large_virtual_alloc(&size); +#endif } if (!memory_unaligned) @@ -1370,6 +1374,7 @@ bool buf_pool_t::create() noexcept #ifdef UNIV_PFS_MEMORY PSI_MEMORY_CALL(memory_alloc)(mem_key_buf_buf_pool, actual_size, &owner); #endif +#ifdef _WIN32 if (!my_virtual_mem_commit(memory, actual_size)) { my_virtual_mem_release(memory_unaligned, size_unaligned); @@ -1377,6 +1382,9 @@ bool buf_pool_t::create() noexcept memory_unaligned= nullptr; goto oom; } +#else + update_malloc_size(actual_size, 0); +#endif #ifdef HAVE_LIBNUMA if (srv_numa_interleave) @@ -1788,6 +1796,9 @@ ATTRIBUTE_COLD buf_pool_t::shrink_status buf_pool_t::shrink(size_t size) goto next; } + if (UT_LIST_GET_LEN(free) + UT_LIST_GET_LEN(LRU) < usable_size() / 20) + return SHRINK_ABORT; + mysql_mutex_lock(&flush_list_mutex); if (LRU_warned && !UT_LIST_GET_FIRST(free)) diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 1f5d6eab2593a..bbf2014608d04 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -276,7 +276,10 @@ static void buf_LRU_check_size_of_non_data_objects() noexcept auto s= UT_LIST_GET_LEN(buf_pool.free) + UT_LIST_GET_LEN(buf_pool.LRU); - if (s < curr_size / 20) + if (s >= curr_size / 20); + else if (buf_pool.is_shrinking()) + buf_pool.LRU_warn(); + else { sql_print_error("[FATAL] InnoDB: Over 95 percent of the buffer pool is" " occupied by lock heaps" diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index a155ce4c0e1a6..7d6b704f086bc 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -933,7 +933,7 @@ void dict_sys_t::create() noexcept UT_LIST_INIT(table_LRU, &dict_table_t::table_LRU); UT_LIST_INIT(table_non_LRU, &dict_table_t::table_LRU); - const ulint hash_size = buf_pool.curr_size() + const ulint hash_size = buf_pool.curr_pool_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); table_hash.create(hash_size); @@ -4399,7 +4399,7 @@ void dict_sys_t::resize() noexcept table_id_hash.free(); temp_id_hash.free(); - const ulint hash_size = buf_pool.curr_size() + const ulint hash_size = buf_pool.curr_pool_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE); table_hash.create(hash_size); table_id_hash.create(hash_size); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f1c48ccfcb711..d03ef08d1db4b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4075,7 +4075,6 @@ static int innodb_init_params() #else ut_ad(srv_file_flush_method <= SRV_O_DIRECT_NO_FSYNC); #endif - srv_lock_table_size = 5 * buf_pool.curr_size(); DBUG_RETURN(0); } diff --git a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h index 9ac26c7d4be1c..11c42307b4704 100644 --- a/storage/innobase/include/buf0buddy.h +++ b/storage/innobase/include/buf0buddy.h @@ -76,7 +76,7 @@ inline void buf_buddy_free(void* buf, ulint size) noexcept } ATTRIBUTE_COLD MY_ATTRIBUTE((nonnull, warn_unused_result)) -/** Reallocate a ROW_FORMAT=COMPRESSED page frame during buf_pool_t::resize(). +/** Reallocate a ROW_FORMAT=COMPRESSED page frame during buf_pool_t::shrink(). @param bpage page descriptor covering a ROW_FORMAT=COMPRESSED page @param block uncompressed block for storage @return block diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 716dac624d5a8..3c984da3d5d44 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -916,17 +916,16 @@ ATTRIBUTE_COLD void log_t::append_prepare_wait(bool late, bool ex) noexcept { got_ex: const uint64_t l= write_lsn_offset.load(std::memory_order_relaxed); - const lsn_t lsn{base_lsn.load(std::memory_order_relaxed)}; - ut_d(lsn_t ll= lsn + (l & (WRITE_BACKOFF - 1))); - ut_ad(is_mmap() - ? ll - get_flushed_lsn(std::memory_order_relaxed) < capacity() - : ll - write_lsn - ((write_size - 1) & (write_lsn - first_lsn)) < - buf_size); + const lsn_t lsn= base_lsn.load(std::memory_order_relaxed) + + (l & (WRITE_BACKOFF - 1)); waits++; #ifdef HAVE_PMEM const bool is_pmem{is_mmap()}; if (is_pmem) - persist(lsn + (l & (WRITE_BACKOFF - 1))); + { + ut_ad(lsn - get_flushed_lsn(std::memory_order_relaxed) < capacity()); + persist(lsn); + } #endif latch.wr_unlock(); /* write_buf() or persist() will clear the WRITE_BACKOFF flag, @@ -934,7 +933,7 @@ ATTRIBUTE_COLD void log_t::append_prepare_wait(bool late, bool ex) noexcept #ifdef HAVE_PMEM if (!is_pmem) #endif - log_write_up_to(lsn + (l & (WRITE_BACKOFF - 1)), false); + log_write_up_to(lsn, false); if (ex) { latch.wr_lock(SRW_LOCK_CALL); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 3577cd7b1184f..ba8b202191d76 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1311,7 +1311,7 @@ dberr_t srv_start(bool create_new_db) log_sys.create(); recv_sys.create(); - lock_sys.create(srv_lock_table_size); + lock_sys.create(srv_lock_table_size = 5 * buf_pool.curr_size()); srv_startup_is_before_trx_rollback_phase = true; diff --git a/storage/innobase/ut/ut0rnd.cc b/storage/innobase/ut/ut0rnd.cc index a2e569514cbf0..0e0e0004bb1e6 100644 --- a/storage/innobase/ut/ut0rnd.cc +++ b/storage/innobase/ut/ut0rnd.cc @@ -48,6 +48,8 @@ ut_find_prime( ulint pow2; ulint i; + ut_ad(n); + n += 100; pow2 = 1;