MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
srv0srv.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2008, 2009 Google Inc.
5 Copyright (c) 2009, Percona Inc.
6 
7 Portions of this file contain modifications contributed and copyrighted by
8 Google, Inc. Those modifications are gratefully acknowledged and are described
9 briefly in the InnoDB documentation. The contributions by Google are
10 incorporated with their permission, and subject to the conditions contained in
11 the file COPYING.Google.
12 
13 Portions of this file contain modifications contributed and copyrighted
14 by Percona Inc.. Those modifications are
15 gratefully acknowledged and are described briefly in the InnoDB
16 documentation. The contributions by Percona Inc. are incorporated with
17 their permission, and subject to the conditions contained in the file
18 COPYING.Percona.
19 
20 This program is free software; you can redistribute it and/or modify it under
21 the terms of the GNU General Public License as published by the Free Software
22 Foundation; version 2 of the License.
23 
24 This program is distributed in the hope that it will be useful, but WITHOUT
25 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27 
28 You should have received a copy of the GNU General Public License along with
29 this program; if not, write to the Free Software Foundation, Inc.,
30 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
31 
32 *****************************************************************************/
33 
34 /**************************************************/
41 /* Dummy comment */
42 #include "srv0srv.h"
43 
44 #include "ut0mem.h"
45 #include "ut0ut.h"
46 #include "os0proc.h"
47 #include "mem0mem.h"
48 #include "mem0pool.h"
49 #include "sync0sync.h"
50 #include "que0que.h"
51 #include "log0recv.h"
52 #include "pars0pars.h"
53 #include "usr0sess.h"
54 #include "lock0lock.h"
55 #include "trx0purge.h"
56 #include "ibuf0ibuf.h"
57 #include "buf0flu.h"
58 #include "buf0lru.h"
59 #include "btr0sea.h"
60 #include "dict0load.h"
61 #include "dict0boot.h"
62 #include "dict0stats_bg.h" /* dict_stats_event */
63 #include "srv0start.h"
64 #include "row0mysql.h"
65 #include "ha_prototypes.h"
66 #include "trx0i_s.h"
67 #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
68 #include "srv0mon.h"
69 #include "ut0crc32.h"
70 
71 #include "mysql/plugin.h"
72 #include "mysql/service_thd_wait.h"
73 
74 /* The following is the maximum allowed duration of a lock wait. */
75 UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600;
76 
77 /* How much data manipulation language (DML) statements need to be delayed,
78 in microseconds, in order to reduce the lagging of the purge thread. */
79 UNIV_INTERN ulint srv_dml_needed_delay = 0;
80 
81 UNIV_INTERN ibool srv_monitor_active = FALSE;
82 UNIV_INTERN ibool srv_error_monitor_active = FALSE;
83 
84 UNIV_INTERN ibool srv_buf_dump_thread_active = FALSE;
85 
86 UNIV_INTERN ibool srv_dict_stats_thread_active = FALSE;
87 
88 UNIV_INTERN const char* srv_main_thread_op_info = "";
89 
91 const char srv_mysql50_table_name_prefix[10] = "#mysql50#";
92 
93 /* Server parameters which are read from the initfile */
94 
95 /* The following three are dir paths which are catenated before file
96 names, where the file name itself may also contain a path */
97 
98 UNIV_INTERN char* srv_data_home = NULL;
99 
101 UNIV_INTERN char* srv_undo_dir = NULL;
102 
104 UNIV_INTERN ulong srv_undo_tablespaces = 8;
105 
107 UNIV_INTERN ulint srv_undo_tablespaces_open = 8;
108 
109 /* The number of rollback segments to use */
110 UNIV_INTERN ulong srv_undo_logs = 1;
111 
112 #ifdef UNIV_LOG_ARCHIVE
113 UNIV_INTERN char* srv_arch_dir = NULL;
114 #endif /* UNIV_LOG_ARCHIVE */
115 
119 UNIV_INTERN my_bool srv_read_only_mode;
122 UNIV_INTERN my_bool srv_file_per_table;
124 UNIV_INTERN ulint srv_file_format = 0;
128 UNIV_INTERN ulint srv_max_file_format_at_startup = UNIV_FORMAT_MAX;
129 
130 #if UNIV_FORMAT_A
131 # error "UNIV_FORMAT_A must be 0!"
132 #endif
133 
136 UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
138 UNIV_INTERN ulong srv_sort_buf_size = 1048576;
140 UNIV_INTERN unsigned long long srv_online_max_size;
141 
142 /* If this flag is TRUE, then we will use the native aio of the
143 OS (provided we compiled Innobase with it in), otherwise we will
144 use simulated aio we build below with threads.
145 Currently we support native aio on windows and linux */
146 UNIV_INTERN my_bool srv_use_native_aio = TRUE;
147 
148 #ifdef __WIN__
149 /* Windows native condition variables. We use runtime loading / function
150 pointers, because they are not available on Windows Server 2003 and
151 Windows XP/2000.
152 
153 We use condition for events on Windows if possible, even if os_event
154 resembles Windows kernel event object well API-wise. The reason is
155 performance, kernel objects are heavyweights and WaitForSingleObject() is a
156 performance killer causing calling thread to context switch. Besides, Innodb
157 is preallocating large number (often millions) of os_events. With kernel event
158 objects it takes a big chunk out of non-paged pool, which is better suited
159 for tasks like IO than for storing idle event objects. */
160 UNIV_INTERN ibool srv_use_native_conditions = FALSE;
161 #endif /* __WIN__ */
162 
163 UNIV_INTERN ulint srv_n_data_files = 0;
164 UNIV_INTERN char** srv_data_file_names = NULL;
165 /* size in database pages */
166 UNIV_INTERN ulint* srv_data_file_sizes = NULL;
167 
168 /* if TRUE, then we auto-extend the last data file */
169 UNIV_INTERN ibool srv_auto_extend_last_data_file = FALSE;
170 /* if != 0, this tells the max size auto-extending may increase the
171 last data file size */
172 UNIV_INTERN ulint srv_last_file_size_max = 0;
173 /* If the last data file is auto-extended, we add this
174 many pages to it at a time */
175 UNIV_INTERN ulong srv_auto_extend_increment = 8;
176 UNIV_INTERN ulint* srv_data_file_is_raw_partition = NULL;
177 
178 /* If the following is TRUE we do not allow inserts etc. This protects
179 the user from forgetting the 'newraw' keyword to my.cnf */
180 
181 UNIV_INTERN ibool srv_created_new_raw = FALSE;
182 
183 UNIV_INTERN char* srv_log_group_home_dir = NULL;
184 
185 UNIV_INTERN ulong srv_n_log_files = SRV_N_LOG_FILES_MAX;
186 /* size in database pages */
187 UNIV_INTERN ib_uint64_t srv_log_file_size = IB_UINT64_MAX;
188 UNIV_INTERN ib_uint64_t srv_log_file_size_requested;
189 /* size in database pages */
190 UNIV_INTERN ulint srv_log_buffer_size = ULINT_MAX;
191 UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
192 UNIV_INTERN uint srv_flush_log_at_timeout = 1;
193 UNIV_INTERN ulong srv_page_size = UNIV_PAGE_SIZE_DEF;
194 UNIV_INTERN ulong srv_page_size_shift = UNIV_PAGE_SIZE_SHIFT_DEF;
195 
196 /* Try to flush dirty pages so as to avoid IO bursts at
197 the checkpoints. */
198 UNIV_INTERN char srv_adaptive_flushing = TRUE;
199 
202 #define MAX_MUTEX_NOWAIT 20
203 
208 #define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
209 
212 UNIV_INTERN const byte* srv_latin1_ordering;
213 
214 /* use os/external memory allocator */
215 UNIV_INTERN my_bool srv_use_sys_malloc = TRUE;
216 /* requested size in kilobytes */
217 UNIV_INTERN ulint srv_buf_pool_size = ULINT_MAX;
218 /* requested number of buffer pool instances */
219 UNIV_INTERN ulint srv_buf_pool_instances = 1;
220 /* number of locks to protect buf_pool->page_hash */
221 UNIV_INTERN ulong srv_n_page_hash_locks = 16;
223 UNIV_INTERN ulong srv_LRU_scan_depth = 1024;
225 UNIV_INTERN ulong srv_flush_neighbors = 1;
226 /* previously requested size */
227 UNIV_INTERN ulint srv_buf_pool_old_size;
228 /* current size in kilobytes */
229 UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
230 /* size in bytes */
231 UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
232 UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
233 
234 /* This parameter is deprecated. Use srv_n_io_[read|write]_threads
235 instead. */
236 UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
237 UNIV_INTERN ulint srv_n_read_io_threads = ULINT_MAX;
238 UNIV_INTERN ulint srv_n_write_io_threads = ULINT_MAX;
239 
240 /* Switch to enable random read ahead. */
241 UNIV_INTERN my_bool srv_random_read_ahead = FALSE;
242 /* User settable value of the number of pages that must be present
243 in the buffer cache and accessed sequentially for InnoDB to trigger a
244 readahead request. */
245 UNIV_INTERN ulong srv_read_ahead_threshold = 56;
246 
247 #ifdef UNIV_LOG_ARCHIVE
248 UNIV_INTERN ibool srv_log_archive_on = FALSE;
249 UNIV_INTERN ibool srv_archive_recovery = 0;
250 UNIV_INTERN ib_uint64_t srv_archive_recovery_limit_lsn;
251 #endif /* UNIV_LOG_ARCHIVE */
252 
253 /* This parameter is used to throttle the number of insert buffers that are
254 merged in a batch. By increasing this parameter on a faster disk you can
255 possibly reduce the number of I/O operations performed to complete the
256 merge operation. The value of this parameter is used as is by the
257 background loop when the system is idle (low load), on a busy system
258 the parameter is scaled down by a factor of 4, this is to avoid putting
259 a heavier load on the I/O sub system. */
260 
261 UNIV_INTERN ulong srv_insert_buffer_batch_size = 20;
262 
263 UNIV_INTERN char* srv_file_flush_method_str = NULL;
264 UNIV_INTERN ulint srv_unix_file_flush_method = SRV_UNIX_FSYNC;
265 UNIV_INTERN ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
266 
267 UNIV_INTERN ulint srv_max_n_open_files = 300;
268 
269 /* Number of IO operations per second the server can do */
270 UNIV_INTERN ulong srv_io_capacity = 200;
271 UNIV_INTERN ulong srv_max_io_capacity = 400;
272 
273 /* The InnoDB main thread tries to keep the ratio of modified pages
274 in the buffer pool to all database pages in the buffer pool smaller than
275 the following number. But it is not guaranteed that the value stays below
276 that during a time of heavy update/insert activity. */
277 
278 UNIV_INTERN ulong srv_max_buf_pool_modified_pct = 75;
279 UNIV_INTERN ulong srv_max_dirty_pages_pct_lwm = 50;
280 
281 /* This is the percentage of log capacity at which adaptive flushing,
282 if enabled, will kick in. */
283 UNIV_INTERN ulong srv_adaptive_flushing_lwm = 10;
284 
285 /* Number of iterations over which adaptive flushing is averaged. */
286 UNIV_INTERN ulong srv_flushing_avg_loops = 30;
287 
288 /* The number of purge threads to use.*/
289 UNIV_INTERN ulong srv_n_purge_threads = 1;
290 
291 /* the number of pages to purge in one batch */
292 UNIV_INTERN ulong srv_purge_batch_size = 20;
293 
294 /* Internal setting for "innodb_stats_method". Decides how InnoDB treats
295 NULL value when collecting statistics. By default, it is set to
296 SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
297 UNIV_INTERN ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
298 
299 UNIV_INTERN srv_stats_t srv_stats;
300 
301 /* structure to pass status variables to MySQL */
303 
308 UNIV_INTERN ulong srv_force_recovery;
309 #ifndef DBUG_OFF
310 
312 UNIV_INTERN ulong srv_force_recovery_crash;
313 #endif /* !DBUG_OFF */
314 
317 UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
318 
320 UNIV_INTERN my_bool srv_cmp_per_index_enabled = FALSE;
321 
322 /* If the following is set to 1 then we do not run purge and insert buffer
323 merge to completion before shutdown. If it is set to 2, do not even flush the
324 buffer pool to data files at the shutdown: we effectively 'crash'
325 InnoDB (but lose no committed transactions). */
326 UNIV_INTERN ulint srv_fast_shutdown = 0;
327 
328 /* Generate a innodb_status.<pid> file */
329 UNIV_INTERN ibool srv_innodb_status = FALSE;
330 
331 /* When estimating number of different key values in an index, sample
332 this many index pages, there are 2 ways to calculate statistics:
333 * persistent stats that are calculated by ANALYZE TABLE and saved
334  in the innodb database.
335 * quick transient stats, that are used if persistent stats for the given
336  table/index are not found in the innodb database */
337 UNIV_INTERN unsigned long long srv_stats_transient_sample_pages = 8;
338 UNIV_INTERN my_bool srv_stats_persistent = TRUE;
339 UNIV_INTERN unsigned long long srv_stats_persistent_sample_pages = 20;
340 UNIV_INTERN my_bool srv_stats_auto_recalc = TRUE;
341 
342 UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
343 
348 UNIV_INTERN ulong srv_doublewrite_batch_size = 120;
349 
350 UNIV_INTERN ulong srv_replication_delay = 0;
351 
352 /*-------------------------------------------*/
353 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
354 UNIV_INTERN ulong srv_spin_wait_delay = 6;
355 UNIV_INTERN ibool srv_priority_boost = TRUE;
356 
357 #ifdef UNIV_DEBUG
358 UNIV_INTERN ibool srv_print_thread_releases = FALSE;
359 UNIV_INTERN ibool srv_print_lock_waits = FALSE;
360 UNIV_INTERN ibool srv_print_buf_io = FALSE;
361 UNIV_INTERN ibool srv_print_log_io = FALSE;
362 UNIV_INTERN ibool srv_print_latch_waits = FALSE;
363 #endif /* UNIV_DEBUG */
364 
365 static ulint srv_n_rows_inserted_old = 0;
366 static ulint srv_n_rows_updated_old = 0;
367 static ulint srv_n_rows_deleted_old = 0;
368 static ulint srv_n_rows_read_old = 0;
369 
370 UNIV_INTERN ulint srv_truncated_status_writes = 0;
371 UNIV_INTERN ulint srv_available_undo_logs = 0;
372 
373 /* Set the following to 0 if you want InnoDB to write messages on
374 stderr on startup/shutdown. */
375 UNIV_INTERN ibool srv_print_verbose_log = TRUE;
376 UNIV_INTERN ibool srv_print_innodb_monitor = FALSE;
377 UNIV_INTERN ibool srv_print_innodb_lock_monitor = FALSE;
378 UNIV_INTERN ibool srv_print_innodb_tablespace_monitor = FALSE;
379 UNIV_INTERN ibool srv_print_innodb_table_monitor = FALSE;
380 
381 /* Array of English strings describing the current state of an
382 i/o handler thread */
383 
384 UNIV_INTERN const char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS];
385 UNIV_INTERN const char* srv_io_thread_function[SRV_MAX_N_IO_THREADS];
386 
387 UNIV_INTERN time_t srv_last_monitor_time;
388 
389 UNIV_INTERN ib_mutex_t srv_innodb_monitor_mutex;
390 
391 /* Mutex for locking srv_monitor_file. Not created if srv_read_only_mode */
392 UNIV_INTERN ib_mutex_t srv_monitor_file_mutex;
393 
394 #ifdef UNIV_PFS_MUTEX
395 # ifndef HAVE_ATOMIC_BUILTINS
396 /* Key to register server_mutex with performance schema */
397 UNIV_INTERN mysql_pfs_key_t server_mutex_key;
398 # endif /* !HAVE_ATOMIC_BUILTINS */
399 
400 UNIV_INTERN mysql_pfs_key_t srv_innodb_monitor_mutex_key;
402 UNIV_INTERN mysql_pfs_key_t srv_monitor_file_mutex_key;
404 UNIV_INTERN mysql_pfs_key_t srv_dict_tmpfile_mutex_key;
406 UNIV_INTERN mysql_pfs_key_t srv_misc_tmpfile_mutex_key;
408 UNIV_INTERN mysql_pfs_key_t srv_sys_mutex_key;
410 UNIV_INTERN mysql_pfs_key_t srv_sys_tasks_mutex_key;
411 #endif /* UNIV_PFS_MUTEX */
412 
414 UNIV_INTERN FILE* srv_monitor_file;
420 UNIV_INTERN FILE* srv_dict_tmpfile;
426 UNIV_INTERN FILE* srv_misc_tmpfile;
427 
428 UNIV_INTERN ulint srv_main_thread_process_no = 0;
429 UNIV_INTERN ulint srv_main_thread_id = 0;
430 
431 /* The following counts are used by the srv_master_thread. */
432 
434 static ulint srv_main_active_loops = 0;
436 static ulint srv_main_idle_loops = 0;
438 static ulint srv_main_shutdown_loops = 0;
440 static ulint srv_log_writes_and_flush = 0;
441 
442 /* This is only ever touched by the master thread. It records the
443 time when the last flush of log file has happened. The master
444 thread ensures that we flush the log files at least once per
445 second. */
446 static time_t srv_last_log_flush_time;
447 
448 /* Interval in seconds at which various tasks are performed by the
449 master thread when server is active. In order to balance the workload,
450 we should try to keep intervals such that they are not multiple of
451 each other. For example, if we have intervals for various tasks
452 defined as 5, 10, 15, 60 then all tasks will be performed when
453 current_time % 60 == 0 and no tasks will be performed when
454 current_time % 5 != 0. */
455 
456 # define SRV_MASTER_CHECKPOINT_INTERVAL (7)
457 # define SRV_MASTER_PURGE_INTERVAL (10)
458 #ifdef MEM_PERIODIC_CHECK
459 # define SRV_MASTER_MEM_VALIDATE_INTERVAL (13)
460 #endif /* MEM_PERIODIC_CHECK */
461 # define SRV_MASTER_DICT_LRU_INTERVAL (47)
462 
464 #define srv_sys_mutex_enter() do { \
465  mutex_enter(&srv_sys->mutex); \
466 } while (0)
467 
469 #define srv_sys_mutex_own() (mutex_own(&srv_sys->mutex) \
470  && !srv_read_only_mode)
471 
473 #define srv_sys_mutex_exit() do { \
474  mutex_exit(&srv_sys->mutex); \
475 } while (0)
476 
477 #define fetch_lock_wait_timeout(trx) \
478  ((trx)->lock.allowed_to_wait \
479  ? thd_lock_wait_timeout((trx)->mysql_thd) \
480  : 0)
481 
482 /*
483  IMPLEMENTATION OF THE SERVER MAIN PROGRAM
484  =========================================
485 
486 There is the following analogue between this database
487 server and an operating system kernel:
488 
489 DB concept equivalent OS concept
490 ---------- ---------------------
491 transaction -- process;
492 
493 query thread -- thread;
494 
495 lock -- semaphore;
496 
497 kernel -- kernel;
498 
499 query thread execution:
500 (a) without lock mutex
501 reserved -- process executing in user mode;
502 (b) with lock mutex reserved
503  -- process executing in kernel mode;
504 
505 The server has several backgroind threads all running at the same
506 priority as user threads. It periodically checks if here is anything
507 happening in the server which requires intervention of the master
508 thread. Such situations may be, for example, when flushing of dirty
509 blocks is needed in the buffer pool or old version of database rows
510 have to be cleaned away (purged). The user can configure a separate
511 dedicated purge thread(s) too, in which case the master thread does not
512 do any purging.
513 
514 The threads which we call user threads serve the queries of the MySQL
515 server. They run at normal priority.
516 
517 When there is no activity in the system, also the master thread
518 suspends itself to wait for an event making the server totally silent.
519 
520 There is still one complication in our server design. If a
521 background utility thread obtains a resource (e.g., mutex) needed by a user
522 thread, and there is also some other user activity in the system,
523 the user thread may have to wait indefinitely long for the
524 resource, as the OS does not schedule a background thread if
525 there is some other runnable user thread. This problem is called
526 priority inversion in real-time programming.
527 
528 One solution to the priority inversion problem would be to keep record
529 of which thread owns which resource and in the above case boost the
530 priority of the background thread so that it will be scheduled and it
531 can release the resource. This solution is called priority inheritance
532 in real-time programming. A drawback of this solution is that the overhead
533 of acquiring a mutex increases slightly, maybe 0.2 microseconds on a 100
534 MHz Pentium, because the thread has to call os_thread_get_curr_id. This may
535 be compared to 0.5 microsecond overhead for a mutex lock-unlock pair. Note
536 that the thread cannot store the information in the resource , say mutex,
537 itself, because competing threads could wipe out the information if it is
538 stored before acquiring the mutex, and if it stored afterwards, the
539 information is outdated for the time of one machine instruction, at least.
540 (To be precise, the information could be stored to lock_word in mutex if
541 the machine supports atomic swap.)
542 
543 The above solution with priority inheritance may become actual in the
544 future, currently we do not implement any priority twiddling solution.
545 Our general aim is to reduce the contention of all mutexes by making
546 them more fine grained.
547 
548 The thread table contains information of the current status of each
549 thread existing in the system, and also the event semaphores used in
550 suspending the master thread and utility threads when they have nothing
551 to do. The thread table can be seen as an analogue to the process table
552 in a traditional Unix implementation. */
553 
555 struct srv_sys_t{
558  UT_LIST_BASE_NODE_T(que_thr_t)
568  ulint n_threads_active[SRV_MASTER + 1];
572  srv_stats_t::ulint_ctr_1_t
575 };
576 
577 #ifndef HAVE_ATOMIC_BUILTINS
578 
580 #endif /* !HAVE_ATOMIC_BUILTINS */
581 
582 static srv_sys_t* srv_sys = NULL;
583 
586 
589 
592 
594 UNIV_INTERN char* srv_buf_dump_filename;
595 
598 UNIV_INTERN char srv_buffer_pool_dump_at_shutdown = FALSE;
599 UNIV_INTERN char srv_buffer_pool_load_at_startup = FALSE;
600 
602 static const ulint SRV_PURGE_SLOT = 1;
603 
605 static const ulint SRV_MASTER_SLOT = 0;
606 
607 /*********************************************************************/
609 static
610 void
611 srv_print_master_thread_info(
612 /*=========================*/
613  FILE *file) /* in: output stream */
614 {
615  fprintf(file, "srv_master_thread loops: %lu srv_active, "
616  "%lu srv_shutdown, %lu srv_idle\n",
617  srv_main_active_loops,
618  srv_main_shutdown_loops,
619  srv_main_idle_loops);
620  fprintf(file, "srv_master_thread log flush and writes: %lu\n",
621  srv_log_writes_and_flush);
622 }
623 
624 /*********************************************************************/
626 UNIV_INTERN
627 void
629 /*======================*/
630  ulint i,
631  const char* str)
633 {
634  ut_a(i < SRV_MAX_N_IO_THREADS);
635 
636  srv_io_thread_op_info[i] = str;
637 }
638 
639 /*********************************************************************/
641 UNIV_INTERN
642 void
644 /*=========================*/
645 {
646  for (ulint i = 0; i < UT_ARR_SIZE(srv_io_thread_op_info); ++i) {
647  srv_io_thread_op_info[i] = "not started yet";
648  }
649 }
650 
651 #ifdef UNIV_DEBUG
652 /*********************************************************************/
655 static
656 ibool
657 srv_thread_type_validate(
658 /*=====================*/
660 {
661  switch (type) {
662  case SRV_NONE:
663  break;
664  case SRV_WORKER:
665  case SRV_PURGE:
666  case SRV_MASTER:
667  return(TRUE);
668  }
669  ut_error;
670  return(FALSE);
671 }
672 #endif /* UNIV_DEBUG */
673 
674 /*********************************************************************/
677 static
679 srv_slot_get_type(
680 /*==============*/
681  const srv_slot_t* slot)
682 {
683  srv_thread_type type = slot->type;
684  ut_ad(srv_thread_type_validate(type));
685  return(type);
686 }
687 
688 /*********************************************************************/
691 static
692 srv_slot_t*
693 srv_reserve_slot(
694 /*=============*/
695  srv_thread_type type)
696 {
697  srv_slot_t* slot = 0;
698 
700 
701  ut_ad(srv_thread_type_validate(type));
702 
703  switch (type) {
704  case SRV_MASTER:
705  slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
706  break;
707 
708  case SRV_PURGE:
709  slot = &srv_sys->sys_threads[SRV_PURGE_SLOT];
710  break;
711 
712  case SRV_WORKER:
713  /* Find an empty slot, skip the master and purge slots. */
714  for (slot = &srv_sys->sys_threads[2];
715  slot->in_use;
716  ++slot) {
717 
718  ut_a(slot < &srv_sys->sys_threads[
719  srv_sys->n_sys_threads]);
720  }
721  break;
722 
723  case SRV_NONE:
724  ut_error;
725  }
726 
727  ut_a(!slot->in_use);
728 
729  slot->in_use = TRUE;
730  slot->suspended = FALSE;
731  slot->type = type;
732 
733  ut_ad(srv_slot_get_type(slot) == type);
734 
735  ++srv_sys->n_threads_active[type];
736 
738 
739  return(slot);
740 }
741 
742 /*********************************************************************/
745 static
746 ib_int64_t
747 srv_suspend_thread_low(
748 /*===================*/
749  srv_slot_t* slot)
750 {
751 
754 
755  ut_ad(slot->in_use);
756 
757  srv_thread_type type = srv_slot_get_type(slot);
758 
759  switch (type) {
760  case SRV_NONE:
761  ut_error;
762 
763  case SRV_MASTER:
764  /* We have only one master thread and it
765  should be the first entry always. */
766  ut_a(srv_sys->n_threads_active[type] == 1);
767  break;
768 
769  case SRV_PURGE:
770  /* We have only one purge coordinator thread
771  and it should be the second entry always. */
772  ut_a(srv_sys->n_threads_active[type] == 1);
773  break;
774 
775  case SRV_WORKER:
776  ut_a(srv_n_purge_threads > 1);
777  ut_a(srv_sys->n_threads_active[type] > 0);
778  break;
779  }
780 
781  ut_a(!slot->suspended);
782  slot->suspended = TRUE;
783 
784  ut_a(srv_sys->n_threads_active[type] > 0);
785 
786  srv_sys->n_threads_active[type]--;
787 
788  return(os_event_reset(slot->event));
789 }
790 
791 /*********************************************************************/
794 static
795 ib_int64_t
796 srv_suspend_thread(
797 /*===============*/
798  srv_slot_t* slot)
799 {
801 
802  ib_int64_t sig_count = srv_suspend_thread_low(slot);
803 
805 
806  return(sig_count);
807 }
808 
809 /*********************************************************************/
814 UNIV_INTERN
815 ulint
817 /*================*/
818  srv_thread_type type,
819  ulint n)
820 {
821  ulint i;
822  ulint count = 0;
823 
824  ut_ad(srv_thread_type_validate(type));
825  ut_ad(n > 0);
826 
828 
829  for (i = 0; i < srv_sys->n_sys_threads; i++) {
830  srv_slot_t* slot;
831 
832  slot = &srv_sys->sys_threads[i];
833 
834  if (slot->in_use
835  && srv_slot_get_type(slot) == type
836  && slot->suspended) {
837 
838  switch (type) {
839  case SRV_NONE:
840  ut_error;
841 
842  case SRV_MASTER:
843  /* We have only one master thread and it
844  should be the first entry always. */
845  ut_a(n == 1);
846  ut_a(i == SRV_MASTER_SLOT);
847  ut_a(srv_sys->n_threads_active[type] == 0);
848  break;
849 
850  case SRV_PURGE:
851  /* We have only one purge coordinator thread
852  and it should be the second entry always. */
853  ut_a(n == 1);
854  ut_a(i == SRV_PURGE_SLOT);
855  ut_a(srv_n_purge_threads > 0);
856  ut_a(srv_sys->n_threads_active[type] == 0);
857  break;
858 
859  case SRV_WORKER:
860  ut_a(srv_n_purge_threads > 1);
861  ut_a(srv_sys->n_threads_active[type]
862  < srv_n_purge_threads - 1);
863  break;
864  }
865 
866  slot->suspended = FALSE;
867 
868  ++srv_sys->n_threads_active[type];
869 
870  os_event_set(slot->event);
871 
872  if (++count == n) {
873  break;
874  }
875  }
876  }
877 
879 
880  return(count);
881 }
882 
883 /*********************************************************************/
885 static
886 void
887 srv_free_slot(
888 /*==========*/
889  srv_slot_t* slot)
890 {
892 
893  if (!slot->suspended) {
894  /* Mark the thread as inactive. */
895  srv_suspend_thread_low(slot);
896  }
897 
898  /* Free the slot for reuse. */
899  ut_ad(slot->in_use);
900  slot->in_use = FALSE;
901 
903 }
904 
905 /*********************************************************************/
907 UNIV_INTERN
908 void
909 srv_init(void)
910 /*==========*/
911 {
912  ulint n_sys_threads = 0;
913  ulint srv_sys_sz = sizeof(*srv_sys);
914 
915 #ifndef HAVE_ATOMIC_BUILTINS
916  mutex_create(server_mutex_key, &server_mutex, SYNC_ANY_LATCH);
917 #endif /* !HAVE_ATOMIC_BUILTINS */
918 
919  mutex_create(srv_innodb_monitor_mutex_key,
920  &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
921 
922  if (!srv_read_only_mode) {
923 
924  /* Number of purge threads + master thread */
925  n_sys_threads = srv_n_purge_threads + 1;
926 
927  srv_sys_sz += n_sys_threads * sizeof(*srv_sys->sys_threads);
928  }
929 
930  srv_sys = static_cast<srv_sys_t*>(mem_zalloc(srv_sys_sz));
931 
932  srv_sys->n_sys_threads = n_sys_threads;
933 
934  if (!srv_read_only_mode) {
935 
936  mutex_create(srv_sys_mutex_key, &srv_sys->mutex, SYNC_THREADS);
937 
938  mutex_create(srv_sys_tasks_mutex_key,
939  &srv_sys->tasks_mutex, SYNC_ANY_LATCH);
940 
941  srv_sys->sys_threads = (srv_slot_t*) &srv_sys[1];
942 
943  for (ulint i = 0; i < srv_sys->n_sys_threads; ++i) {
944  srv_slot_t* slot = &srv_sys->sys_threads[i];
945 
946  slot->event = os_event_create();
947 
948  ut_a(slot->event);
949  }
950 
952 
954 
956 
957  UT_LIST_INIT(srv_sys->tasks);
958  }
959 
960  /* page_zip_stat_per_index_mutex is acquired from:
961  1. page_zip_compress() (after SYNC_FSP)
962  2. page_zip_decompress()
963  3. i_s_cmp_per_index_fill_low() (where SYNC_DICT is acquired)
964  4. innodb_cmp_per_index_update(), no other latches
965  since we do not acquire any other latches while holding this mutex,
966  it can have very low level. We pick SYNC_ANY_LATCH for it. */
967 
968  mutex_create(
969  page_zip_stat_per_index_mutex_key,
970  &page_zip_stat_per_index_mutex, SYNC_ANY_LATCH);
971 
972  /* Create dummy indexes for infimum and supremum records */
973 
974  dict_ind_init();
975 
976  srv_conc_init();
977 
978  /* Initialize some INFORMATION SCHEMA internal structures */
980 
981  ut_crc32_init();
982 }
983 
984 /*********************************************************************/
986 UNIV_INTERN
987 void
988 srv_free(void)
989 /*==========*/
990 {
991  srv_conc_free();
992 
993  /* The mutexes srv_sys->mutex and srv_sys->tasks_mutex should have
994  been freed by sync_close() already. */
995  mem_free(srv_sys);
996  srv_sys = NULL;
997 
999 
1000  if (!srv_read_only_mode) {
1002  srv_buf_dump_event = NULL;
1003  }
1004 }
1005 
1006 /*********************************************************************/
1009 UNIV_INTERN
1010 void
1012 /*==================*/
1013 {
1014  ut_mem_init();
1015  /* Reset the system variables in the recovery module. */
1017  os_sync_init();
1018  sync_init();
1019  mem_init(srv_mem_pool_size);
1020  que_init();
1021  row_mysql_init();
1022 }
1023 
1024 /*********************************************************************/
1026 static
1027 void
1028 srv_normalize_init_values(void)
1029 /*===========================*/
1030 {
1031  ulint n;
1032  ulint i;
1033 
1034  n = srv_n_data_files;
1035 
1036  for (i = 0; i < n; i++) {
1037  srv_data_file_sizes[i] = srv_data_file_sizes[i]
1038  * ((1024 * 1024) / UNIV_PAGE_SIZE);
1039  }
1040 
1041  srv_last_file_size_max = srv_last_file_size_max
1042  * ((1024 * 1024) / UNIV_PAGE_SIZE);
1043 
1044  srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
1045 
1046  srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
1047 
1048  srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
1049 }
1050 
1051 /*********************************************************************/
1053 UNIV_INTERN
1054 void
1056 /*==========*/
1057 {
1058  /* Transform the init parameter values given by MySQL to
1059  use units we use inside InnoDB: */
1060 
1061  srv_normalize_init_values();
1062 
1063  /* Initialize synchronization primitives, memory management, and thread
1064  local storage */
1065 
1066  srv_general_init();
1067 
1068  /* Initialize this module */
1069 
1070  srv_init();
1071  srv_mon_create();
1072 }
1073 
1074 /******************************************************************/
1076 static
1077 void
1078 srv_refresh_innodb_monitor_stats(void)
1079 /*==================================*/
1080 {
1081  mutex_enter(&srv_innodb_monitor_mutex);
1082 
1083  srv_last_monitor_time = time(NULL);
1084 
1086 
1089 
1091 
1093 
1094  srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
1095  srv_n_rows_updated_old = srv_stats.n_rows_updated;
1096  srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
1097  srv_n_rows_read_old = srv_stats.n_rows_read;
1098 
1099  mutex_exit(&srv_innodb_monitor_mutex);
1100 }
1101 
1102 /******************************************************************/
1106 UNIV_INTERN
1107 ibool
1109 /*======================*/
1110  FILE* file,
1111  ibool nowait,
1113  ulint* trx_start_pos,
1115  ulint* trx_end)
1117 {
1118  double time_elapsed;
1119  time_t current_time;
1120  ulint n_reserved;
1121  ibool ret;
1122 
1123  mutex_enter(&srv_innodb_monitor_mutex);
1124 
1125  current_time = time(NULL);
1126 
1127  /* We add 0.001 seconds to time_elapsed to prevent division
1128  by zero if two users happen to call SHOW ENGINE INNODB STATUS at the
1129  same time */
1130 
1131  time_elapsed = difftime(current_time, srv_last_monitor_time)
1132  + 0.001;
1133 
1134  srv_last_monitor_time = time(NULL);
1135 
1136  fputs("\n=====================================\n", file);
1137 
1138  ut_print_timestamp(file);
1139  fprintf(file,
1140  " INNODB MONITOR OUTPUT\n"
1141  "=====================================\n"
1142  "Per second averages calculated from the last %lu seconds\n",
1143  (ulong) time_elapsed);
1144 
1145  fputs("-----------------\n"
1146  "BACKGROUND THREAD\n"
1147  "-----------------\n", file);
1148  srv_print_master_thread_info(file);
1149 
1150  fputs("----------\n"
1151  "SEMAPHORES\n"
1152  "----------\n", file);
1153  sync_print(file);
1154 
1155  /* Conceptually, srv_innodb_monitor_mutex has a very high latching
1156  order level in sync0sync.h, while dict_foreign_err_mutex has a very
1157  low level 135. Therefore we can reserve the latter mutex here without
1158  a danger of a deadlock of threads. */
1159 
1160  mutex_enter(&dict_foreign_err_mutex);
1161 
1162  if (!srv_read_only_mode && ftell(dict_foreign_err_file) != 0L) {
1163  fputs("------------------------\n"
1164  "LATEST FOREIGN KEY ERROR\n"
1165  "------------------------\n", file);
1166  ut_copy_file(file, dict_foreign_err_file);
1167  }
1168 
1169  mutex_exit(&dict_foreign_err_mutex);
1170 
1171  /* Only if lock_print_info_summary proceeds correctly,
1172  before we call the lock_print_info_all_transactions
1173  to print all the lock information. IMPORTANT NOTE: This
1174  function acquires the lock mutex on success. */
1175  ret = lock_print_info_summary(file, nowait);
1176 
1177  if (ret) {
1178  if (trx_start_pos) {
1179  long t = ftell(file);
1180  if (t < 0) {
1181  *trx_start_pos = ULINT_UNDEFINED;
1182  } else {
1183  *trx_start_pos = (ulint) t;
1184  }
1185  }
1186 
1187  /* NOTE: If we get here then we have the lock mutex. This
1188  function will release the lock mutex that we acquired when
1189  we called the lock_print_info_summary() function earlier. */
1190 
1192 
1193  if (trx_end) {
1194  long t = ftell(file);
1195  if (t < 0) {
1196  *trx_end = ULINT_UNDEFINED;
1197  } else {
1198  *trx_end = (ulint) t;
1199  }
1200  }
1201  }
1202 
1203  fputs("--------\n"
1204  "FILE I/O\n"
1205  "--------\n", file);
1206  os_aio_print(file);
1207 
1208  fputs("-------------------------------------\n"
1209  "INSERT BUFFER AND ADAPTIVE HASH INDEX\n"
1210  "-------------------------------------\n", file);
1211  ibuf_print(file);
1212 
1214 
1215  fprintf(file,
1216  "%.2f hash searches/s, %.2f non-hash searches/s\n",
1218  / time_elapsed,
1220  / time_elapsed);
1223 
1224  fputs("---\n"
1225  "LOG\n"
1226  "---\n", file);
1227  log_print(file);
1228 
1229  fputs("----------------------\n"
1230  "BUFFER POOL AND MEMORY\n"
1231  "----------------------\n", file);
1232  fprintf(file,
1233  "Total memory allocated " ULINTPF
1234  "; in additional pool allocated " ULINTPF "\n",
1237  fprintf(file, "Dictionary memory allocated " ULINTPF "\n",
1238  dict_sys->size);
1239 
1240  buf_print_io(file);
1241 
1242  fputs("--------------\n"
1243  "ROW OPERATIONS\n"
1244  "--------------\n", file);
1245  fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n",
1246  (long) srv_conc_get_active_threads(),
1248 
1249  /* This is a dirty read, without holding trx_sys->mutex. */
1250  fprintf(file, "%lu read views open inside InnoDB\n",
1251  UT_LIST_GET_LEN(trx_sys->view_list));
1252 
1253  n_reserved = fil_space_get_n_reserved_extents(0);
1254  if (n_reserved > 0) {
1255  fprintf(file,
1256  "%lu tablespace extents now reserved for"
1257  " B-tree split operations\n",
1258  (ulong) n_reserved);
1259  }
1260 
1261 #ifdef UNIV_LINUX
1262  fprintf(file, "Main thread process no. %lu, id %lu, state: %s\n",
1263  (ulong) srv_main_thread_process_no,
1264  (ulong) srv_main_thread_id,
1265  srv_main_thread_op_info);
1266 #else
1267  fprintf(file, "Main thread id %lu, state: %s\n",
1268  (ulong) srv_main_thread_id,
1269  srv_main_thread_op_info);
1270 #endif
1271  fprintf(file,
1272  "Number of rows inserted " ULINTPF
1273  ", updated " ULINTPF ", deleted " ULINTPF
1274  ", read " ULINTPF "\n",
1275  (ulint) srv_stats.n_rows_inserted,
1276  (ulint) srv_stats.n_rows_updated,
1277  (ulint) srv_stats.n_rows_deleted,
1278  (ulint) srv_stats.n_rows_read);
1279  fprintf(file,
1280  "%.2f inserts/s, %.2f updates/s,"
1281  " %.2f deletes/s, %.2f reads/s\n",
1282  ((ulint) srv_stats.n_rows_inserted - srv_n_rows_inserted_old)
1283  / time_elapsed,
1284  ((ulint) srv_stats.n_rows_updated - srv_n_rows_updated_old)
1285  / time_elapsed,
1286  ((ulint) srv_stats.n_rows_deleted - srv_n_rows_deleted_old)
1287  / time_elapsed,
1288  ((ulint) srv_stats.n_rows_read - srv_n_rows_read_old)
1289  / time_elapsed);
1290 
1291  srv_n_rows_inserted_old = srv_stats.n_rows_inserted;
1292  srv_n_rows_updated_old = srv_stats.n_rows_updated;
1293  srv_n_rows_deleted_old = srv_stats.n_rows_deleted;
1294  srv_n_rows_read_old = srv_stats.n_rows_read;
1295 
1296  fputs("----------------------------\n"
1297  "END OF INNODB MONITOR OUTPUT\n"
1298  "============================\n", file);
1299  mutex_exit(&srv_innodb_monitor_mutex);
1300  fflush(file);
1301 
1302  return(ret);
1303 }
1304 
1305 /******************************************************************/
1307 UNIV_INTERN
1308 void
1310 /*==========================*/
1311 {
1312  buf_pool_stat_t stat;
1313  buf_pools_list_size_t buf_pools_list_size;
1314  ulint LRU_len;
1315  ulint free_len;
1316  ulint flush_list_len;
1317 
1318  buf_get_total_stat(&stat);
1319  buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
1320  buf_get_total_list_size_in_bytes(&buf_pools_list_size);
1321 
1322  mutex_enter(&srv_innodb_monitor_mutex);
1323 
1326 
1329 
1333 
1334  export_vars.innodb_data_fsyncs = os_n_fsyncs;
1335 
1337 
1338  export_vars.innodb_data_reads = os_n_file_reads;
1339 
1340  export_vars.innodb_data_writes = os_n_file_writes;
1341 
1343 
1345 
1348 
1351 
1354 
1356 
1358  stat.n_ra_pages_read_rnd;
1359 
1361  stat.n_ra_pages_read;
1362 
1364  stat.n_ra_pages_evicted;
1365 
1367 
1369  buf_pools_list_size.LRU_bytes
1370  + buf_pools_list_size.unzip_LRU_bytes;
1371 
1373 
1375  buf_pools_list_size.flush_list_bytes;
1376 
1378 
1379 #ifdef UNIV_DEBUG
1380  export_vars.innodb_buffer_pool_pages_latched =
1381  buf_get_latched_pages_number();
1382 #endif /* UNIV_DEBUG */
1384 
1386  buf_pool_get_n_pages() - LRU_len - free_len;
1387 
1388 #ifdef HAVE_ATOMIC_BUILTINS
1390 #else
1392 #endif
1393  export_vars.innodb_page_size = UNIV_PAGE_SIZE;
1394 
1396 
1398 
1400 
1402 
1405 
1407 
1409 
1412 
1414 
1416 
1418 
1420 
1422 
1425 
1427 
1428  if (srv_stats.n_lock_wait_count > 0) {
1429 
1432  / 1000 / srv_stats.n_lock_wait_count);
1433 
1434  } else {
1436  }
1437 
1440 
1442 
1444 
1446 
1448 
1450 
1452  srv_truncated_status_writes;
1453 
1454  export_vars.innodb_available_undo_logs = srv_available_undo_logs;
1455 
1456 #ifdef UNIV_DEBUG
1458  trx_id_t done_trx_no = purge_sys->done.trx_no;
1459  trx_id_t up_limit_id = purge_sys->view
1461  : 0;
1462  rw_lock_s_unlock(&purge_sys->latch);
1463 
1464  mutex_enter(&trx_sys->mutex);
1465  trx_id_t max_trx_id = trx_sys->rw_max_trx_id;
1466  mutex_exit(&trx_sys->mutex);
1467 
1468  if (!done_trx_no || max_trx_id < done_trx_no - 1) {
1469  export_vars.innodb_purge_trx_id_age = 0;
1470  } else {
1471  export_vars.innodb_purge_trx_id_age =
1472  (ulint) (max_trx_id - done_trx_no + 1);
1473  }
1474 
1475  if (!up_limit_id
1476  || max_trx_id < up_limit_id) {
1477  export_vars.innodb_purge_view_trx_id_age = 0;
1478  } else {
1479  export_vars.innodb_purge_view_trx_id_age =
1480  (ulint) (max_trx_id - up_limit_id);
1481  }
1482 #endif /* UNIV_DEBUG */
1483 
1484  mutex_exit(&srv_innodb_monitor_mutex);
1485 }
1486 
1487 /*********************************************************************/
1490 extern "C" UNIV_INTERN
1491 os_thread_ret_t
1493 /*===============================*/
1494  void* arg __attribute__((unused)))
1497 {
1498  ib_int64_t sig_count;
1499  double time_elapsed;
1500  time_t current_time;
1501  time_t last_table_monitor_time;
1502  time_t last_tablespace_monitor_time;
1503  time_t last_monitor_time;
1504  ulint mutex_skipped;
1505  ibool last_srv_print_monitor;
1506 
1508 
1509 #ifdef UNIV_DEBUG_THREAD_CREATION
1510  fprintf(stderr, "Lock timeout thread starts, id %lu\n",
1512 #endif /* UNIV_DEBUG_THREAD_CREATION */
1513 
1514 #ifdef UNIV_PFS_THREAD
1515  pfs_register_thread(srv_monitor_thread_key);
1516 #endif /* UNIV_PFS_THREAD */
1517  srv_monitor_active = TRUE;
1518 
1519  UT_NOT_USED(arg);
1520  srv_last_monitor_time = ut_time();
1521  last_table_monitor_time = ut_time();
1522  last_tablespace_monitor_time = ut_time();
1523  last_monitor_time = ut_time();
1524  mutex_skipped = 0;
1525  last_srv_print_monitor = srv_print_innodb_monitor;
1526 loop:
1527  /* Wake up every 5 seconds to see if we need to print
1528  monitor information or if signalled at shutdown. */
1529 
1530  sig_count = os_event_reset(srv_monitor_event);
1531 
1532  os_event_wait_time_low(srv_monitor_event, 5000000, sig_count);
1533 
1534  current_time = ut_time();
1535 
1536  time_elapsed = difftime(current_time, last_monitor_time);
1537 
1538  if (time_elapsed > 15) {
1539  last_monitor_time = ut_time();
1540 
1541  if (srv_print_innodb_monitor) {
1542  /* Reset mutex_skipped counter everytime
1543  srv_print_innodb_monitor changes. This is to
1544  ensure we will not be blocked by lock_sys->mutex
1545  for short duration information printing,
1546  such as requested by sync_array_print_long_waits() */
1547  if (!last_srv_print_monitor) {
1548  mutex_skipped = 0;
1549  last_srv_print_monitor = TRUE;
1550  }
1551 
1552  if (!srv_printf_innodb_monitor(stderr,
1553  MUTEX_NOWAIT(mutex_skipped),
1554  NULL, NULL)) {
1555  mutex_skipped++;
1556  } else {
1557  /* Reset the counter */
1558  mutex_skipped = 0;
1559  }
1560  } else {
1561  last_srv_print_monitor = FALSE;
1562  }
1563 
1564 
1565  /* We don't create the temp files or associated
1566  mutexes in read-only-mode */
1567 
1568  if (!srv_read_only_mode && srv_innodb_status) {
1569  mutex_enter(&srv_monitor_file_mutex);
1570  rewind(srv_monitor_file);
1572  MUTEX_NOWAIT(mutex_skipped),
1573  NULL, NULL)) {
1574  mutex_skipped++;
1575  } else {
1576  mutex_skipped = 0;
1577  }
1578 
1580  mutex_exit(&srv_monitor_file_mutex);
1581  }
1582 
1583  if (srv_print_innodb_tablespace_monitor
1584  && difftime(current_time,
1585  last_tablespace_monitor_time) > 60) {
1586  last_tablespace_monitor_time = ut_time();
1587 
1588  fputs("========================"
1589  "========================\n",
1590  stderr);
1591 
1592  ut_print_timestamp(stderr);
1593 
1594  fputs(" INNODB TABLESPACE MONITOR OUTPUT\n"
1595  "========================"
1596  "========================\n",
1597  stderr);
1598 
1599  fsp_print(0);
1600  fputs("Validating tablespace\n", stderr);
1601  fsp_validate(0);
1602  fputs("Validation ok\n"
1603  "---------------------------------------\n"
1604  "END OF INNODB TABLESPACE MONITOR OUTPUT\n"
1605  "=======================================\n",
1606  stderr);
1607  }
1608 
1609  if (srv_print_innodb_table_monitor
1610  && difftime(current_time, last_table_monitor_time) > 60) {
1611 
1612  last_table_monitor_time = ut_time();
1613 
1614  fprintf(stderr, "Warning: %s\n",
1615  DEPRECATED_MSG_INNODB_TABLE_MONITOR);
1616 
1617  fputs("===========================================\n",
1618  stderr);
1619 
1620  ut_print_timestamp(stderr);
1621 
1622  fputs(" INNODB TABLE MONITOR OUTPUT\n"
1623  "===========================================\n",
1624  stderr);
1625  dict_print();
1626 
1627  fputs("-----------------------------------\n"
1628  "END OF INNODB TABLE MONITOR OUTPUT\n"
1629  "==================================\n",
1630  stderr);
1631 
1632  fprintf(stderr, "Warning: %s\n",
1633  DEPRECATED_MSG_INNODB_TABLE_MONITOR);
1634  }
1635  }
1636 
1638  goto exit_func;
1639  }
1640 
1641  if (srv_print_innodb_monitor
1642  || srv_print_innodb_lock_monitor
1643  || srv_print_innodb_tablespace_monitor
1644  || srv_print_innodb_table_monitor) {
1645  goto loop;
1646  }
1647 
1648  goto loop;
1649 
1650 exit_func:
1651  srv_monitor_active = FALSE;
1652 
1653  /* We count the number of threads in os_thread_exit(). A created
1654  thread should always use that to exit and not use return() to exit. */
1655 
1656  os_thread_exit(NULL);
1657 
1658  OS_THREAD_DUMMY_RETURN;
1659 }
1660 
1661 /*********************************************************************/
1665 extern "C" UNIV_INTERN
1666 os_thread_ret_t
1668 /*=====================================*/
1669  void* arg __attribute__((unused)))
1672 {
1673  /* number of successive fatal timeouts observed */
1674  ulint fatal_cnt = 0;
1675  lsn_t old_lsn;
1676  lsn_t new_lsn;
1677  ib_int64_t sig_count;
1678  /* longest waiting thread for a semaphore */
1680  os_thread_id_t old_waiter = waiter;
1681  /* the semaphore that is being waited for */
1682  const void* sema = NULL;
1683  const void* old_sema = NULL;
1684 
1686 
1687  old_lsn = srv_start_lsn;
1688 
1689 #ifdef UNIV_DEBUG_THREAD_CREATION
1690  fprintf(stderr, "Error monitor thread starts, id %lu\n",
1692 #endif /* UNIV_DEBUG_THREAD_CREATION */
1693 
1694 #ifdef UNIV_PFS_THREAD
1695  pfs_register_thread(srv_error_monitor_thread_key);
1696 #endif /* UNIV_PFS_THREAD */
1697  srv_error_monitor_active = TRUE;
1698 
1699 loop:
1700  /* Try to track a strange bug reported by Harald Fuchs and others,
1701  where the lsn seems to decrease at times */
1702 
1703  new_lsn = log_get_lsn();
1704 
1705  if (new_lsn < old_lsn) {
1706  ut_print_timestamp(stderr);
1707  fprintf(stderr,
1708  " InnoDB: Error: old log sequence number " LSN_PF
1709  " was greater\n"
1710  "InnoDB: than the new log sequence number " LSN_PF "!\n"
1711  "InnoDB: Please submit a bug report"
1712  " to http://bugs.mysql.com\n",
1713  old_lsn, new_lsn);
1714  ut_ad(0);
1715  }
1716 
1717  old_lsn = new_lsn;
1718 
1719  if (difftime(time(NULL), srv_last_monitor_time) > 60) {
1720  /* We referesh InnoDB Monitor values so that averages are
1721  printed from at most 60 last seconds */
1722 
1723  srv_refresh_innodb_monitor_stats();
1724  }
1725 
1726  /* Update the statistics collected for deciding LRU
1727  eviction policy. */
1729 
1730  /* In case mutex_exit is not a memory barrier, it is
1731  theoretically possible some threads are left waiting though
1732  the semaphore is already released. Wake up those threads: */
1733 
1735 
1736  if (sync_array_print_long_waits(&waiter, &sema)
1737  && sema == old_sema && os_thread_eq(waiter, old_waiter)) {
1738  fatal_cnt++;
1739  if (fatal_cnt > 10) {
1740 
1741  fprintf(stderr,
1742  "InnoDB: Error: semaphore wait has lasted"
1743  " > %lu seconds\n"
1744  "InnoDB: We intentionally crash the server,"
1745  " because it appears to be hung.\n",
1746  (ulong) srv_fatal_semaphore_wait_threshold);
1747 
1748  ut_error;
1749  }
1750  } else {
1751  fatal_cnt = 0;
1752  old_waiter = waiter;
1753  old_sema = sema;
1754  }
1755 
1756  /* Flush stderr so that a database user gets the output
1757  to possible MySQL error file */
1758 
1759  fflush(stderr);
1760 
1761  sig_count = os_event_reset(srv_error_event);
1762 
1763  os_event_wait_time_low(srv_error_event, 1000000, sig_count);
1764 
1766 
1767  goto loop;
1768  }
1769 
1770  srv_error_monitor_active = FALSE;
1771 
1772  /* We count the number of threads in os_thread_exit(). A created
1773  thread should always use that to exit and not use return() to exit. */
1774 
1775  os_thread_exit(NULL);
1776 
1777  OS_THREAD_DUMMY_RETURN;
1778 }
1779 
1780 /******************************************************************/
1782 UNIV_INTERN
1783 void
1785 /*========================*/
1786 {
1787  srv_sys->activity_count.inc();
1788 }
1789 
1790 /**********************************************************************/
1795 UNIV_INTERN
1798 /*============================*/
1799 {
1801 
1802  if (srv_read_only_mode) {
1803  return(SRV_NONE);
1804  }
1805 
1807 
1808  for (ulint i = SRV_WORKER; i <= SRV_MASTER; ++i) {
1809  if (srv_sys->n_threads_active[i] != 0) {
1810  ret = static_cast<srv_thread_type>(i);
1811  break;
1812  }
1813  }
1814 
1816 
1817  /* Check only on shutdown. */
1818  if (ret == SRV_NONE
1822 
1823  ret = SRV_PURGE;
1824  }
1825 
1826  return(ret);
1827 }
1828 
1829 /**********************************************************************/
1833 UNIV_INTERN
1834 const char*
1836 /*=======================================*/
1837 {
1838  const char* thread_active = NULL;
1839 
1840  if (srv_read_only_mode) {
1841  return(NULL);
1842  } else if (srv_error_monitor_active) {
1843  thread_active = "srv_error_monitor_thread";
1844  } else if (lock_sys->timeout_thread_active) {
1845  thread_active = "srv_lock_timeout thread";
1846  } else if (srv_monitor_active) {
1847  thread_active = "srv_monitor_thread";
1848  } else if (srv_buf_dump_thread_active) {
1849  thread_active = "buf_dump_thread";
1850  } else if (srv_dict_stats_thread_active) {
1851  thread_active = "dict_stats_thread";
1852  }
1853 
1859 
1860  return(thread_active);
1861 }
1862 
1863 /*******************************************************************/
1869 UNIV_INTERN
1870 void
1872 /*===============================*/
1873 {
1874  if (srv_read_only_mode) {
1875  return;
1876  }
1877 
1879 
1881 
1882  if (srv_sys->n_threads_active[SRV_MASTER] == 0) {
1883  srv_slot_t* slot;
1884 
1886 
1887  slot = &srv_sys->sys_threads[SRV_MASTER_SLOT];
1888 
1889  /* Only if the master thread has been started. */
1890 
1891  if (slot->in_use) {
1892  ut_a(srv_slot_get_type(slot) == SRV_MASTER);
1893 
1894  if (slot->suspended) {
1895 
1896  slot->suspended = FALSE;
1897 
1898  ++srv_sys->n_threads_active[SRV_MASTER];
1899 
1900  os_event_set(slot->event);
1901  }
1902  }
1903 
1905  }
1906 }
1907 
1908 /*******************************************************************/
1914 UNIV_INTERN
1915 void
1917 /*=====================================*/
1918 {
1920 
1922  && srv_sys->n_threads_active[SRV_PURGE] == 0) {
1923 
1925  }
1926 }
1927 
1928 /*******************************************************************/
1930 UNIV_INTERN
1931 void
1933 /*========================*/
1934 {
1936 
1938 
1939  srv_release_threads(SRV_MASTER, 1);
1940 }
1941 
1942 /*******************************************************************/
1946 UNIV_INTERN
1947 ulint
1949 /*========================*/
1950 {
1951  return(srv_sys->activity_count);
1952 }
1953 
1954 /*******************************************************************/
1957 UNIV_INTERN
1958 ibool
1960 /*===============*/
1961  ulint old_activity_count)
1962 {
1963  return(srv_sys->activity_count != old_activity_count);
1964 }
1965 
1966 /********************************************************************/
1971 static
1972 void
1973 srv_sync_log_buffer_in_background(void)
1974 /*===================================*/
1975 {
1976  time_t current_time = time(NULL);
1977 
1978  srv_main_thread_op_info = "flushing log";
1979  if (difftime(current_time, srv_last_log_flush_time)
1980  >= srv_flush_log_at_timeout) {
1982  srv_last_log_flush_time = current_time;
1983  srv_log_writes_and_flush++;
1984  }
1985 }
1986 
1987 /********************************************************************/
1990 static
1991 ulint
1992 srv_master_evict_from_table_cache(
1993 /*==============================*/
1994  ulint pct_check)
1995 {
1996  ulint n_tables_evicted = 0;
1997 
1998  rw_lock_x_lock(&dict_operation_lock);
1999 
2001 
2002  n_tables_evicted = dict_make_room_in_cache(
2003  innobase_get_table_cache_size(), pct_check);
2004 
2006 
2007  rw_lock_x_unlock(&dict_operation_lock);
2008 
2009  return(n_tables_evicted);
2010 }
2011 
2012 /*********************************************************************/
2015 static
2016 void
2017 srv_shutdown_print_master_pending(
2018 /*==============================*/
2019  ib_time_t* last_print_time,
2021  ulint n_tables_to_drop,
2023  ulint n_bytes_merged)
2025 {
2026  ib_time_t current_time;
2027  double time_elapsed;
2028 
2029  current_time = ut_time();
2030  time_elapsed = ut_difftime(current_time, *last_print_time);
2031 
2032  if (time_elapsed > 60) {
2033  *last_print_time = ut_time();
2034 
2035  if (n_tables_to_drop) {
2036  ut_print_timestamp(stderr);
2037  fprintf(stderr, " InnoDB: Waiting for "
2038  "%lu table(s) to be dropped\n",
2039  (ulong) n_tables_to_drop);
2040  }
2041 
2042  /* Check change buffer merge, we only wait for change buffer
2043  merge if it is a slow shutdown */
2044  if (!srv_fast_shutdown && n_bytes_merged) {
2045  ut_print_timestamp(stderr);
2046  fprintf(stderr, " InnoDB: Waiting for change "
2047  "buffer merge to complete\n"
2048  " InnoDB: number of bytes of change buffer "
2049  "just merged: %lu\n",
2050  n_bytes_merged);
2051  }
2052  }
2053 }
2054 
2055 /*********************************************************************/
2062 static
2063 void
2064 srv_master_do_active_tasks(void)
2065 /*============================*/
2066 {
2067  ib_time_t cur_time = ut_time();
2068  ullint counter_time = ut_time_us(NULL);
2069 
2070  /* First do the tasks that we are suppose to do at each
2071  invocation of this function. */
2072 
2073  ++srv_main_active_loops;
2074 
2075  MONITOR_INC(MONITOR_MASTER_ACTIVE_LOOPS);
2076 
2077  /* ALTER TABLE in MySQL requires on Unix that the table handler
2078  can drop tables lazily after there no longer are SELECT
2079  queries to them. */
2080  srv_main_thread_op_info = "doing background drop tables";
2083  MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND, counter_time);
2084 
2085  if (srv_shutdown_state > 0) {
2086  return;
2087  }
2088 
2089  /* make sure that there is enough reusable space in the redo
2090  log files */
2091  srv_main_thread_op_info = "checking free log space";
2092  log_free_check();
2093 
2094  /* Do an ibuf merge */
2095  srv_main_thread_op_info = "doing insert buffer merge";
2096  counter_time = ut_time_us(NULL);
2097  ibuf_contract_in_background(0, FALSE);
2099  MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time);
2100 
2101  /* Flush logs if needed */
2102  srv_main_thread_op_info = "flushing log";
2103  srv_sync_log_buffer_in_background();
2105  MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time);
2106 
2107  /* Now see if various tasks that are performed at defined
2108  intervals need to be performed. */
2109 
2110 #ifdef MEM_PERIODIC_CHECK
2111  /* Check magic numbers of every allocated mem block once in
2112  SRV_MASTER_MEM_VALIDATE_INTERVAL seconds */
2113  if (cur_time % SRV_MASTER_MEM_VALIDATE_INTERVAL == 0) {
2114  mem_validate_all_blocks();
2116  MONITOR_SRV_MEM_VALIDATE_MICROSECOND, counter_time);
2117  }
2118 #endif
2119  if (srv_shutdown_state > 0) {
2120  return;
2121  }
2122 
2123  if (srv_shutdown_state > 0) {
2124  return;
2125  }
2126 
2127  if (cur_time % SRV_MASTER_DICT_LRU_INTERVAL == 0) {
2128  srv_main_thread_op_info = "enforcing dict cache limit";
2129  srv_master_evict_from_table_cache(50);
2131  MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time);
2132  }
2133 
2134  if (srv_shutdown_state > 0) {
2135  return;
2136  }
2137 
2138  /* Make a new checkpoint */
2139  if (cur_time % SRV_MASTER_CHECKPOINT_INTERVAL == 0) {
2140  srv_main_thread_op_info = "making checkpoint";
2141  log_checkpoint(TRUE, FALSE);
2143  MONITOR_SRV_CHECKPOINT_MICROSECOND, counter_time);
2144  }
2145 }
2146 
2147 /*********************************************************************/
2155 static
2156 void
2157 srv_master_do_idle_tasks(void)
2158 /*==========================*/
2159 {
2160  ullint counter_time;
2161 
2162  ++srv_main_idle_loops;
2163 
2164  MONITOR_INC(MONITOR_MASTER_IDLE_LOOPS);
2165 
2166 
2167  /* ALTER TABLE in MySQL requires on Unix that the table handler
2168  can drop tables lazily after there no longer are SELECT
2169  queries to them. */
2170  counter_time = ut_time_us(NULL);
2171  srv_main_thread_op_info = "doing background drop tables";
2174  MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND,
2175  counter_time);
2176 
2177  if (srv_shutdown_state > 0) {
2178  return;
2179  }
2180 
2181  /* make sure that there is enough reusable space in the redo
2182  log files */
2183  srv_main_thread_op_info = "checking free log space";
2184  log_free_check();
2185 
2186  /* Do an ibuf merge */
2187  counter_time = ut_time_us(NULL);
2188  srv_main_thread_op_info = "doing insert buffer merge";
2189  ibuf_contract_in_background(0, TRUE);
2191  MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time);
2192 
2193  if (srv_shutdown_state > 0) {
2194  return;
2195  }
2196 
2197  srv_main_thread_op_info = "enforcing dict cache limit";
2198  srv_master_evict_from_table_cache(100);
2200  MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time);
2201 
2202  /* Flush logs if needed */
2203  srv_sync_log_buffer_in_background();
2205  MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time);
2206 
2207  if (srv_shutdown_state > 0) {
2208  return;
2209  }
2210 
2211  /* Make a new checkpoint */
2212  srv_main_thread_op_info = "making checkpoint";
2213  log_checkpoint(TRUE, FALSE);
2214  MONITOR_INC_TIME_IN_MICRO_SECS(MONITOR_SRV_CHECKPOINT_MICROSECOND,
2215  counter_time);
2216 }
2217 
2218 /*********************************************************************/
2226 static
2227 ibool
2228 srv_master_do_shutdown_tasks(
2229 /*=========================*/
2230  ib_time_t* last_print_time)
2232 {
2233  ulint n_bytes_merged = 0;
2234  ulint n_tables_to_drop = 0;
2235 
2237 
2238  ++srv_main_shutdown_loops;
2239 
2240  ut_a(srv_shutdown_state > 0);
2241 
2242  /* In very fast shutdown none of the following is necessary */
2243  if (srv_fast_shutdown == 2) {
2244  return(FALSE);
2245  }
2246 
2247  /* ALTER TABLE in MySQL requires on Unix that the table handler
2248  can drop tables lazily after there no longer are SELECT
2249  queries to them. */
2250  srv_main_thread_op_info = "doing background drop tables";
2251  n_tables_to_drop = row_drop_tables_for_mysql_in_background();
2252 
2253  /* make sure that there is enough reusable space in the redo
2254  log files */
2255  srv_main_thread_op_info = "checking free log space";
2256  log_free_check();
2257 
2258  /* In case of normal shutdown we don't do ibuf merge or purge */
2259  if (srv_fast_shutdown == 1) {
2260  goto func_exit;
2261  }
2262 
2263  /* Do an ibuf merge */
2264  srv_main_thread_op_info = "doing insert buffer merge";
2265  n_bytes_merged = ibuf_contract_in_background(0, TRUE);
2266 
2267  /* Flush logs if needed */
2268  srv_sync_log_buffer_in_background();
2269 
2270 func_exit:
2271  /* Make a new checkpoint about once in 10 seconds */
2272  srv_main_thread_op_info = "making checkpoint";
2273  log_checkpoint(TRUE, FALSE);
2274 
2275  /* Print progress message every 60 seconds during shutdown */
2276  if (srv_shutdown_state > 0 && srv_print_verbose_log) {
2277  srv_shutdown_print_master_pending(
2278  last_print_time, n_tables_to_drop, n_bytes_merged);
2279  }
2280 
2281  return(n_bytes_merged || n_tables_to_drop);
2282 }
2283 
2284 /*********************************************************************/
2288 static
2289 void
2290 srv_master_sleep(void)
2291 /*==================*/
2292 {
2293  srv_main_thread_op_info = "sleeping";
2294  os_thread_sleep(1000000);
2295  srv_main_thread_op_info = "";
2296 }
2297 
2298 /*********************************************************************/
2301 extern "C" UNIV_INTERN
2302 os_thread_ret_t
2304 /*==============================*/
2305  void* arg __attribute__((unused)))
2308 {
2309  srv_slot_t* slot;
2310  ulint old_activity_count = srv_get_activity_count();
2311  ib_time_t last_print_time;
2312 
2314 
2315 #ifdef UNIV_DEBUG_THREAD_CREATION
2316  fprintf(stderr, "Master thread starts, id %lu\n",
2318 #endif /* UNIV_DEBUG_THREAD_CREATION */
2319 
2320 #ifdef UNIV_PFS_THREAD
2321  pfs_register_thread(srv_master_thread_key);
2322 #endif /* UNIV_PFS_THREAD */
2323 
2324  srv_main_thread_process_no = os_proc_get_number();
2325  srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2326 
2327  slot = srv_reserve_slot(SRV_MASTER);
2328  ut_a(slot == srv_sys->sys_threads);
2329 
2330  last_print_time = ut_time();
2331 loop:
2333  goto suspend_thread;
2334  }
2335 
2337 
2338  srv_master_sleep();
2339 
2340  MONITOR_INC(MONITOR_MASTER_THREAD_SLEEP);
2341 
2342  if (srv_check_activity(old_activity_count)) {
2343  old_activity_count = srv_get_activity_count();
2344  srv_master_do_active_tasks();
2345  } else {
2346  srv_master_do_idle_tasks();
2347  }
2348  }
2349 
2350  while (srv_master_do_shutdown_tasks(&last_print_time)) {
2351 
2352  /* Shouldn't loop here in case of very fast shutdown */
2353  ut_ad(srv_fast_shutdown < 2);
2354  }
2355 
2356 suspend_thread:
2357  srv_main_thread_op_info = "suspending";
2358 
2359  srv_suspend_thread(slot);
2360 
2361  /* DO NOT CHANGE THIS STRING. innobase_start_or_create_for_mysql()
2362  waits for database activity to die down when converting < 4.1.x
2363  databases, and relies on this string being exactly as it is. InnoDB
2364  manual also mentions this string in several places. */
2365  srv_main_thread_op_info = "waiting for server activity";
2366 
2367  os_event_wait(slot->event);
2368 
2370  os_thread_exit(NULL);
2371  }
2372 
2373  goto loop;
2374 
2375  OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
2376 }
2377 
2378 /*********************************************************************/
2381 static
2382 bool
2383 srv_purge_should_exit(
2384 /*==============*/
2385  ulint n_purged)
2386 {
2387  switch (srv_shutdown_state) {
2388  case SRV_SHUTDOWN_NONE:
2389  /* Normal operation. */
2390  break;
2391 
2392  case SRV_SHUTDOWN_CLEANUP:
2394  /* Exit unless slow shutdown requested or all done. */
2395  return(srv_fast_shutdown != 0 || n_purged == 0);
2396 
2399  ut_error;
2400  }
2401 
2402  return(false);
2403 }
2404 
2405 /*********************************************************************/
2408 static
2409 bool
2410 srv_task_execute(void)
2411 /*==================*/
2412 {
2413  que_thr_t* thr = NULL;
2414 
2417 
2418  mutex_enter(&srv_sys->tasks_mutex);
2419 
2420  if (UT_LIST_GET_LEN(srv_sys->tasks) > 0) {
2421 
2422  thr = UT_LIST_GET_FIRST(srv_sys->tasks);
2423 
2424  ut_a(que_node_get_type(thr->child) == QUE_NODE_PURGE);
2425 
2426  UT_LIST_REMOVE(queue, srv_sys->tasks, thr);
2427  }
2428 
2429  mutex_exit(&srv_sys->tasks_mutex);
2430 
2431  if (thr != NULL) {
2432 
2433  que_run_threads(thr);
2434 
2435  os_atomic_inc_ulint(
2437  }
2438 
2439  return(thr != NULL);
2440 }
2441 
2442 /*********************************************************************/
2445 extern "C" UNIV_INTERN
2446 os_thread_ret_t
2448 /*==============================*/
2449  void* arg __attribute__((unused)))
2451 {
2452  srv_slot_t* slot;
2453 
2456 
2457 #ifdef UNIV_DEBUG_THREAD_CREATION
2458  ut_print_timestamp(stderr);
2459  fprintf(stderr, " InnoDB: worker thread starting, id %lu\n",
2461 #endif /* UNIV_DEBUG_THREAD_CREATION */
2462 
2463  slot = srv_reserve_slot(SRV_WORKER);
2464 
2465  ut_a(srv_n_purge_threads > 1);
2466 
2468 
2469  ut_a(srv_sys->n_threads_active[SRV_WORKER] < srv_n_purge_threads);
2470 
2472 
2473  /* We need to ensure that the worker threads exit after the
2474  purge coordinator thread. Otherwise the purge coordinaor can
2475  end up waiting forever in trx_purge_wait_for_workers_to_complete() */
2476 
2477  do {
2478  srv_suspend_thread(slot);
2479 
2480  os_event_wait(slot->event);
2481 
2482  if (srv_task_execute()) {
2483 
2484  /* If there are tasks in the queue, wakeup
2485  the purge coordinator thread. */
2486 
2488  }
2489 
2490  /* Note: we are checking the state without holding the
2491  purge_sys->latch here. */
2492  } while (purge_sys->state != PURGE_STATE_EXIT);
2493 
2494  srv_free_slot(slot);
2495 
2496  rw_lock_x_lock(&purge_sys->latch);
2497 
2498  ut_a(!purge_sys->running);
2501 
2502  rw_lock_x_unlock(&purge_sys->latch);
2503 
2504 #ifdef UNIV_DEBUG_THREAD_CREATION
2505  ut_print_timestamp(stderr);
2506  fprintf(stderr, " InnoDB: Purge worker thread exiting, id %lu\n",
2508 #endif /* UNIV_DEBUG_THREAD_CREATION */
2509 
2510  /* We count the number of threads in os_thread_exit(). A created
2511  thread should always use that to exit and not use return() to exit. */
2512  os_thread_exit(NULL);
2513 
2514  OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
2515 }
2516 
2517 /*********************************************************************/
2520 static
2521 ulint
2522 srv_do_purge(
2523 /*=========*/
2524  ulint n_threads,
2525  ulint* n_total_purged)
2526 {
2527  ulint n_pages_purged;
2528 
2529  static ulint count = 0;
2530  static ulint n_use_threads = 0;
2531  static ulint rseg_history_len = 0;
2532  ulint old_activity_count = srv_get_activity_count();
2533 
2534  ut_a(n_threads > 0);
2536 
2537  /* Purge until there are no more records to purge and there is
2538  no change in configuration or server state. If the user has
2539  configured more than one purge thread then we treat that as a
2540  pool of threads and only use the extra threads if purge can't
2541  keep up with updates. */
2542 
2543  if (n_use_threads == 0) {
2544  n_use_threads = n_threads;
2545  }
2546 
2547  do {
2548  if (trx_sys->rseg_history_len > rseg_history_len
2549  || (srv_max_purge_lag > 0
2550  && rseg_history_len > srv_max_purge_lag)) {
2551 
2552  /* History length is now longer than what it was
2553  when we took the last snapshot. Use more threads. */
2554 
2555  if (n_use_threads < n_threads) {
2556  ++n_use_threads;
2557  }
2558 
2559  } else if (srv_check_activity(old_activity_count)
2560  && n_use_threads > 1) {
2561 
2562  /* History length same or smaller since last snapshot,
2563  use fewer threads. */
2564 
2565  --n_use_threads;
2566 
2567  old_activity_count = srv_get_activity_count();
2568  }
2569 
2570  /* Ensure that the purge threads are less than what
2571  was configured. */
2572 
2573  ut_a(n_use_threads > 0);
2574  ut_a(n_use_threads <= n_threads);
2575 
2576  /* Take a snapshot of the history list before purge. */
2577  if ((rseg_history_len = trx_sys->rseg_history_len) == 0) {
2578  break;
2579  }
2580 
2581  n_pages_purged = trx_purge(
2582  n_use_threads, srv_purge_batch_size, false);
2583 
2584  if (!(count++ % TRX_SYS_N_RSEGS)) {
2585  /* Force a truncate of the history list. */
2586  n_pages_purged += trx_purge(
2587  1, srv_purge_batch_size, true);
2588  }
2589 
2590  *n_total_purged += n_pages_purged;
2591 
2592  } while (!srv_purge_should_exit(n_pages_purged) && n_pages_purged > 0);
2593 
2594  return(rseg_history_len);
2595 }
2596 
2597 /*********************************************************************/
2599 static
2600 void
2601 srv_purge_coordinator_suspend(
2602 /*==========================*/
2603  srv_slot_t* slot,
2605  ulint rseg_history_len)
2607 {
2609  ut_a(slot->type == SRV_PURGE);
2610 
2611  bool stop = false;
2612 
2614  static const ulint SRV_PURGE_MAX_TIMEOUT = 10000;
2615 
2616  ib_int64_t sig_count = srv_suspend_thread(slot);
2617 
2618  do {
2619  ulint ret;
2620 
2621  rw_lock_x_lock(&purge_sys->latch);
2622 
2623  purge_sys->running = false;
2624 
2625  rw_lock_x_unlock(&purge_sys->latch);
2626 
2627  /* We don't wait right away on the the non-timed wait because
2628  we want to signal the thread that wants to suspend purge. */
2629 
2630  if (stop) {
2631  os_event_wait_low(slot->event, sig_count);
2632  ret = 0;
2633  } else if (rseg_history_len <= trx_sys->rseg_history_len) {
2634  ret = os_event_wait_time_low(
2635  slot->event, SRV_PURGE_MAX_TIMEOUT, sig_count);
2636  } else {
2637  /* We don't want to waste time waiting, if the
2638  history list increased by the time we got here,
2639  unless purge has been stopped. */
2640  ret = 0;
2641  }
2642 
2644 
2645  /* The thread can be in state !suspended after the timeout
2646  but before this check if another thread sent a wakeup signal. */
2647 
2648  if (slot->suspended) {
2649  slot->suspended = FALSE;
2650  ++srv_sys->n_threads_active[slot->type];
2651  ut_a(srv_sys->n_threads_active[slot->type] == 1);
2652  }
2653 
2655 
2656  sig_count = srv_suspend_thread(slot);
2657 
2658  rw_lock_x_lock(&purge_sys->latch);
2659 
2660  stop = (purge_sys->state == PURGE_STATE_STOP);
2661 
2662  if (!stop) {
2663  ut_a(purge_sys->n_stop == 0);
2664  purge_sys->running = true;
2665  } else {
2666  ut_a(purge_sys->n_stop > 0);
2667 
2668  /* Signal that we are suspended. */
2670  }
2671 
2672  rw_lock_x_unlock(&purge_sys->latch);
2673 
2674  if (ret == OS_SYNC_TIME_EXCEEDED) {
2675 
2676  /* No new records added since wait started then simply
2677  wait for new records. The magic number 5000 is an
2678  approximation for the case where we have cached UNDO
2679  log records which prevent truncate of the UNDO
2680  segments. */
2681 
2682  if (rseg_history_len == trx_sys->rseg_history_len
2683  && trx_sys->rseg_history_len < 5000) {
2684 
2685  stop = true;
2686  }
2687  }
2688 
2689  } while (stop);
2690 
2692 
2693  if (slot->suspended) {
2694  slot->suspended = FALSE;
2695  ++srv_sys->n_threads_active[slot->type];
2696  ut_a(srv_sys->n_threads_active[slot->type] == 1);
2697  }
2698 
2700 }
2701 
2702 /*********************************************************************/
2705 extern "C" UNIV_INTERN
2706 os_thread_ret_t
2708 /*=========================================*/
2709  void* arg __attribute__((unused)))
2711 {
2712  srv_slot_t* slot;
2713  ulint n_total_purged = ULINT_UNDEFINED;
2714 
2716  ut_a(srv_n_purge_threads >= 1);
2719 
2720  rw_lock_x_lock(&purge_sys->latch);
2721 
2722  purge_sys->running = true;
2724 
2725  rw_lock_x_unlock(&purge_sys->latch);
2726 
2727 #ifdef UNIV_PFS_THREAD
2728  pfs_register_thread(srv_purge_thread_key);
2729 #endif /* UNIV_PFS_THREAD */
2730 
2731 #ifdef UNIV_DEBUG_THREAD_CREATION
2732  ut_print_timestamp(stderr);
2733  fprintf(stderr, " InnoDB: Purge coordinator thread created, id %lu\n",
2735 #endif /* UNIV_DEBUG_THREAD_CREATION */
2736 
2737  slot = srv_reserve_slot(SRV_PURGE);
2738 
2739  ulint rseg_history_len = trx_sys->rseg_history_len;
2740 
2741  do {
2742  /* If there are no records to purge or the last
2743  purge didn't purge any records then wait for activity. */
2744 
2746  || n_total_purged == 0) {
2747 
2748  srv_purge_coordinator_suspend(slot, rseg_history_len);
2749  }
2750 
2751  if (srv_purge_should_exit(n_total_purged)) {
2752  ut_a(!slot->suspended);
2753  break;
2754  }
2755 
2756  n_total_purged = 0;
2757 
2758  rseg_history_len = srv_do_purge(
2759  srv_n_purge_threads, &n_total_purged);
2760 
2761  } while (!srv_purge_should_exit(n_total_purged));
2762 
2763  /* Ensure that we don't jump out of the loop unless the
2764  exit condition is satisfied. */
2765 
2766  ut_a(srv_purge_should_exit(n_total_purged));
2767 
2768  ulint n_pages_purged = ULINT_MAX;
2769 
2770  /* Ensure that all records are purged if it is not a fast shutdown.
2771  This covers the case where a record can be added after we exit the
2772  loop above. */
2773  while (srv_fast_shutdown == 0 && n_pages_purged > 0) {
2774  n_pages_purged = trx_purge(1, srv_purge_batch_size, false);
2775  }
2776 
2777  /* Force a truncate of the history list. */
2778  n_pages_purged = trx_purge(1, srv_purge_batch_size, true);
2779  ut_a(n_pages_purged == 0 || srv_fast_shutdown != 0);
2780 
2781  /* The task queue should always be empty, independent of fast
2782  shutdown state. */
2784 
2785  srv_free_slot(slot);
2786 
2787  /* Note that we are shutting down. */
2788  rw_lock_x_lock(&purge_sys->latch);
2789 
2791 
2792  purge_sys->running = false;
2793 
2794  rw_lock_x_unlock(&purge_sys->latch);
2795 
2796 #ifdef UNIV_DEBUG_THREAD_CREATION
2797  ut_print_timestamp(stderr);
2798  fprintf(stderr, " InnoDB: Purge coordinator exiting, id %lu\n",
2800 #endif /* UNIV_DEBUG_THREAD_CREATION */
2801 
2802  /* Ensure that all the worker threads quit. */
2803  if (srv_n_purge_threads > 1) {
2804  srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1);
2805  }
2806 
2807  /* We count the number of threads in os_thread_exit(). A created
2808  thread should always use that to exit and not use return() to exit. */
2809  os_thread_exit(NULL);
2810 
2811  OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
2812 }
2813 
2814 /**********************************************************************/
2817 UNIV_INTERN
2818 void
2820 /*=====================*/
2821  que_thr_t* thr)
2822 {
2824  mutex_enter(&srv_sys->tasks_mutex);
2825 
2826  UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
2827 
2828  mutex_exit(&srv_sys->tasks_mutex);
2829 
2831 }
2832 
2833 /**********************************************************************/
2836 UNIV_INTERN
2837 ulint
2839 /*===========================*/
2840 {
2841  ulint n_tasks;
2842 
2844 
2845  mutex_enter(&srv_sys->tasks_mutex);
2846 
2847  n_tasks = UT_LIST_GET_LEN(srv_sys->tasks);
2848 
2849  mutex_exit(&srv_sys->tasks_mutex);
2850 
2851  return(n_tasks);
2852 }
2853 
2854 /**********************************************************************/
2856 UNIV_INTERN
2857 void
2859 /*==================*/
2860 {
2862 
2864 
2866 
2867  if (srv_n_purge_threads > 1) {
2868  ulint n_workers = srv_n_purge_threads - 1;
2869 
2870  srv_release_threads(SRV_WORKER, n_workers);
2871  }
2872  }
2873 }
2874