-
Praveenkumar.Hulakund authored
Bug#20705642 - max_statement_time: assertion failed: pending || thd_timer->thread_id Description: ------------- Both of these issues are related to deletion of timer from the Timer-queue. Issue in bug20705648 is, the timer object created in windows is not deleted after the timer expiration. Hence memory leak is seen on the windows. Issue in bug20705642 is, the timer reset operation sets state of timer as "not expired" when the timer is already expired and the callback function execution of it is completed. This is resulting in the assert condition failure. Analysis: ------------- In the current code, for the set timer operation new Timer-queue timer is created. For timer cancel and destroy operations, timer -queue timer is deleted from the Timer-queue. But when timer is expired, assumption was timers of type "WT_EXECUTEONLYONCE" are deleted. But these timer objects are not delete from Timer-queue on expiration. Hence the memory leak is observed in the current code. The windows API to delete timer-queue timer, 1 Fails when timer is expired or callback function is in execution. 2 Succeeds when timer is *not* expired. 3 Succeeds when timer is expired and callback function execution is completed. In the current code, case 1 and 2 are handled properly but case 3 is not handled. Because of which windows timer reset operation returns timer state as not expired. If timer is not expired then non zero thread_id value is expected (as notify function for timer expiration is not called) in reset timer code. Assert condition to check the same fails in debug build because of not handling condition 3. In non-debug build, timer object is just set for the reuse. Fix: ------ To fix memory leak, if timer is expired then deleting it from the queue on next timer set or timer destroy operations. To fix assert issues, new timer_state member is introduced in the my_timer for windows. timer_state is set to "TIMER_SET" in timer set operation and in timer_callback to "TIMER_EXPIRED". With timer_state, setting timer expired/not expired state in timer reset operation is handled as below, Timer reset operation (my_timer_cancel()): Windows API DeleteTimerQueueTimer is used to delete m the timer queue. This API, * Succeeds when timer is *not* expired. state is set to *not expired* as timer_state is TIMER_SET. * Succeeds when timer is expired and callback function execution is completed. state is set to *expired* as timer_state is TIMER_EXPIRED. * *Fails* when timer is expired or callback function is in execution. state is set to *expired*. timer_state value is *not* checked in this case. So to fix assert condition failure, "timer_state" value is checked to set timer expired or non expired state. Now if timer cancellation is called after timer callback execution then "expired" state is returned. Testing: -------- Without patch, memory leak of around 400kb/sec is observed with mysqlslap.exe -hlocalhost --number-of-queries=10000000000 --query="select max_statement_time=1 sleep(rand()) ;" --iterations=1000000 --create-schema=test With patch no memory leak or crash is observed, \bin>time The current time is: 11:21:03.07 Enter the new time: \bin>tasklist /FI "IMAGENAME eq mysqld.exe" Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ mysqld.exe 11304 RDP-Tcp#28 2 119,244 K \bin>time The current time is: 11:28:35.59 Enter the new time: . \bin>tasklist /FI "IMAGENAME eq mysqld.exe" Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ mysqld.exe 11304 RDP-Tcp#28 2 119,244 K
Praveenkumar.Hulakund authoredBug#20705642 - max_statement_time: assertion failed: pending || thd_timer->thread_id Description: ------------- Both of these issues are related to deletion of timer from the Timer-queue. Issue in bug20705648 is, the timer object created in windows is not deleted after the timer expiration. Hence memory leak is seen on the windows. Issue in bug20705642 is, the timer reset operation sets state of timer as "not expired" when the timer is already expired and the callback function execution of it is completed. This is resulting in the assert condition failure. Analysis: ------------- In the current code, for the set timer operation new Timer-queue timer is created. For timer cancel and destroy operations, timer -queue timer is deleted from the Timer-queue. But when timer is expired, assumption was timers of type "WT_EXECUTEONLYONCE" are deleted. But these timer objects are not delete from Timer-queue on expiration. Hence the memory leak is observed in the current code. The windows API to delete timer-queue timer, 1 Fails when timer is expired or callback function is in execution. 2 Succeeds when timer is *not* expired. 3 Succeeds when timer is expired and callback function execution is completed. In the current code, case 1 and 2 are handled properly but case 3 is not handled. Because of which windows timer reset operation returns timer state as not expired. If timer is not expired then non zero thread_id value is expected (as notify function for timer expiration is not called) in reset timer code. Assert condition to check the same fails in debug build because of not handling condition 3. In non-debug build, timer object is just set for the reuse. Fix: ------ To fix memory leak, if timer is expired then deleting it from the queue on next timer set or timer destroy operations. To fix assert issues, new timer_state member is introduced in the my_timer for windows. timer_state is set to "TIMER_SET" in timer set operation and in timer_callback to "TIMER_EXPIRED". With timer_state, setting timer expired/not expired state in timer reset operation is handled as below, Timer reset operation (my_timer_cancel()): Windows API DeleteTimerQueueTimer is used to delete m the timer queue. This API, * Succeeds when timer is *not* expired. state is set to *not expired* as timer_state is TIMER_SET. * Succeeds when timer is expired and callback function execution is completed. state is set to *expired* as timer_state is TIMER_EXPIRED. * *Fails* when timer is expired or callback function is in execution. state is set to *expired*. timer_state value is *not* checked in this case. So to fix assert condition failure, "timer_state" value is checked to set timer expired or non expired state. Now if timer cancellation is called after timer callback execution then "expired" state is returned. Testing: -------- Without patch, memory leak of around 400kb/sec is observed with mysqlslap.exe -hlocalhost --number-of-queries=10000000000 --query="select max_statement_time=1 sleep(rand()) ;" --iterations=1000000 --create-schema=test With patch no memory leak or crash is observed, \bin>time The current time is: 11:21:03.07 Enter the new time: \bin>tasklist /FI "IMAGENAME eq mysqld.exe" Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ mysqld.exe 11304 RDP-Tcp#28 2 119,244 K \bin>time The current time is: 11:28:35.59 Enter the new time: . \bin>tasklist /FI "IMAGENAME eq mysqld.exe" Image Name PID Session Name Session# Mem Usage ========================= ======== ================ =========== ============ mysqld.exe 11304 RDP-Tcp#28 2 119,244 K
Loading