MDEV-4566 : Failing DBUG_ASSERT() in SELECT SLEEP(), with threadpool.
This bug only happens with long sleep()s ( > 5 sec), and in debug version. Analysis: The assertion is caused by nested thd_wait_begin() calls, which is not an expected condition. - "outer" thd_wait_begin()) , in Item_func_sleep::val_int() - "inner" thd_wait_begin() in Interruptible_wait::wait(). This function periodically checks whether connection is still valid, via THD::is_connection(), which ends up calling vio_io_wait() with timeout parameter set to 0. Fix is not to call thd wait callback in vio_io_wait(), if timeout parameter is 0. There is no "waiting" in this case.
This commit is contained in:
parent
52045d40d4
commit
08ce9bfe05
@ -2157,10 +2157,10 @@ Warnings:
|
|||||||
Warning 1052 Column 'kundentyp' in group statement is ambiguous
|
Warning 1052 Column 'kundentyp' in group statement is ambiguous
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SET optimizer_switch=@save_optimizer_switch;
|
SET optimizer_switch=@save_optimizer_switch;
|
||||||
SELECT sleep(5);
|
SELECT sleep(5.5);
|
||||||
SELECT sleep(5);
|
SELECT sleep(5);
|
||||||
# -- Success: more than --thread_pool_max_threads normal connections not possible
|
# -- Success: more than --thread_pool_max_threads normal connections not possible
|
||||||
sleep(5)
|
sleep(5.5)
|
||||||
0
|
0
|
||||||
sleep(5)
|
sleep(5)
|
||||||
0
|
0
|
||||||
|
@ -17,7 +17,10 @@ SET optimizer_switch=@save_optimizer_switch;
|
|||||||
# First set two connections running, and check that extra connection
|
# First set two connections running, and check that extra connection
|
||||||
# on normal port fails due to--thread-pool-max_threads=2
|
# on normal port fails due to--thread-pool-max_threads=2
|
||||||
connection default;
|
connection default;
|
||||||
send SELECT sleep(5);
|
|
||||||
|
# Sleep for slightly longer than 5 sec to trigger MDEV-4566
|
||||||
|
# (abort in interruptible wait connection check)
|
||||||
|
send SELECT sleep(5.5);
|
||||||
--sleep 1
|
--sleep 1
|
||||||
|
|
||||||
connect(con2,localhost,root,,);
|
connect(con2,localhost,root,,);
|
||||||
|
@ -42,21 +42,21 @@ static void (*before_io_wait)(void)= 0;
|
|||||||
static void (*after_io_wait)(void)= 0;
|
static void (*after_io_wait)(void)= 0;
|
||||||
|
|
||||||
/* Wait callback macros (both performance schema and threadpool */
|
/* Wait callback macros (both performance schema and threadpool */
|
||||||
#define START_SOCKET_WAIT(locker, state_ptr, sock, which) \
|
#define START_SOCKET_WAIT(locker, state_ptr, sock, which, timeout) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
MYSQL_START_SOCKET_WAIT(locker, state_ptr, sock, \
|
MYSQL_START_SOCKET_WAIT(locker, state_ptr, sock, \
|
||||||
which, 0); \
|
which, 0); \
|
||||||
if (before_io_wait) \
|
if (timeout && before_io_wait) \
|
||||||
before_io_wait(); \
|
before_io_wait(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define END_SOCKET_WAIT(locker) \
|
#define END_SOCKET_WAIT(locker,timeout) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
MYSQL_END_SOCKET_WAIT(locker, 0); \
|
MYSQL_END_SOCKET_WAIT(locker, 0); \
|
||||||
if (after_io_wait) \
|
if (timeout && after_io_wait) \
|
||||||
after_io_wait(); \
|
after_io_wait(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@ -930,11 +930,11 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
|
|||||||
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
||||||
{
|
{
|
||||||
START_SOCKET_WAIT(locker, &state, vio->mysql_socket,
|
START_SOCKET_WAIT(locker, &state, vio->mysql_socket,
|
||||||
PSI_SOCKET_SELECT);
|
PSI_SOCKET_SELECT, timeout);
|
||||||
ret= my_io_wait_async(vio->async_context, event, timeout);
|
ret= my_io_wait_async(vio->async_context, event, timeout);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
errno= SOCKET_ETIMEDOUT;
|
errno= SOCKET_ETIMEDOUT;
|
||||||
END_SOCKET_WAIT(locker);
|
END_SOCKET_WAIT(locker,timeout);
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,7 +959,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT);
|
START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, timeout);
|
||||||
/*
|
/*
|
||||||
Wait for the I/O event and return early in case of
|
Wait for the I/O event and return early in case of
|
||||||
error or timeout.
|
error or timeout.
|
||||||
@ -982,7 +982,7 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
END_SOCKET_WAIT(locker);
|
END_SOCKET_WAIT(locker, timeout);
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,11 +1004,11 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
|
|||||||
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
if (timeout != 0 && vio->async_context && vio->async_context->active)
|
||||||
{
|
{
|
||||||
START_SOCKET_WAIT(locker, &state, vio->mysql_socket,
|
START_SOCKET_WAIT(locker, &state, vio->mysql_socket,
|
||||||
PSI_SOCKET_SELECT);
|
PSI_SOCKET_SELECT, timeout);
|
||||||
ret= my_io_wait_async(vio->async_context, event, timeout);
|
ret= my_io_wait_async(vio->async_context, event, timeout);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
WSASetLastError(SOCKET_ETIMEDOUT);
|
WSASetLastError(SOCKET_ETIMEDOUT);
|
||||||
END_SOCKET_WAIT(locker);
|
END_SOCKET_WAIT(locker, timeout);
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,12 +1039,12 @@ int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT);
|
START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, timeout);
|
||||||
|
|
||||||
/* The first argument is ignored on Windows. */
|
/* The first argument is ignored on Windows. */
|
||||||
ret= select(0, &readfds, &writefds, &exceptfds, (timeout >= 0) ? &tm : NULL);
|
ret= select(0, &readfds, &writefds, &exceptfds, (timeout >= 0) ? &tm : NULL);
|
||||||
|
|
||||||
END_SOCKET_WAIT(locker);
|
END_SOCKET_WAIT(locker, timeout);
|
||||||
|
|
||||||
/* Set error code to indicate a timeout error. */
|
/* Set error code to indicate a timeout error. */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user