From 8361151765cc5efd72ad18c5553f80aa440a1d83 Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Tue, 1 Mar 2016 12:29:51 +0530 Subject: Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE Problem: ======== Currently SHOW SLAVE STATUS blocks if IO thread waits for disk space. This makes automation tools verifying server health block on taking relevant action. Finally this will create SHOW SLAVE STATUS piles. Analysis: ========= SHOW SLAVE STATUS hangs on mi->data_lock if relay log write is waiting for free disk space while holding mi->data_lock. mi->data_lock is needed to protect the format description event (mi->format_description_event) which is accessed by the clients running FLUSH LOGS and slave IO thread. Note relay log writes don't need to be protected by mi->data_lock, LOCK_log is used to protect relay log between IO and SQL thread (see MYSQL_BIN_LOG::append_event). The code takes mi->data_lock to protect mi->format_description_event during relay log rotate which might get triggered right after relay log write. Fix: ==== Release the data_lock just for the duration of writing into relay log. Made change to ensure the following lock order is maintained to avoid deadlocks. data_lock, LOCK_log data_lock is held during relay log rotations to protect the description event. --- mysys/errors.c | 13 +++++++++---- mysys/my_write.c | 10 +++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'mysys') diff --git a/mysys/errors.c b/mysys/errors.c index ddd65836b30..942fd3230c0 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -109,6 +109,7 @@ void init_glob_errs() */ void wait_for_free_space(const char *filename, int errors) { + size_t time_to_sleep= MY_WAIT_FOR_USER_TO_FIX_PANIC; if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE)) { my_printf_warning(EE(EE_DISK_FULL), @@ -119,10 +120,14 @@ void wait_for_free_space(const char *filename, int errors) } DBUG_EXECUTE_IF("simulate_no_free_space_error", { - (void) sleep(1); - return; + time_to_sleep= 1; }); - (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC); + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", + { + time_to_sleep= 1; + }); + + (void) sleep(time_to_sleep); } const char **get_global_errmsgs() diff --git a/mysys/my_write.c b/mysys/my_write.c index ef15e9a55b6..2e68a4dcff3 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -24,6 +24,7 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes, written; uint errors; + size_t ToWriteCount; DBUG_ENTER("my_write"); DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", Filedes, Buffer, (ulong) Count, MyFlags)); @@ -37,11 +38,14 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { DBUG_SET("+d,simulate_file_write_error");}); for (;;) { + ToWriteCount= Count; + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { ToWriteCount= 1; }); #ifdef _WIN32 - writtenbytes= my_win_write(Filedes, Buffer, Count); + writtenbytes= my_win_write(Filedes, Buffer, ToWriteCount); #else - writtenbytes= write(Filedes, Buffer, Count); + writtenbytes= write(Filedes, Buffer, ToWriteCount); #endif + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { errno= ENOSPC; }); DBUG_EXECUTE_IF("simulate_file_write_error", { errno= ENOSPC; -- cgit v1.2.1 From 6608f84158d3561ef2c2f12a7136aa05cc39d7b4 Mon Sep 17 00:00:00 2001 From: Nisha Gopalakrishnan Date: Mon, 14 Mar 2016 15:20:21 +0530 Subject: BUG#22594514: HANDLE_FATAL_SIGNAL (SIG=11) IN UNIQUE::~UNIQUE | SQL/UNIQUES.CC:355 Analysis ======== Enabling the sort_buffer_size with a large value can cause operations utilizing the sort buffer like DELETE as mentioned in the bug report to fail. 5.5 and 5.6 versions reports OOM error while in 5.7+, the server crashes. While initializing the mem_root for the sort buffer tree, the block size for the mem_root is determined from the 'sort_buffer_size' value. This unsigned long value is typecasted to unsigned int, hence it becomes zero. Further block_size computation while initializing the mem_root results in a very large block_size value. Hence while trying to allocate a block during the DELETE operation, an OOM error is reported. In case of 5.7+, the PFS instrumentation for memory allocation, overshoots the unsigned value and allocates a block of just one byte. While trying to free the block of the mem_root, the original block_size is used. This triggers the crash since the server tries to free unallocated memory. Fix: ==== In order to restrict usage of such unreasonable sort_buffer_size, the typecast of block size to 'unsigned int' is removed and hence reports OOM error across all versions for sizes exceeding unsigned int range. --- mysys/tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mysys') diff --git a/mysys/tree.c b/mysys/tree.c index c5bf3681a35..3f7360de40a 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 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 @@ -83,7 +83,7 @@ static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent); static int test_rb_tree(TREE_ELEMENT *element); #endif -void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, +void init_tree(TREE *tree, size_t default_alloc_size, ulong memory_limit, int size, qsort_cmp2 compare, my_bool with_delete, tree_element_free free_element, void *custom_arg) { @@ -127,7 +127,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, } if (!(tree->with_delete=with_delete)) { - init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0); + init_alloc_root(&tree->mem_root, default_alloc_size, 0); tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element); } DBUG_VOID_RETURN; -- cgit v1.2.1 From 3a8f43bec76d3d93a809b6a3c76e26e946ba0425 Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Mon, 11 Apr 2016 11:41:47 +0530 Subject: Bug#22897202: RPL_IO_THD_WAIT_FOR_DISK_SPACE HAS OCCASIONAL FAILURES Analysis: ========= Test script is not ensuring that "assert_grep.inc" should be called only after 'Disk is full' error is written to the error log. Test checks for "Queueing master event to the relay log" state. But this state is set before invoking 'queue_event'. Actual 'Disk is full' error happens at a very lower level. It can happen that we might even reset the debug point before even the actual disk full simulation occurs and the "Disk is full" message will never appear in the error log. In order to guarentee that we must have some mechanism where in after we write "Disk is full" error messge into the error log we must signal the test to execute SSS and then reset the debug point. So that test is deterministic. Fix: === Added debug sync point to make script deterministic. --- mysys/errors.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mysys') diff --git a/mysys/errors.c b/mysys/errors.c index 942fd3230c0..b6064460535 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -15,7 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" - +#include "m_string.h" #ifndef SHARED_LIBRARY const char *globerrs[GLOBERRS]= @@ -128,6 +128,7 @@ void wait_for_free_space(const char *filename, int errors) }); (void) sleep(time_to_sleep); + DEBUG_SYNC_C("disk_full_reached"); } const char **get_global_errmsgs() -- cgit v1.2.1 From ef3f09f0c9e62ea1bf86b33b5d97e954b3ae34fe Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Fri, 13 May 2016 16:42:45 +0530 Subject: Bug#23251517: SEMISYNC REPLICATION HANGING Revert following bug fix: Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE This fix results in a deadlock between slave IO thread and SQL thread. (cherry picked from commit e3fea6c6dbb36c6ab21c4ab777224560e9608b53) --- mysys/errors.c | 14 ++++---------- mysys/my_write.c | 8 ++------ 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'mysys') diff --git a/mysys/errors.c b/mysys/errors.c index b6064460535..a6e2e300a1f 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -15,7 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" -#include "m_string.h" + #ifndef SHARED_LIBRARY const char *globerrs[GLOBERRS]= @@ -109,7 +109,6 @@ void init_glob_errs() */ void wait_for_free_space(const char *filename, int errors) { - size_t time_to_sleep= MY_WAIT_FOR_USER_TO_FIX_PANIC; if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE)) { my_printf_warning(EE(EE_DISK_FULL), @@ -120,15 +119,10 @@ void wait_for_free_space(const char *filename, int errors) } DBUG_EXECUTE_IF("simulate_no_free_space_error", { - time_to_sleep= 1; - }); - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", - { - time_to_sleep= 1; + (void) sleep(1); + return; }); - - (void) sleep(time_to_sleep); - DEBUG_SYNC_C("disk_full_reached"); + (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC); } const char **get_global_errmsgs() diff --git a/mysys/my_write.c b/mysys/my_write.c index 2e68a4dcff3..f092420756e 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -24,7 +24,6 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes, written; uint errors; - size_t ToWriteCount; DBUG_ENTER("my_write"); DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", Filedes, Buffer, (ulong) Count, MyFlags)); @@ -38,14 +37,11 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { DBUG_SET("+d,simulate_file_write_error");}); for (;;) { - ToWriteCount= Count; - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { ToWriteCount= 1; }); #ifdef _WIN32 - writtenbytes= my_win_write(Filedes, Buffer, ToWriteCount); + writtenbytes= my_win_write(Filedes, Buffer, Count); #else - writtenbytes= write(Filedes, Buffer, ToWriteCount); + writtenbytes= write(Filedes, Buffer, Count); #endif - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { errno= ENOSPC; }); DBUG_EXECUTE_IF("simulate_file_write_error", { errno= ENOSPC; -- cgit v1.2.1 From 0089af8e1c767ed34ff8d92428beacf50fa97e79 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 13 Jun 2016 18:11:31 +0300 Subject: MDEV-9433: [PATCH] cppcheck reported a number of minor coding errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a bug in testhash.c that caused an out of bounds memory access when command line parameters specified 0 records to be inserted in the hashtable. Signed-off-by: Vicențiu Ciorbaru --- mysys/testhash.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'mysys') diff --git a/mysys/testhash.c b/mysys/testhash.c index ffdaaece770..aa78a2d8c40 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -169,7 +169,9 @@ static int do_test() for (j=0 ; j < 1000 ; j++) if (key1[j] > 1) break; - if (key1[j] > 1) + // j will be 1000 only if we have no keys in the hash. This only happens + // when the parameter recant is set to 0 via command line argument. + if (j < 1000 && key1[j] > 1) { HASH_SEARCH_STATE state; printf("- Testing identical read\n"); -- cgit v1.2.1 From bfef17bec193d8c965604ad29d4b4b9f800bccac Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 13 Jun 2016 18:30:02 +0300 Subject: MDEV-9433: [PATCH} cppcheck reported a number of minor coding errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix cppwarning of va_args being opened but not closed. Signed-off-by: Vicențiu Ciorbaru --- mysys/mf_iocache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'mysys') diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 02e5c5373ae..31a09e214d2 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1874,6 +1874,7 @@ void die(const char* fmt, ...) fprintf(stderr,"Error:"); vfprintf(stderr, fmt,va_args); fprintf(stderr,", errno=%d\n", errno); + va_end(va_args); exit(1); } -- cgit v1.2.1