1 # name : innodb_fast_shutdown
5 # Shutting down XtraDB takes uninterruptible sleep()s up to 10
6 # seconds, even when there is no actual work to do during shutdown.
8 # This patch removes most such delays during shutdown, as found using
9 # PMP. This makes standard test run very close in speed to with
10 # --loose-innodb-fast-shutdown=2, and greatly speeds up running the test
13 # The patch also implements os_event_wait_time() for POSIX systems.
15 +++ b/COPYING.innodb_fast_shutdown
17 +Copyright (c) 2010, Kristian Nielsen
20 +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
22 + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
23 + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
24 + * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
26 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --- a/storage/innodb_plugin/include/os0sync.h
28 +++ b/storage/innodb_plugin/include/os0sync.h
31 /**********************************************************//**
32 Waits for an event object until it is in the signaled state or
33 -a timeout is exceeded. In Unix the timeout is always infinite.
34 +a timeout is exceeded.
35 @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
40 os_event_t event, /*!< in: event to wait */
41 - ulint time); /*!< in: timeout in microseconds, or
42 + ulint wtime); /*!< in: timeout in microseconds, or
43 OS_SYNC_INFINITE_TIME */
45 /**********************************************************//**
46 --- a/storage/innodb_plugin/include/srv0srv.h
47 +++ b/storage/innodb_plugin/include/srv0srv.h
49 thread starts running */
50 extern os_event_t srv_lock_timeout_thread_event;
52 +/* This event is set at shutdown to wakeup threads from sleep */
53 +extern os_event_t srv_shutdown_event;
55 /* If the last data file is auto-extended, we add this many pages to it
57 #define SRV_AUTO_EXTEND_INCREMENT \
58 --- a/storage/innodb_plugin/log/log0log.c
59 +++ b/storage/innodb_plugin/log/log0log.c
61 algorithm only works if the server is idle at shutdown */
63 srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
64 + os_event_set(srv_shutdown_event);
66 os_thread_sleep(100000);
68 --- a/storage/innodb_plugin/os/os0sync.c
69 +++ b/storage/innodb_plugin/os/os0sync.c
75 +#include <sys/time.h>
82 /**********************************************************//**
83 Waits for an event object until it is in the signaled state or
84 -a timeout is exceeded. In Unix the timeout is always infinite.
85 +a timeout is exceeded.
86 @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
91 os_event_t event, /*!< in: event to wait */
92 - ulint time) /*!< in: timeout in microseconds, or
93 + ulint wtime) /*!< in: timeout in microseconds, or
94 OS_SYNC_INFINITE_TIME */
101 - if (time != OS_SYNC_INFINITE_TIME) {
102 - err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
103 + if (wtime != OS_SYNC_INFINITE_TIME) {
104 + err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
106 err = WaitForSingleObject(event->handle, INFINITE);
108 @@ -439,13 +442,47 @@
109 return(1000000); /* dummy value to eliminate compiler warn. */
116 + ib_int64_t old_count;
117 + struct timeval tv_start;
118 + struct timespec timeout;
120 + if (wtime == OS_SYNC_INFINITE_TIME) {
121 + os_event_wait(event);
125 + /* Compute the absolute point in time at which to time out. */
126 + gettimeofday(&tv_start, NULL);
127 + tmp = tv_start.tv_usec + wtime;
128 + timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000);
129 + timeout.tv_nsec = (tmp % 1000000) * 1000;
131 + os_fast_mutex_lock(&(event->os_mutex));
132 + old_count = event->signal_count;
134 - /* In Posix this is just an ordinary, infinite wait */
136 + if (event->is_set == TRUE || event->signal_count != old_count)
139 + err = pthread_cond_timedwait(&(event->cond_var),
140 + &(event->os_mutex), &timeout);
141 + if (err == ETIMEDOUT) {
142 + ret = OS_SYNC_TIME_EXCEEDED;
147 - os_event_wait(event);
148 + os_fast_mutex_unlock(&(event->os_mutex));
150 + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
152 + os_thread_exit(NULL);
160 --- a/storage/innodb_plugin/srv/srv0srv.c
161 +++ b/storage/innodb_plugin/srv/srv0srv.c
164 UNIV_INTERN os_event_t srv_lock_timeout_thread_event;
166 +UNIV_INTERN os_event_t srv_shutdown_event;
168 UNIV_INTERN srv_sys_t* srv_sys = NULL;
170 /* padding to prevent other memory update hotspots from residing on
171 @@ -1027,6 +1029,7 @@
174 srv_lock_timeout_thread_event = os_event_create(NULL);
175 + srv_shutdown_event = os_event_create(NULL);
177 for (i = 0; i < SRV_MASTER + 1; i++) {
178 srv_n_threads_active[i] = 0;
179 @@ -2256,7 +2259,7 @@
180 /* Wake up every 5 seconds to see if we need to print
181 monitor information. */
183 - os_thread_sleep(5000000);
184 + os_event_wait_time(srv_shutdown_event, 5000000);
186 current_time = time(NULL);
188 @@ -2398,7 +2401,7 @@
189 /* When someone is waiting for a lock, we wake up every second
190 and check if a timeout has passed for a lock wait */
192 - os_thread_sleep(1000000);
193 + os_event_wait_time(srv_shutdown_event, 1000000);
195 srv_lock_timeout_active = TRUE;
197 @@ -2602,7 +2605,7 @@
201 - os_thread_sleep(1000000);
202 + os_event_wait_time(srv_shutdown_event, 1000000);
204 if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
206 @@ -2648,7 +2651,7 @@
207 last_dump_time = time(NULL);
210 - os_thread_sleep(5000000);
211 + os_event_wait_time(srv_shutdown_event, 5000000);
213 if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
215 @@ -2831,7 +2834,7 @@
217 if (next_itr_time > cur_time) {
219 - os_thread_sleep(ut_min(1000000, (next_itr_time - cur_time) * 1000));
220 + os_event_wait_time(srv_shutdown_event, ut_min(1000000, (next_itr_time - cur_time) * 1000));
224 @@ -3538,9 +3541,10 @@
225 mutex_exit(&kernel_mutex);
228 + os_event_reset(srv_shutdown_event);
231 - os_thread_sleep( sleep_ms * 1000 );
232 + os_event_wait_time(srv_shutdown_event, sleep_ms * 1000);
234 history_len = trx_sys->rseg_history_len;
235 if (history_len > 1000)