~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/srv/srv0srv.c

  • Committer: Brian Aker
  • Date: 2009-02-10 00:14:40 UTC
  • Revision ID: brian@tangent.org-20090210001440-qjg8eofh3h93064b
Adding Multi-threaded Scheduler into the system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1995, 2010, Innobase Oy. 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., 51 Franklin
30
 
St, Fifth Floor, Boston, MA 02110-1301 USA
31
 
 
32
 
*****************************************************************************/
33
 
 
34
 
/**************************************************//**
35
 
@file srv/srv0srv.c
 
1
/******************************************************
36
2
The database server main program
37
3
 
38
4
NOTE: SQL Server 7 uses something which the documentation
54
20
Another possibility could be to use some very fast user space
55
21
thread library. This might confuse NT though.
56
22
 
 
23
(c) 1995 Innobase Oy
 
24
 
57
25
Created 10/8/1995 Heikki Tuuri
58
26
*******************************************************/
59
 
 
60
27
/* Dummy comment */
61
28
#include "srv0srv.h"
62
29
 
63
 
#include <drizzled/error.h>
64
 
#include <drizzled/errmsg_print.h>
65
 
 
66
30
#include "ut0mem.h"
67
31
#include "ut0ut.h"
68
32
#include "os0proc.h"
71
35
#include "sync0sync.h"
72
36
#include "thr0loc.h"
73
37
#include "que0que.h"
 
38
#include "srv0que.h"
74
39
#include "log0recv.h"
75
40
#include "pars0pars.h"
76
41
#include "usr0sess.h"
86
51
#include "row0mysql.h"
87
52
#include "ha_prototypes.h"
88
53
#include "trx0i_s.h"
89
 
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
90
54
 
91
55
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
92
56
affects only FOREIGN KEY definition parsing */
103
67
in microseconds, in order to reduce the lagging of the purge thread. */
104
68
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
105
69
 
106
 
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
107
 
UNIV_INTERN ibool       srv_monitor_active = FALSE;
 
70
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
108
71
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
109
72
 
110
73
UNIV_INTERN const char* srv_main_thread_op_info = "";
111
74
 
 
75
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
 
76
UNIV_INTERN const char  srv_mysql50_table_name_prefix[9] = "#mysql50#";
 
77
 
112
78
/* Server parameters which are read from the initfile */
113
79
 
114
80
/* The following three are dir paths which are catenated before file
119
85
UNIV_INTERN char*       srv_arch_dir    = NULL;
120
86
#endif /* UNIV_LOG_ARCHIVE */
121
87
 
122
 
/** store to its own file each table created by an user; data
 
88
/* store to its own file each table created by an user; data
123
89
dictionary tables are in the system tablespace 0 */
124
90
UNIV_INTERN my_bool     srv_file_per_table;
125
 
/** The file format to use on new *.ibd files. */
 
91
/* The file format to use on new *.ibd files. */
126
92
UNIV_INTERN ulint       srv_file_format = 0;
127
 
/** Whether to check file format during startup.  A value of
 
93
/* Whether to check file format during startup a value of 
128
94
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
129
95
set it to the highest format we support. */
130
 
UNIV_INTERN ulint       srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
 
96
UNIV_INTERN ulint       srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
131
97
 
132
98
#if DICT_TF_FORMAT_51
133
99
# error "DICT_TF_FORMAT_51 must be 0!"
134
100
#endif
135
 
/** Place locks to records only i.e. do not use next-key locking except
 
101
/* Place locks to records only i.e. do not use next-key locking except
136
102
on duplicate key checking and foreign key checking */
137
103
UNIV_INTERN ibool       srv_locks_unsafe_for_binlog = FALSE;
138
104
 
139
 
/* If this flag is TRUE, then we will use the native aio of the
140
 
OS (provided we compiled Innobase with it in), otherwise we will
141
 
use simulated aio we build below with threads.
142
 
Currently we support native aio on windows and linux */
143
 
UNIV_INTERN my_bool     srv_use_native_aio = TRUE;
144
 
 
145
 
#ifdef __WIN__
146
 
/* Windows native condition variables. We use runtime loading / function
147
 
pointers, because they are not available on Windows Server 2003 and
148
 
Windows XP/2000.
149
 
 
150
 
We use condition for events on Windows if possible, even if os_event
151
 
resembles Windows kernel event object well API-wise. The reason is
152
 
performance, kernel objects are heavyweights and WaitForSingleObject() is a
153
 
performance killer causing calling thread to context switch. Besides, Innodb
154
 
is preallocating large number (often millions) of os_events. With kernel event
155
 
objects it takes a big chunk out of non-paged pool, which is better suited
156
 
for tasks like IO than for storing idle event objects. */
157
 
UNIV_INTERN ibool       srv_use_native_conditions = FALSE;
158
 
#endif /* __WIN__ */
159
 
 
160
105
UNIV_INTERN ulint       srv_n_data_files = 0;
161
106
UNIV_INTERN char**      srv_data_file_names = NULL;
162
107
/* size in database pages */
169
114
UNIV_INTERN ulint       srv_last_file_size_max  = 0;
170
115
/* If the last data file is auto-extended, we add this
171
116
many pages to it at a time */
172
 
UNIV_INTERN unsigned int srv_auto_extend_increment = 8;
 
117
UNIV_INTERN ulong       srv_auto_extend_increment = 8;
173
118
UNIV_INTERN ulint*      srv_data_file_is_raw_partition = NULL;
174
119
 
175
120
/* If the following is TRUE we do not allow inserts etc. This protects
187
132
UNIV_INTERN ulint       srv_log_buffer_size     = ULINT_MAX;
188
133
UNIV_INTERN ulong       srv_flush_log_at_trx_commit = 1;
189
134
 
190
 
/* Try to flush dirty pages so as to avoid IO bursts at
191
 
the checkpoints. */
192
 
UNIV_INTERN bool        srv_adaptive_flushing   = TRUE;
193
 
 
194
 
/** Maximum number of times allowed to conditionally acquire
195
 
mutex before switching to blocking wait on the mutex */
196
 
#define MAX_MUTEX_NOWAIT        20
197
 
 
198
 
/** Check whether the number of failed nonblocking mutex
199
 
acquisition attempts exceeds maximum allowed value. If so,
200
 
srv_printf_innodb_monitor() will request mutex acquisition
201
 
with mutex_enter(), which will wait until it gets the mutex. */
202
 
#define MUTEX_NOWAIT(mutex_skipped)     ((mutex_skipped) < MAX_MUTEX_NOWAIT)
203
 
 
204
 
/** The sort order table of the MySQL latin1_swedish_ci character set
 
135
/* The sort order table of the MySQL latin1_swedish_ci character set
205
136
collation */
206
 
#if defined(BUILD_DRIZZLE)
207
 
const byte      srv_latin1_ordering[256]        /* The sort order table of the latin1
 
137
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
208
138
                                        character set. The following table is
209
139
                                        the MySQL order as of Feb 10th, 2002 */
210
140
= {
241
171
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xF7
242
172
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
243
173
};
244
 
#else
245
 
UNIV_INTERN const byte*        srv_latin1_ordering;
246
 
#endif /* BUILD_DRIZZLE */
247
 
 
248
 
 
249
 
/* use os/external memory allocator */
250
 
UNIV_INTERN my_bool     srv_use_sys_malloc      = TRUE;
 
174
 
 
175
 
251
176
/* requested size in kilobytes */
252
 
UNIV_INTERN ulint       srv_buf_pool_size       = ULINT_MAX;
253
 
/* requested number of buffer pool instances */
254
 
UNIV_INTERN ulint       srv_buf_pool_instances  = 1;
 
177
UNIV_INTERN ulong       srv_buf_pool_size       = ULINT_MAX;
255
178
/* previously requested size */
256
 
UNIV_INTERN ulint       srv_buf_pool_old_size;
 
179
UNIV_INTERN ulong       srv_buf_pool_old_size;
257
180
/* current size in kilobytes */
258
 
UNIV_INTERN ulint       srv_buf_pool_curr_size  = 0;
 
181
UNIV_INTERN ulong       srv_buf_pool_curr_size  = 0;
259
182
/* size in bytes */
260
183
UNIV_INTERN ulint       srv_mem_pool_size       = ULINT_MAX;
261
184
UNIV_INTERN ulint       srv_lock_table_size     = ULINT_MAX;
262
185
 
263
 
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
264
 
instead. */
265
186
UNIV_INTERN ulint       srv_n_file_io_threads   = ULINT_MAX;
266
 
UNIV_INTERN ulint       srv_n_read_io_threads   = ULINT_MAX;
267
 
UNIV_INTERN ulint       srv_n_write_io_threads  = ULINT_MAX;
268
 
 
269
 
/* User settable value of the number of pages that must be present
270
 
in the buffer cache and accessed sequentially for InnoDB to trigger a
271
 
readahead request. */
272
 
UNIV_INTERN ulong       srv_read_ahead_threshold        = 56;
273
187
 
274
188
#ifdef UNIV_LOG_ARCHIVE
275
189
UNIV_INTERN ibool               srv_log_archive_on      = FALSE;
293
207
 
294
208
UNIV_INTERN ulint       srv_max_n_open_files      = 300;
295
209
 
296
 
/* Number of IO operations per second the server can do */
297
 
UNIV_INTERN ulong       srv_io_capacity         = 200;
298
 
 
299
210
/* The InnoDB main thread tries to keep the ratio of modified pages
300
211
in the buffer pool to all database pages in the buffer pool smaller than
301
212
the following number. But it is not guaranteed that the value stays below
302
213
that during a time of heavy update/insert activity. */
303
214
 
304
 
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 75;
305
 
 
306
 
/* the number of purge threads to use from the worker pool (currently 0 or 1).*/
307
 
UNIV_INTERN ulong srv_n_purge_threads = 0;
308
 
 
309
 
/* the number of records to purge in one batch */
310
 
UNIV_INTERN ulong srv_purge_batch_size = 20;
 
215
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 90;
311
216
 
312
217
/* variable counts amount of data read in total (in bytes) */
313
218
UNIV_INTERN ulint srv_data_read = 0;
351
256
pool to the disk */
352
257
UNIV_INTERN ulint srv_buf_pool_flushed = 0;
353
258
 
354
 
/** Number of buffer pool reads that led to the
 
259
/* variable to count the number of buffer pool reads that led to the
355
260
reading of a disk page */
356
261
UNIV_INTERN ulint srv_buf_pool_reads = 0;
357
262
 
 
263
/* variable to count the number of sequential read-aheads */
 
264
UNIV_INTERN ulint srv_read_ahead_seq = 0;
 
265
 
 
266
/* variable to count the number of random read-aheads */
 
267
UNIV_INTERN ulint srv_read_ahead_rnd = 0;
 
268
 
358
269
/* structure to pass status variables to MySQL */
359
270
UNIV_INTERN export_struc export_vars;
360
271
 
378
289
concurrency check. */
379
290
 
380
291
UNIV_INTERN ulong       srv_thread_concurrency  = 0;
 
292
UNIV_INTERN ulong       srv_commit_concurrency  = 0;
381
293
 
382
294
/* this mutex protects srv_conc data structures */
383
295
UNIV_INTERN os_fast_mutex_t     srv_conc_mutex;
384
 
/* number of transactions that have declared_to_be_inside_innodb set.
385
 
It used to be a non-error for this value to drop below zero temporarily.
386
 
This is no longer true. We'll, however, keep the lint datatype to add
387
 
assertions to catch any corner cases that we may have missed. */
 
296
/* number of OS threads currently inside InnoDB; it is not an error if
 
297
this drops temporarily below zero because we do not demand that every
 
298
thread increments this, but a thread waiting for a lock decrements
 
299
this temporarily */
388
300
UNIV_INTERN lint        srv_conc_n_threads      = 0;
389
301
/* number of OS threads waiting in the FIFO for a permission to enter
390
302
InnoDB */
392
304
 
393
305
typedef struct srv_conc_slot_struct     srv_conc_slot_t;
394
306
struct srv_conc_slot_struct{
395
 
        os_event_t                      event;          /*!< event to wait */
396
 
        ibool                           reserved;       /*!< TRUE if slot
 
307
        os_event_t                      event;          /* event to wait */
 
308
        ibool                           reserved;       /* TRUE if slot
397
309
                                                        reserved */
398
 
        ibool                           wait_ended;     /*!< TRUE when another
 
310
        ibool                           wait_ended;     /* TRUE when another
399
311
                                                        thread has already set
400
312
                                                        the event and the
401
313
                                                        thread in this slot is
402
314
                                                        free to proceed; but
403
315
                                                        reserved may still be
404
316
                                                        TRUE at that point */
405
 
        UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /*!< queue node */
 
317
        UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
406
318
};
407
319
 
408
320
/* queue of threads waiting to get in */
431
343
UNIV_INTERN ibool       srv_use_doublewrite_buf = TRUE;
432
344
UNIV_INTERN ibool       srv_use_checksums = TRUE;
433
345
 
 
346
UNIV_INTERN ibool       srv_set_thread_priorities = TRUE;
 
347
UNIV_INTERN int srv_query_thread_priority = 0;
 
348
 
434
349
UNIV_INTERN ulong       srv_replication_delay           = 0;
435
350
 
436
351
/*-------------------------------------------*/
437
 
UNIV_INTERN ulong       srv_n_spin_wait_rounds  = 30;
 
352
UNIV_INTERN ulong       srv_n_spin_wait_rounds  = 20;
438
353
UNIV_INTERN ulong       srv_n_free_tickets_to_enter = 500;
439
354
UNIV_INTERN ulong       srv_thread_sleep_delay = 10000;
440
 
UNIV_INTERN ulong       srv_spin_wait_delay     = 6;
 
355
UNIV_INTERN ulint       srv_spin_wait_delay     = 5;
441
356
UNIV_INTERN ibool       srv_priority_boost      = TRUE;
442
357
 
443
358
#ifdef UNIV_DEBUG
452
367
UNIV_INTERN ulint               srv_n_rows_updated              = 0;
453
368
UNIV_INTERN ulint               srv_n_rows_deleted              = 0;
454
369
UNIV_INTERN ulint               srv_n_rows_read                 = 0;
455
 
 
 
370
#ifndef UNIV_HOTBACKUP
456
371
static ulint    srv_n_rows_inserted_old         = 0;
457
372
static ulint    srv_n_rows_updated_old          = 0;
458
373
static ulint    srv_n_rows_deleted_old          = 0;
459
374
static ulint    srv_n_rows_read_old             = 0;
 
375
#endif /* !UNIV_HOTBACKUP */
460
376
 
461
377
UNIV_INTERN ulint               srv_n_lock_wait_count           = 0;
462
378
UNIV_INTERN ulint               srv_n_lock_wait_current_count   = 0;
463
379
UNIV_INTERN ib_int64_t  srv_n_lock_wait_time            = 0;
464
380
UNIV_INTERN ulint               srv_n_lock_max_wait_time        = 0;
465
381
 
466
 
UNIV_INTERN ulint               srv_truncated_status_writes     = 0;
467
382
 
468
383
/*
469
384
  Set the following to 0 if you want InnoDB to write messages on
487
402
 
488
403
/* Mutex for locking srv_monitor_file */
489
404
UNIV_INTERN mutex_t     srv_monitor_file_mutex;
490
 
 
491
 
#ifdef UNIV_PFS_MUTEX
492
 
/* Key to register kernel_mutex with performance schema */
493
 
UNIV_INTERN mysql_pfs_key_t     kernel_mutex_key;
494
 
/* Key to protect writing the commit_id to the sys header */
495
 
UNIV_INTERN mysql_pfs_key_t     commit_id_mutex_key;
496
 
/* Key to register srv_innodb_monitor_mutex with performance schema */
497
 
UNIV_INTERN mysql_pfs_key_t     srv_innodb_monitor_mutex_key;
498
 
/* Key to register srv_monitor_file_mutex with performance schema */
499
 
UNIV_INTERN mysql_pfs_key_t     srv_monitor_file_mutex_key;
500
 
/* Key to register srv_dict_tmpfile_mutex with performance schema */
501
 
UNIV_INTERN mysql_pfs_key_t     srv_dict_tmpfile_mutex_key;
502
 
/* Key to register the mutex with performance schema */
503
 
UNIV_INTERN mysql_pfs_key_t     srv_misc_tmpfile_mutex_key;
504
 
#endif /* UNIV_PFS_MUTEX */
505
 
 
506
405
/* Temporary file for innodb monitor output */
507
406
UNIV_INTERN FILE*       srv_monitor_file;
508
407
/* Mutex for locking srv_dict_tmpfile.
521
420
UNIV_INTERN ulint       srv_main_thread_process_no      = 0;
522
421
UNIV_INTERN ulint       srv_main_thread_id              = 0;
523
422
 
524
 
/* The following count work done by srv_master_thread. */
525
 
 
526
 
/* Iterations by the 'once per second' loop. */
527
 
static ulint   srv_main_1_second_loops          = 0;
528
 
/* Calls to sleep by the 'once per second' loop. */
529
 
static ulint   srv_main_sleeps                  = 0;
530
 
/* Iterations by the 'once per 10 seconds' loop. */
531
 
static ulint   srv_main_10_second_loops         = 0;
532
 
/* Iterations of the loop bounded by the 'background_loop' label. */
533
 
static ulint   srv_main_background_loops        = 0;
534
 
/* Iterations of the loop bounded by the 'flush_loop' label. */
535
 
static ulint   srv_main_flush_loops             = 0;
536
 
/* Log writes involving flush. */
537
 
static ulint   srv_log_writes_and_flush         = 0;
538
 
 
539
 
/* This is only ever touched by the master thread. It records the
540
 
time when the last flush of log file has happened. The master
541
 
thread ensures that we flush the log files at least once per
542
 
second. */
543
 
static time_t   srv_last_log_flush_time;
544
 
 
545
 
/* The master thread performs various tasks based on the current
546
 
state of IO activity and the level of IO utilization is past
547
 
intervals. Following macros define thresholds for these conditions. */
548
 
#define SRV_PEND_IO_THRESHOLD   (PCT_IO(3))
549
 
#define SRV_RECENT_IO_ACTIVITY  (PCT_IO(5))
550
 
#define SRV_PAST_IO_ACTIVITY    (PCT_IO(200))
551
 
 
552
423
/*
553
424
        IMPLEMENTATION OF THE SERVER MAIN PROGRAM
554
425
        =========================================
719
590
 
720
591
/* Thread slot in the thread table */
721
592
struct srv_slot_struct{
722
 
        os_thread_id_t  id;             /*!< thread id */
723
 
        os_thread_t     handle;         /*!< thread handle */
724
 
        unsigned        type:3;         /*!< thread type: user, utility etc. */
725
 
        unsigned        in_use:1;       /*!< TRUE if this slot is in use */
726
 
        unsigned        suspended:1;    /*!< TRUE if the thread is waiting
 
593
        os_thread_id_t  id;             /* thread id */
 
594
        os_thread_t     handle;         /* thread handle */
 
595
        unsigned        type:3;         /* thread type: user, utility etc. */
 
596
        unsigned        in_use:1;       /* TRUE if this slot is in use */
 
597
        unsigned        suspended:1;    /* TRUE if the thread is waiting
727
598
                                        for the event of this slot */
728
 
        ib_time_t       suspend_time;   /*!< time when the thread was
 
599
        ib_time_t       suspend_time;   /* time when the thread was
729
600
                                        suspended */
730
 
        os_event_t      event;          /*!< event used in suspending the
 
601
        os_event_t      event;          /* event used in suspending the
731
602
                                        thread when it has nothing to do */
732
 
        que_thr_t*      thr;            /*!< suspended query thread (only
 
603
        que_thr_t*      thr;            /* suspended query thread (only
733
604
                                        used for MySQL threads) */
734
605
};
735
606
 
736
607
/* Table for MySQL threads where they will be suspended to wait for locks */
737
608
UNIV_INTERN srv_slot_t* srv_mysql_table = NULL;
738
609
 
739
 
UNIV_INTERN os_event_t  srv_timeout_event;
740
 
 
741
 
UNIV_INTERN os_event_t  srv_monitor_event;
742
 
 
743
 
UNIV_INTERN os_event_t  srv_error_event;
744
 
 
745
610
UNIV_INTERN os_event_t  srv_lock_timeout_thread_event;
746
611
 
747
612
UNIV_INTERN srv_sys_t*  srv_sys = NULL;
751
616
UNIV_INTERN byte        srv_pad1[64];
752
617
/* mutex protecting the server, trx structs, query threads, and lock table */
753
618
UNIV_INTERN mutex_t*    kernel_mutex_temp;
754
 
/* mutex protecting the sys header for writing the commit id */
755
 
UNIV_INTERN mutex_t*    commit_id_mutex_temp;
756
 
 
757
619
/* padding to prevent other memory update hotspots from residing on
758
620
the same memory cache line */
759
621
UNIV_INTERN byte        srv_pad2[64];
772
634
static ulint    srv_meter_foreground[SRV_MASTER + 1];
773
635
#endif
774
636
 
775
 
/***********************************************************************
776
 
Prints counters for work done by srv_master_thread. */
777
 
static
778
 
void
779
 
srv_print_master_thread_info(
780
 
/*=========================*/
781
 
        FILE  *file)    /* in: output stream */
782
 
{
783
 
        fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
784
 
                "%lu 10_second, %lu background, %lu flush\n",
785
 
                srv_main_1_second_loops, srv_main_sleeps,
786
 
                srv_main_10_second_loops, srv_main_background_loops,
787
 
                srv_main_flush_loops);
788
 
        fprintf(file, "srv_master_thread log flush and writes: %lu\n",
789
 
                      srv_log_writes_and_flush);
790
 
}
791
 
 
792
637
/* The following values give info about the activity going on in
793
638
the database. They are protected by the server mutex. The arrays
794
639
are indexed by the type of the thread. */
796
641
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
797
642
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
798
643
 
799
 
/*********************************************************************//**
 
644
/*************************************************************************
800
645
Sets the info describing an i/o thread current state. */
801
646
UNIV_INTERN
802
647
void
803
648
srv_set_io_thread_op_info(
804
649
/*======================*/
805
 
        ulint           i,      /*!< in: the 'segment' of the i/o thread */
806
 
        const char*     str)    /*!< in: constant char string describing the
 
650
        ulint           i,      /* in: the 'segment' of the i/o thread */
 
651
        const char*     str)    /* in: constant char string describing the
807
652
                                state */
808
653
{
809
654
        ut_a(i < SRV_MAX_N_IO_THREADS);
811
656
        srv_io_thread_op_info[i] = str;
812
657
}
813
658
 
814
 
/*********************************************************************//**
 
659
/*************************************************************************
815
660
Accessor function to get pointer to n'th slot in the server thread
816
 
table.
817
 
@return pointer to the slot */
 
661
table. */
818
662
static
819
663
srv_slot_t*
820
664
srv_table_get_nth_slot(
821
665
/*===================*/
822
 
        ulint   index)          /*!< in: index of the slot */
 
666
                                /* out: pointer to the slot */
 
667
        ulint   index)          /* in: index of the slot */
823
668
{
824
669
        ut_a(index < OS_THREAD_MAX_N);
825
670
 
826
671
        return(srv_sys->threads + index);
827
672
}
828
673
 
829
 
/*********************************************************************//**
830
 
Gets the number of threads in the system.
831
 
@return sum of srv_n_threads[] */
 
674
#ifndef UNIV_HOTBACKUP
 
675
/*************************************************************************
 
676
Gets the number of threads in the system. */
832
677
UNIV_INTERN
833
678
ulint
834
679
srv_get_n_threads(void)
849
694
        return(n_threads);
850
695
}
851
696
 
852
 
/*********************************************************************//**
 
697
/*************************************************************************
853
698
Reserves a slot in the thread table for the current thread. Also creates the
854
699
thread local storage struct for the current thread. NOTE! The server mutex
855
 
has to be reserved by the caller!
856
 
@return reserved slot index */
 
700
has to be reserved by the caller! */
857
701
static
858
702
ulint
859
703
srv_table_reserve_slot(
860
704
/*===================*/
861
 
        enum srv_thread_type    type)   /*!< in: type of the thread */
 
705
                                        /* out: reserved slot index */
 
706
        enum srv_thread_type    type)   /* in: type of the thread */
862
707
{
863
708
        srv_slot_t*     slot;
864
709
        ulint           i;
889
734
        return(i);
890
735
}
891
736
 
892
 
/*********************************************************************//**
 
737
/*************************************************************************
893
738
Suspends the calling thread to wait for the event in its thread slot.
894
 
NOTE! The server mutex has to be reserved by the caller!
895
 
@return event for the calling thread to wait */
 
739
NOTE! The server mutex has to be reserved by the caller! */
896
740
static
897
741
os_event_t
898
742
srv_suspend_thread(void)
899
743
/*====================*/
 
744
                        /* out: event for the calling thread to wait */
900
745
{
901
746
        srv_slot_t*             slot;
902
747
        os_event_t              event;
915
760
 
916
761
        slot = srv_table_get_nth_slot(slot_no);
917
762
 
918
 
        type = static_cast<srv_thread_type>(slot->type);
 
763
        type = slot->type;
919
764
 
920
765
        ut_ad(type >= SRV_WORKER);
921
766
        ut_ad(type <= SRV_MASTER);
932
777
 
933
778
        return(event);
934
779
}
 
780
#endif /* !UNIV_HOTBACKUP */
935
781
 
936
 
/*********************************************************************//**
 
782
/*************************************************************************
937
783
Releases threads of the type given from suspension in the thread table.
938
 
NOTE! The server mutex has to be reserved by the caller!
939
 
@return number of threads released: this may be less than n if not
940
 
enough threads were suspended at the moment */
 
784
NOTE! The server mutex has to be reserved by the caller! */
941
785
UNIV_INTERN
942
786
ulint
943
787
srv_release_threads(
944
788
/*================*/
945
 
        enum srv_thread_type    type,   /*!< in: thread type */
946
 
        ulint                   n)      /*!< in: number of threads to release */
 
789
                                        /* out: number of threads
 
790
                                        released: this may be < n if
 
791
                                        not enough threads were
 
792
                                        suspended at the moment */
 
793
        enum srv_thread_type    type,   /* in: thread type */
 
794
        ulint                   n)      /* in: number of threads to release */
947
795
{
948
796
        srv_slot_t*     slot;
949
797
        ulint           i;
958
806
 
959
807
                slot = srv_table_get_nth_slot(i);
960
808
 
961
 
                if (slot->in_use &&
962
 
                    (static_cast<srv_thread_type>(slot->type) == type) &&
963
 
                    slot->suspended) {
 
809
                if (slot->in_use && slot->type == type && slot->suspended) {
964
810
 
965
811
                        slot->suspended = FALSE;
966
812
 
987
833
        return(count);
988
834
}
989
835
 
990
 
/*********************************************************************//**
991
 
Returns the calling thread type.
992
 
@return SRV_COM, ... */
 
836
/*************************************************************************
 
837
Returns the calling thread type. */
993
838
UNIV_INTERN
994
839
enum srv_thread_type
995
840
srv_get_thread_type(void)
996
841
/*=====================*/
 
842
                        /* out: SRV_COM, ... */
997
843
{
998
844
        ulint                   slot_no;
999
845
        srv_slot_t*             slot;
1005
851
 
1006
852
        slot = srv_table_get_nth_slot(slot_no);
1007
853
 
1008
 
        type = static_cast<srv_thread_type>(slot->type);
 
854
        type = slot->type;
1009
855
 
1010
856
        ut_ad(type >= SRV_WORKER);
1011
857
        ut_ad(type <= SRV_MASTER);
1015
861
        return(type);
1016
862
}
1017
863
 
1018
 
/*********************************************************************//**
 
864
/*************************************************************************
1019
865
Initializes the server. */
1020
866
UNIV_INTERN
1021
867
void
1024
870
{
1025
871
        srv_conc_slot_t*        conc_slot;
1026
872
        srv_slot_t*             slot;
 
873
        dict_table_t*           table;
1027
874
        ulint                   i;
1028
875
 
1029
 
        srv_sys = static_cast<srv_sys_t *>(mem_alloc(sizeof(srv_sys_t)));
1030
 
 
1031
 
        kernel_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
1032
 
        mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
1033
 
 
1034
 
        commit_id_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
1035
 
        mutex_create(commit_id_mutex_key, &commit_id_mutex, SYNC_COMMIT_ID_LOCK);
1036
 
 
1037
 
        mutex_create(srv_innodb_monitor_mutex_key,
1038
 
                     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
1039
 
 
1040
 
        srv_sys->threads = static_cast<srv_table_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
 
876
        srv_sys = mem_alloc(sizeof(srv_sys_t));
 
877
 
 
878
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
 
879
        mutex_create(&kernel_mutex, SYNC_KERNEL);
 
880
 
 
881
        mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
882
 
 
883
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1041
884
 
1042
885
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1043
886
                slot = srv_table_get_nth_slot(i);
1047
890
                ut_a(slot->event);
1048
891
        }
1049
892
 
1050
 
        srv_mysql_table = static_cast<srv_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
 
893
        srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1051
894
 
1052
895
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1053
896
                slot = srv_mysql_table + i;
1057
900
                ut_a(slot->event);
1058
901
        }
1059
902
 
1060
 
        srv_error_event = os_event_create(NULL);
1061
 
 
1062
 
        srv_timeout_event = os_event_create(NULL);
1063
 
 
1064
 
        srv_monitor_event = os_event_create(NULL);
1065
 
 
1066
903
        srv_lock_timeout_thread_event = os_event_create(NULL);
1067
904
 
1068
905
        for (i = 0; i < SRV_MASTER + 1; i++) {
1079
916
 
1080
917
        UT_LIST_INIT(srv_sys->tasks);
1081
918
 
1082
 
        /* Create dummy indexes for infimum and supremum records */
1083
 
 
1084
 
        dict_ind_init();
 
919
        /* create dummy table and index for old-style infimum and supremum */
 
920
        table = dict_mem_table_create("SYS_DUMMY1",
 
921
                                      DICT_HDR_SPACE, 1, 0);
 
922
        dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
 
923
                               DATA_ENGLISH | DATA_NOT_NULL, 8);
 
924
 
 
925
        srv_sys->dummy_ind1 = dict_mem_index_create(
 
926
                "SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
 
927
        dict_index_add_col(srv_sys->dummy_ind1, table,
 
928
                           dict_table_get_nth_col(table, 0), 0);
 
929
        srv_sys->dummy_ind1->table = table;
 
930
        /* create dummy table and index for new-style infimum and supremum */
 
931
        table = dict_mem_table_create("SYS_DUMMY2",
 
932
                                      DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
 
933
        dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
 
934
                               DATA_ENGLISH | DATA_NOT_NULL, 8);
 
935
        srv_sys->dummy_ind2 = dict_mem_index_create(
 
936
                "SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
 
937
        dict_index_add_col(srv_sys->dummy_ind2, table,
 
938
                           dict_table_get_nth_col(table, 0), 0);
 
939
        srv_sys->dummy_ind2->table = table;
 
940
 
 
941
        /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
 
942
        srv_sys->dummy_ind1->cached = srv_sys->dummy_ind2->cached = TRUE;
1085
943
 
1086
944
        /* Init the server concurrency restriction data structures */
1087
945
 
1089
947
 
1090
948
        UT_LIST_INIT(srv_conc_queue);
1091
949
 
1092
 
        srv_conc_slots = static_cast<srv_conc_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t)));
 
950
        srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
1093
951
 
1094
952
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1095
953
                conc_slot = srv_conc_slots + i;
1102
960
        trx_i_s_cache_init(trx_i_s_cache);
1103
961
}
1104
962
 
1105
 
/*********************************************************************//**
1106
 
Frees the data structures created in srv_init(). */
 
963
/*************************************************************************
 
964
Frees the OS fast mutex created in srv_init(). */
1107
965
UNIV_INTERN
1108
966
void
1109
967
srv_free(void)
1110
968
/*==========*/
1111
969
{
1112
970
        os_fast_mutex_free(&srv_conc_mutex);
1113
 
        mem_free(srv_conc_slots);
1114
 
        srv_conc_slots = NULL;
1115
 
 
1116
 
        mem_free(srv_sys->threads);
1117
 
        mem_free(srv_sys);
1118
 
        srv_sys = NULL;
1119
 
 
1120
 
        mem_free(kernel_mutex_temp);
1121
 
        kernel_mutex_temp = NULL;
1122
 
        mem_free(srv_mysql_table);
1123
 
        srv_mysql_table = NULL;
1124
 
 
1125
 
        mem_free(commit_id_mutex_temp);
1126
 
        commit_id_mutex_temp = NULL;
1127
 
 
1128
 
        trx_i_s_cache_free(trx_i_s_cache);
1129
971
}
1130
972
 
1131
 
/*********************************************************************//**
 
973
/*************************************************************************
1132
974
Initializes the synchronization primitives, memory system, and the thread
1133
975
local storage. */
1134
976
UNIV_INTERN
1136
978
srv_general_init(void)
1137
979
/*==================*/
1138
980
{
1139
 
        ut_mem_init();
1140
 
        /* Reset the system variables in the recovery module. */
1141
 
        recv_sys_var_init();
1142
981
        os_sync_init();
1143
982
        sync_init();
1144
983
        mem_init(srv_mem_pool_size);
1150
989
/* Maximum allowable purge history length.  <=0 means 'infinite'. */
1151
990
UNIV_INTERN ulong       srv_max_purge_lag               = 0;
1152
991
 
1153
 
/*********************************************************************//**
 
992
/*************************************************************************
1154
993
Puts an OS thread to wait if there are too many concurrent threads
1155
994
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
1156
995
UNIV_INTERN
1157
996
void
1158
997
srv_conc_enter_innodb(
1159
998
/*==================*/
1160
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
999
        trx_t*  trx)    /* in: transaction object associated with the
1161
1000
                        thread */
1162
1001
{
1163
1002
        ibool                   has_slept = FALSE;
1197
1036
                return;
1198
1037
        }
1199
1038
 
1200
 
        ut_ad(srv_conc_n_threads >= 0);
1201
 
 
1202
1039
        if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
1203
1040
 
1204
1041
                srv_conc_n_threads++;
1310
1147
        os_fast_mutex_unlock(&srv_conc_mutex);
1311
1148
}
1312
1149
 
1313
 
/*********************************************************************//**
 
1150
/*************************************************************************
1314
1151
This lets a thread enter InnoDB regardless of the number of threads inside
1315
1152
InnoDB. This must be called when a thread ends a lock wait. */
1316
1153
UNIV_INTERN
1317
1154
void
1318
1155
srv_conc_force_enter_innodb(
1319
1156
/*========================*/
1320
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1157
        trx_t*  trx)    /* in: transaction object associated with the
1321
1158
                        thread */
1322
1159
{
1323
1160
        if (UNIV_LIKELY(!srv_thread_concurrency)) {
1325
1162
                return;
1326
1163
        }
1327
1164
 
1328
 
        ut_ad(srv_conc_n_threads >= 0);
1329
 
 
1330
1165
        os_fast_mutex_lock(&srv_conc_mutex);
1331
1166
 
1332
1167
        srv_conc_n_threads++;
1336
1171
        os_fast_mutex_unlock(&srv_conc_mutex);
1337
1172
}
1338
1173
 
1339
 
/*********************************************************************//**
 
1174
/*************************************************************************
1340
1175
This must be called when a thread exits InnoDB in a lock wait or at the
1341
1176
end of an SQL statement. */
1342
1177
UNIV_INTERN
1343
1178
void
1344
1179
srv_conc_force_exit_innodb(
1345
1180
/*=======================*/
1346
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1181
        trx_t*  trx)    /* in: transaction object associated with the
1347
1182
                        thread */
1348
1183
{
1349
1184
        srv_conc_slot_t*        slot    = NULL;
1350
1185
 
 
1186
        if (UNIV_LIKELY(!srv_thread_concurrency)) {
 
1187
 
 
1188
                return;
 
1189
        }
 
1190
 
1351
1191
        if (trx->mysql_thd != NULL
1352
1192
            && thd_is_replication_slave_thread(trx->mysql_thd)) {
1353
1193
 
1361
1201
 
1362
1202
        os_fast_mutex_lock(&srv_conc_mutex);
1363
1203
 
1364
 
        ut_ad(srv_conc_n_threads > 0);
1365
1204
        srv_conc_n_threads--;
1366
1205
        trx->declared_to_be_inside_innodb = FALSE;
1367
1206
        trx->n_tickets_to_enter_innodb = 0;
1393
1232
        }
1394
1233
}
1395
1234
 
1396
 
/*********************************************************************//**
 
1235
/*************************************************************************
1397
1236
This must be called when a thread exits InnoDB. */
1398
1237
UNIV_INTERN
1399
1238
void
1400
1239
srv_conc_exit_innodb(
1401
1240
/*=================*/
1402
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1241
        trx_t*  trx)    /* in: transaction object associated with the
1403
1242
                        thread */
1404
1243
{
1405
1244
        if (trx->n_tickets_to_enter_innodb > 0) {
1418
1257
 
1419
1258
/*========================================================================*/
1420
1259
 
1421
 
/*********************************************************************//**
1422
 
Normalizes init parameter values to use units we use inside InnoDB.
1423
 
@return DB_SUCCESS or error code */
 
1260
/*************************************************************************
 
1261
Normalizes init parameter values to use units we use inside InnoDB. */
1424
1262
static
1425
1263
ulint
1426
1264
srv_normalize_init_values(void)
1427
1265
/*===========================*/
 
1266
                                /* out: DB_SUCCESS or error code */
1428
1267
{
1429
1268
        ulint   n;
1430
1269
        ulint   i;
1448
1287
        return(DB_SUCCESS);
1449
1288
}
1450
1289
 
1451
 
/*********************************************************************//**
1452
 
Boots the InnoDB server.
1453
 
@return DB_SUCCESS or error code */
 
1290
/*************************************************************************
 
1291
Boots the InnoDB server. */
1454
1292
UNIV_INTERN
1455
1293
ulint
1456
1294
srv_boot(void)
1457
1295
/*==========*/
 
1296
                        /* out: DB_SUCCESS or error code */
1458
1297
{
1459
1298
        ulint   err;
1460
1299
 
1479
1318
        return(DB_SUCCESS);
1480
1319
}
1481
1320
 
1482
 
/*********************************************************************//**
 
1321
#ifndef UNIV_HOTBACKUP
 
1322
/*************************************************************************
1483
1323
Reserves a slot in the thread table for the current MySQL OS thread.
1484
 
NOTE! The kernel mutex has to be reserved by the caller!
1485
 
@return reserved slot */
 
1324
NOTE! The kernel mutex has to be reserved by the caller! */
1486
1325
static
1487
1326
srv_slot_t*
1488
1327
srv_table_reserve_slot_for_mysql(void)
1489
1328
/*==================================*/
 
1329
                        /* out: reserved slot */
1490
1330
{
1491
1331
        srv_slot_t*     slot;
1492
1332
        ulint           i;
1543
1383
 
1544
1384
        return(slot);
1545
1385
}
 
1386
#endif /* !UNIV_HOTBACKUP */
1546
1387
 
1547
 
/***************************************************************//**
 
1388
/*******************************************************************
1548
1389
Puts a MySQL OS thread to wait for a lock to be released. If an error
1549
1390
occurs during the wait trx->error_state associated with thr is
1550
1391
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
1554
1395
void
1555
1396
srv_suspend_mysql_thread(
1556
1397
/*=====================*/
1557
 
        que_thr_t*      thr)    /*!< in: query thread associated with the MySQL
 
1398
        que_thr_t*      thr)    /* in: query thread associated with the MySQL
1558
1399
                                OS thread */
1559
1400
{
 
1401
#ifndef UNIV_HOTBACKUP
1560
1402
        srv_slot_t*     slot;
1561
1403
        os_event_t      event;
1562
1404
        double          wait_time;
1645
1487
                row_mysql_unfreeze_data_dictionary(trx);
1646
1488
                break;
1647
1489
        case RW_X_LATCH:
1648
 
                /* There should never be a lock wait when the
1649
 
                dictionary latch is reserved in X mode.  Dictionary
1650
 
                transactions should only acquire locks on dictionary
1651
 
                tables, not other tables. All access to dictionary
1652
 
                tables should be covered by dictionary
1653
 
                transactions. */
1654
 
                ut_print_timestamp(stderr);
1655
 
                fputs("  InnoDB: Error: dict X latch held in "
1656
 
                      "srv_suspend_mysql_thread\n", stderr);
1657
 
                /* This should never occur. This incorrect handling
1658
 
                was added in the early development of
1659
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1660
1490
                /* Release fast index creation latch */
1661
1491
                row_mysql_unlock_data_dictionary(trx);
1662
1492
                break;
1664
1494
 
1665
1495
        ut_a(trx->dict_operation_lock_mode == 0);
1666
1496
 
1667
 
        /* Suspend this thread and wait for the event. */
 
1497
        /* Wait for the release */
1668
1498
 
1669
1499
        os_event_wait(event);
1670
1500
 
1671
 
        /* After resuming, reacquire the data dictionary latch if
1672
 
        necessary. */
1673
 
 
1674
1501
        switch (had_dict_lock) {
1675
1502
        case RW_S_LATCH:
1676
1503
                row_mysql_freeze_data_dictionary(trx);
1677
1504
                break;
1678
1505
        case RW_X_LATCH:
1679
 
                /* This should never occur. This incorrect handling
1680
 
                was added in the early development of
1681
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1682
1506
                row_mysql_lock_data_dictionary(trx);
1683
1507
                break;
1684
1508
        }
1715
1539
                    start_time != -1 && finish_time != -1) {
1716
1540
                        srv_n_lock_max_wait_time = diff_time;
1717
1541
                }
1718
 
 
1719
 
                /* Record the lock wait time for this thread */
1720
 
                thd_set_lock_wait_time(trx->mysql_thd, diff_time);
1721
1542
        }
1722
1543
 
1723
1544
        if (trx->was_chosen_as_deadlock_victim) {
1739
1560
 
1740
1561
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1741
1562
        }
1742
 
 
1743
 
        if (trx_is_interrupted(trx)) {
1744
 
 
1745
 
                trx->error_state = DB_INTERRUPTED;
1746
 
        }
 
1563
#else /* UNIV_HOTBACKUP */
 
1564
        /* This function depends on MySQL code that is not included in
 
1565
        InnoDB Hot Backup builds.  Besides, this function should never
 
1566
        be called in InnoDB Hot Backup. */
 
1567
        ut_error;
 
1568
#endif /* UNIV_HOTBACKUP */
1747
1569
}
1748
1570
 
1749
 
/********************************************************************//**
 
1571
/************************************************************************
1750
1572
Releases a MySQL OS thread waiting for a lock to be released, if the
1751
1573
thread is already suspended. */
1752
1574
UNIV_INTERN
1753
1575
void
1754
1576
srv_release_mysql_thread_if_suspended(
1755
1577
/*==================================*/
1756
 
        que_thr_t*      thr)    /*!< in: query thread associated with the
 
1578
        que_thr_t*      thr)    /* in: query thread associated with the
1757
1579
                                MySQL OS thread  */
1758
1580
{
 
1581
#ifndef UNIV_HOTBACKUP
1759
1582
        srv_slot_t*     slot;
1760
1583
        ulint           i;
1761
1584
 
1775
1598
        }
1776
1599
 
1777
1600
        /* not found */
 
1601
#else /* UNIV_HOTBACKUP */
 
1602
        /* This function depends on MySQL code that is not included in
 
1603
        InnoDB Hot Backup builds.  Besides, this function should never
 
1604
        be called in InnoDB Hot Backup. */
 
1605
        ut_error;
 
1606
#endif /* UNIV_HOTBACKUP */
1778
1607
}
1779
1608
 
1780
 
/******************************************************************//**
 
1609
#ifndef UNIV_HOTBACKUP
 
1610
/**********************************************************************
1781
1611
Refreshes the values used to calculate per-second averages. */
1782
1612
static
1783
1613
void
1795
1625
 
1796
1626
        log_refresh_stats();
1797
1627
 
1798
 
        buf_refresh_io_stats_all();
 
1628
        buf_refresh_io_stats();
1799
1629
 
1800
1630
        srv_n_rows_inserted_old = srv_n_rows_inserted;
1801
1631
        srv_n_rows_updated_old = srv_n_rows_updated;
1805
1635
        mutex_exit(&srv_innodb_monitor_mutex);
1806
1636
}
1807
1637
 
1808
 
/******************************************************************//**
1809
 
Outputs to a file the output of the InnoDB Monitor.
1810
 
@return FALSE if not all information printed
1811
 
due to failure to obtain necessary mutex */
 
1638
/**********************************************************************
 
1639
Outputs to a file the output of the InnoDB Monitor. */
1812
1640
UNIV_INTERN
1813
 
ibool
 
1641
void
1814
1642
srv_printf_innodb_monitor(
1815
1643
/*======================*/
1816
 
        FILE*   file,           /*!< in: output stream */
1817
 
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1818
 
        ulint*  trx_start,      /*!< out: file position of the start of
 
1644
        FILE*   file,           /* in: output stream */
 
1645
        ulint*  trx_start,      /* out: file position of the start of
1819
1646
                                the list of active transactions */
1820
 
        ulint*  trx_end)        /*!< out: file position of the end of
 
1647
        ulint*  trx_end)        /* out: file position of the end of
1821
1648
                                the list of active transactions */
1822
1649
{
1823
1650
        double  time_elapsed;
1824
1651
        time_t  current_time;
1825
1652
        ulint   n_reserved;
1826
 
        ibool   ret;
1827
1653
 
1828
1654
        mutex_enter(&srv_innodb_monitor_mutex);
1829
1655
 
1847
1673
                "Per second averages calculated from the last %lu seconds\n",
1848
1674
                (ulong)time_elapsed);
1849
1675
 
1850
 
        fputs("-----------------\n"
1851
 
              "BACKGROUND THREAD\n"
1852
 
              "-----------------\n", file);
1853
 
        srv_print_master_thread_info(file);
1854
 
 
1855
1676
        fputs("----------\n"
1856
1677
              "SEMAPHORES\n"
1857
1678
              "----------\n", file);
1873
1694
 
1874
1695
        mutex_exit(&dict_foreign_err_mutex);
1875
1696
 
1876
 
        /* Only if lock_print_info_summary proceeds correctly,
1877
 
        before we call the lock_print_info_all_transactions
1878
 
        to print all the lock information. */
1879
 
        ret = lock_print_info_summary(file, nowait);
1880
 
 
1881
 
        if (ret) {
1882
 
                if (trx_start) {
1883
 
                        long    t = ftell(file);
1884
 
                        if (t < 0) {
1885
 
                                *trx_start = ULINT_UNDEFINED;
1886
 
                        } else {
1887
 
                                *trx_start = (ulint) t;
1888
 
                        }
1889
 
                }
1890
 
                lock_print_info_all_transactions(file);
1891
 
                if (trx_end) {
1892
 
                        long    t = ftell(file);
1893
 
                        if (t < 0) {
1894
 
                                *trx_end = ULINT_UNDEFINED;
1895
 
                        } else {
1896
 
                                *trx_end = (ulint) t;
1897
 
                        }
1898
 
                }
1899
 
        }
1900
 
 
 
1697
        lock_print_info_summary(file);
 
1698
        if (trx_start) {
 
1699
                long    t = ftell(file);
 
1700
                if (t < 0) {
 
1701
                        *trx_start = ULINT_UNDEFINED;
 
1702
                } else {
 
1703
                        *trx_start = (ulint) t;
 
1704
                }
 
1705
        }
 
1706
        lock_print_info_all_transactions(file);
 
1707
        if (trx_end) {
 
1708
                long    t = ftell(file);
 
1709
                if (t < 0) {
 
1710
                        *trx_end = ULINT_UNDEFINED;
 
1711
                } else {
 
1712
                        *trx_end = (ulint) t;
 
1713
                }
 
1714
        }
1901
1715
        fputs("--------\n"
1902
1716
              "FILE I/O\n"
1903
1717
              "--------\n", file);
1945
1759
                (ulong) srv_conc_n_waiting_threads);
1946
1760
 
1947
1761
        fprintf(file, "%lu read views open inside InnoDB\n",
1948
 
                static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)));
 
1762
                UT_LIST_GET_LEN(trx_sys->view_list));
1949
1763
 
1950
1764
        n_reserved = fil_space_get_n_reserved_extents(0);
1951
1765
        if (n_reserved > 0) {
1995
1809
              "============================\n", file);
1996
1810
        mutex_exit(&srv_innodb_monitor_mutex);
1997
1811
        fflush(file);
1998
 
 
1999
 
        return(ret);
2000
1812
}
2001
1813
 
2002
 
/******************************************************************//**
 
1814
/**********************************************************************
2003
1815
Function to pass InnoDB status variables to MySQL */
2004
1816
UNIV_INTERN
2005
1817
void
2006
1818
srv_export_innodb_status(void)
2007
 
/*==========================*/
2008
1819
{
2009
 
        buf_pool_stat_t stat;
2010
 
        ulint           LRU_len;
2011
 
        ulint           free_len;
2012
 
        ulint           flush_list_len;
2013
 
 
2014
 
        buf_get_total_stat(&stat);
2015
 
        buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
2016
 
 
2017
1820
        mutex_enter(&srv_innodb_monitor_mutex);
2018
1821
 
2019
1822
        export_vars.innodb_data_pending_reads
2028
1831
        export_vars.innodb_data_reads = os_n_file_reads;
2029
1832
        export_vars.innodb_data_writes = os_n_file_writes;
2030
1833
        export_vars.innodb_data_written = srv_data_written;
2031
 
        export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
 
1834
        export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
2032
1835
        export_vars.innodb_buffer_pool_write_requests
2033
1836
                = srv_buf_pool_write_requests;
2034
1837
        export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
2035
1838
        export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
2036
1839
        export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
2037
 
        export_vars.innodb_buffer_pool_read_ahead
2038
 
                = stat.n_ra_pages_read;
2039
 
        export_vars.innodb_buffer_pool_read_ahead_evicted
2040
 
                = stat.n_ra_pages_evicted;
2041
 
        export_vars.innodb_buffer_pool_pages_data = LRU_len;
2042
 
        export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
2043
 
        export_vars.innodb_buffer_pool_pages_free = free_len;
 
1840
        export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
 
1841
        export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
 
1842
        export_vars.innodb_buffer_pool_pages_data
 
1843
                = UT_LIST_GET_LEN(buf_pool->LRU);
 
1844
        export_vars.innodb_buffer_pool_pages_dirty
 
1845
                = UT_LIST_GET_LEN(buf_pool->flush_list);
 
1846
        export_vars.innodb_buffer_pool_pages_free
 
1847
                = UT_LIST_GET_LEN(buf_pool->free);
2044
1848
#ifdef UNIV_DEBUG
2045
1849
        export_vars.innodb_buffer_pool_pages_latched
2046
1850
                = buf_get_latched_pages_number();
2047
1851
#endif /* UNIV_DEBUG */
2048
 
        export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
 
1852
        export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
2049
1853
 
2050
 
        export_vars.innodb_buffer_pool_pages_misc
2051
 
                = buf_pool_get_n_pages() - LRU_len - free_len;
2052
 
#ifdef HAVE_ATOMIC_BUILTINS
2053
 
        export_vars.innodb_have_atomic_builtins = 1;
2054
 
#else
2055
 
        export_vars.innodb_have_atomic_builtins = 0;
2056
 
#endif
 
1854
        export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
 
1855
                - UT_LIST_GET_LEN(buf_pool->LRU)
 
1856
                - UT_LIST_GET_LEN(buf_pool->free);
2057
1857
        export_vars.innodb_page_size = UNIV_PAGE_SIZE;
2058
1858
        export_vars.innodb_log_waits = srv_log_waits;
2059
1859
        export_vars.innodb_os_log_written = srv_os_log_written;
2064
1864
        export_vars.innodb_log_writes = srv_log_writes;
2065
1865
        export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
2066
1866
        export_vars.innodb_dblwr_writes = srv_dblwr_writes;
2067
 
        export_vars.innodb_pages_created = stat.n_pages_created;
2068
 
        export_vars.innodb_pages_read = stat.n_pages_read;
2069
 
        export_vars.innodb_pages_written = stat.n_pages_written;
 
1867
        export_vars.innodb_pages_created = buf_pool->n_pages_created;
 
1868
        export_vars.innodb_pages_read = buf_pool->n_pages_read;
 
1869
        export_vars.innodb_pages_written = buf_pool->n_pages_written;
2070
1870
        export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
2071
1871
        export_vars.innodb_row_lock_current_waits
2072
1872
                = srv_n_lock_wait_current_count;
2083
1883
        export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2084
1884
        export_vars.innodb_rows_updated = srv_n_rows_updated;
2085
1885
        export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2086
 
        export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
2087
1886
 
2088
1887
        mutex_exit(&srv_innodb_monitor_mutex);
2089
1888
}
2090
1889
 
2091
 
/*********************************************************************//**
2092
 
A thread which prints the info output by various InnoDB monitors.
2093
 
@return a dummy parameter */
 
1890
/*************************************************************************
 
1891
A thread which wakes up threads whose lock wait may have lasted too long.
 
1892
This also prints the info output by various InnoDB monitors. */
2094
1893
UNIV_INTERN
2095
1894
os_thread_ret_t
2096
 
srv_monitor_thread(
2097
 
/*===============*/
2098
 
        void*   /*arg __attribute__((unused))*/)
2099
 
                        /*!< in: a dummy parameter required by
 
1895
srv_lock_timeout_and_monitor_thread(
 
1896
/*================================*/
 
1897
                        /* out: a dummy parameter */
 
1898
        void*   arg __attribute__((unused)))
 
1899
                        /* in: a dummy parameter required by
2100
1900
                        os_thread_create */
2101
1901
{
2102
 
        ib_int64_t      sig_count;
 
1902
        srv_slot_t*     slot;
2103
1903
        double          time_elapsed;
2104
1904
        time_t          current_time;
2105
1905
        time_t          last_table_monitor_time;
2106
1906
        time_t          last_tablespace_monitor_time;
2107
1907
        time_t          last_monitor_time;
2108
 
        ulint           mutex_skipped;
2109
 
        ibool           last_srv_print_monitor;
 
1908
        ibool           some_waits;
 
1909
        double          wait_time;
 
1910
        ulint           i;
2110
1911
 
2111
1912
#ifdef UNIV_DEBUG_THREAD_CREATION
2112
1913
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2113
1914
                os_thread_pf(os_thread_get_curr_id()));
2114
1915
#endif
2115
 
 
2116
 
#ifdef UNIV_PFS_THREAD
2117
 
        pfs_register_thread(srv_monitor_thread_key);
2118
 
#endif
2119
 
 
2120
 
        srv_last_monitor_time = ut_time();
2121
 
        last_table_monitor_time = ut_time();
2122
 
        last_tablespace_monitor_time = ut_time();
2123
 
        last_monitor_time = ut_time();
2124
 
        mutex_skipped = 0;
2125
 
        last_srv_print_monitor = srv_print_innodb_monitor;
 
1916
        UT_NOT_USED(arg);
 
1917
        srv_last_monitor_time = time(NULL);
 
1918
        last_table_monitor_time = time(NULL);
 
1919
        last_tablespace_monitor_time = time(NULL);
 
1920
        last_monitor_time = time(NULL);
2126
1921
loop:
2127
 
        srv_monitor_active = TRUE;
2128
 
 
2129
 
        /* Wake up every 5 seconds to see if we need to print
2130
 
        monitor information or if signalled at shutdown. */
2131
 
 
2132
 
        sig_count = os_event_reset(srv_monitor_event);
2133
 
 
2134
 
        os_event_wait_time_low(srv_monitor_event, 5000000, sig_count);
2135
 
 
2136
 
        current_time = ut_time();
 
1922
        srv_lock_timeout_and_monitor_active = TRUE;
 
1923
 
 
1924
        /* When someone is waiting for a lock, we wake up every second
 
1925
        and check if a timeout has passed for a lock wait */
 
1926
 
 
1927
        os_thread_sleep(1000000);
 
1928
 
 
1929
        current_time = time(NULL);
2137
1930
 
2138
1931
        time_elapsed = difftime(current_time, last_monitor_time);
2139
1932
 
2140
1933
        if (time_elapsed > 15) {
2141
 
                last_monitor_time = ut_time();
 
1934
                last_monitor_time = time(NULL);
2142
1935
 
2143
1936
                if (srv_print_innodb_monitor) {
2144
 
                        /* Reset mutex_skipped counter everytime
2145
 
                        srv_print_innodb_monitor changes. This is to
2146
 
                        ensure we will not be blocked by kernel_mutex
2147
 
                        for short duration information printing,
2148
 
                        such as requested by sync_array_print_long_waits() */
2149
 
                        if (!last_srv_print_monitor) {
2150
 
                                mutex_skipped = 0;
2151
 
                                last_srv_print_monitor = TRUE;
2152
 
                        }
2153
 
 
2154
 
                        if (!srv_printf_innodb_monitor(stderr,
2155
 
                                                MUTEX_NOWAIT(mutex_skipped),
2156
 
                                                NULL, NULL)) {
2157
 
                                mutex_skipped++;
2158
 
                        } else {
2159
 
                                /* Reset the counter */
2160
 
                                mutex_skipped = 0;
2161
 
                        }
2162
 
                } else {
2163
 
                        last_srv_print_monitor = FALSE;
 
1937
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
2164
1938
                }
2165
1939
 
2166
 
 
2167
1940
                if (srv_innodb_status) {
2168
1941
                        mutex_enter(&srv_monitor_file_mutex);
2169
1942
                        rewind(srv_monitor_file);
2170
 
                        if (!srv_printf_innodb_monitor(srv_monitor_file,
2171
 
                                                MUTEX_NOWAIT(mutex_skipped),
2172
 
                                                NULL, NULL)) {
2173
 
                                mutex_skipped++;
2174
 
                        } else {
2175
 
                                mutex_skipped = 0;
2176
 
                        }
2177
 
 
 
1943
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
 
1944
                                                  NULL);
2178
1945
                        os_file_set_eof(srv_monitor_file);
2179
1946
                        mutex_exit(&srv_monitor_file_mutex);
2180
1947
                }
2182
1949
                if (srv_print_innodb_tablespace_monitor
2183
1950
                    && difftime(current_time,
2184
1951
                                last_tablespace_monitor_time) > 60) {
2185
 
                        last_tablespace_monitor_time = ut_time();
 
1952
                        last_tablespace_monitor_time = time(NULL);
2186
1953
 
2187
1954
                        fputs("========================"
2188
1955
                              "========================\n",
2208
1975
                if (srv_print_innodb_table_monitor
2209
1976
                    && difftime(current_time, last_table_monitor_time) > 60) {
2210
1977
 
2211
 
                        last_table_monitor_time = ut_time();
 
1978
                        last_table_monitor_time = time(NULL);
2212
1979
 
2213
1980
                        fputs("===========================================\n",
2214
1981
                              stderr);
2227
1994
                }
2228
1995
        }
2229
1996
 
2230
 
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2231
 
                goto exit_func;
2232
 
        }
2233
 
 
2234
 
        if (srv_print_innodb_monitor
2235
 
            || srv_print_innodb_lock_monitor
2236
 
            || srv_print_innodb_tablespace_monitor
2237
 
            || srv_print_innodb_table_monitor) {
2238
 
                goto loop;
2239
 
        }
2240
 
 
2241
 
        srv_monitor_active = FALSE;
2242
 
 
2243
 
        goto loop;
2244
 
 
2245
 
exit_func:
2246
 
        srv_monitor_active = FALSE;
2247
 
 
2248
 
        /* We count the number of threads in os_thread_exit(). A created
2249
 
        thread should always use that to exit and not use return() to exit. */
2250
 
 
2251
 
        os_thread_exit(NULL);
2252
 
 
2253
 
        OS_THREAD_DUMMY_RETURN;
2254
 
}
2255
 
 
2256
 
/*********************************************************************//**
2257
 
A thread which wakes up threads whose lock wait may have lasted too long.
2258
 
@return a dummy parameter */
2259
 
UNIV_INTERN
2260
 
os_thread_ret_t
2261
 
srv_lock_timeout_thread(
2262
 
/*====================*/
2263
 
        void*   /*arg __attribute__((unused))*/)
2264
 
                        /* in: a dummy parameter required by
2265
 
                        os_thread_create */
2266
 
{
2267
 
        srv_slot_t*     slot;
2268
 
        ibool           some_waits;
2269
 
        double          wait_time;
2270
 
        ulint           i;
2271
 
        ib_int64_t      sig_count;
2272
 
 
2273
 
#ifdef UNIV_PFS_THREAD
2274
 
        pfs_register_thread(srv_lock_timeout_thread_key);
2275
 
#endif
2276
 
 
2277
 
loop:
2278
 
 
2279
 
        /* When someone is waiting for a lock, we wake up every second
2280
 
        and check if a timeout has passed for a lock wait */
2281
 
 
2282
 
        sig_count = os_event_reset(srv_timeout_event);
2283
 
 
2284
 
        os_event_wait_time_low(srv_timeout_event, 1000000, sig_count);
2285
 
 
2286
 
        srv_lock_timeout_active = TRUE;
2287
 
 
2288
1997
        mutex_enter(&kernel_mutex);
2289
1998
 
2290
1999
        some_waits = FALSE;
2308
2017
                        lock_wait_timeout = thd_lock_wait_timeout(
2309
2018
                                trx->mysql_thd);
2310
2019
 
2311
 
                        if (trx_is_interrupted(trx)
2312
 
                            || (lock_wait_timeout < 100000000
2313
 
                                && (wait_time > (double) lock_wait_timeout
2314
 
                                    || wait_time < 0))) {
 
2020
                        if (lock_wait_timeout < 100000000
 
2021
                            && (wait_time > (double) lock_wait_timeout
 
2022
                                || wait_time < 0)) {
2315
2023
 
2316
2024
                                /* Timeout exceeded or a wrap-around in system
2317
2025
                                time counter: cancel the lock request queued
2336
2044
                goto exit_func;
2337
2045
        }
2338
2046
 
2339
 
        if (some_waits) {
 
2047
        if (some_waits || srv_print_innodb_monitor
 
2048
            || srv_print_innodb_lock_monitor
 
2049
            || srv_print_innodb_tablespace_monitor
 
2050
            || srv_print_innodb_table_monitor) {
2340
2051
                goto loop;
2341
2052
        }
2342
2053
 
2343
 
        srv_lock_timeout_active = FALSE;
 
2054
        /* No one was waiting for a lock and no monitor was active:
 
2055
        suspend this thread */
 
2056
 
 
2057
        srv_lock_timeout_and_monitor_active = FALSE;
2344
2058
 
2345
2059
#if 0
2346
2060
        /* The following synchronisation is disabled, since
2350
2064
        goto loop;
2351
2065
 
2352
2066
exit_func:
2353
 
        srv_lock_timeout_active = FALSE;
 
2067
        srv_lock_timeout_and_monitor_active = FALSE;
2354
2068
 
2355
2069
        /* We count the number of threads in os_thread_exit(). A created
2356
2070
        thread should always use that to exit and not use return() to exit. */
2360
2074
        OS_THREAD_DUMMY_RETURN;
2361
2075
}
2362
2076
 
2363
 
/*********************************************************************//**
 
2077
/*************************************************************************
2364
2078
A thread which prints warnings about semaphore waits which have lasted
2365
 
too long. These can be used to track bugs which cause hangs.
2366
 
@return a dummy parameter */
 
2079
too long. These can be used to track bugs which cause hangs. */
2367
2080
UNIV_INTERN
2368
2081
os_thread_ret_t
2369
2082
srv_error_monitor_thread(
2370
2083
/*=====================*/
2371
 
        void*   /*arg __attribute__((unused))*/)
2372
 
                        /*!< in: a dummy parameter required by
 
2084
                        /* out: a dummy parameter */
 
2085
        void*   arg __attribute__((unused)))
 
2086
                        /* in: a dummy parameter required by
2373
2087
                        os_thread_create */
2374
2088
{
2375
2089
        /* number of successive fatal timeouts observed */
2376
2090
        ulint           fatal_cnt       = 0;
2377
2091
        ib_uint64_t     old_lsn;
2378
2092
        ib_uint64_t     new_lsn;
2379
 
        ib_int64_t      sig_count;
2380
2093
 
2381
2094
        old_lsn = srv_start_lsn;
2382
2095
 
2384
2097
        fprintf(stderr, "Error monitor thread starts, id %lu\n",
2385
2098
                os_thread_pf(os_thread_get_curr_id()));
2386
2099
#endif
2387
 
 
2388
 
#ifdef UNIV_PFS_THREAD
2389
 
        pfs_register_thread(srv_error_monitor_thread_key);
2390
 
#endif
2391
 
 
2392
2100
loop:
2393
2101
        srv_error_monitor_active = TRUE;
2394
2102
 
2398
2106
        new_lsn = log_get_lsn();
2399
2107
 
2400
2108
        if (new_lsn < old_lsn) {
2401
 
          drizzled::errmsg_printf(drizzled::error::INFO,
2402
 
                                  "InnoDB: Error: old log sequence number %"PRIu64" was greater than the new log sequence number %"PRIu64"!"
2403
 
                                  "InnoDB: Please submit a bug report to http://bugs.launchpad.net/drizzle",
2404
 
                                  old_lsn, new_lsn);
 
2109
                ut_print_timestamp(stderr);
 
2110
                fprintf(stderr,
 
2111
                        "  InnoDB: Error: old log sequence number %"PRIu64""
 
2112
                        " was greater\n"
 
2113
                        "InnoDB: than the new log sequence number %"PRIu64"!\n"
 
2114
                        "InnoDB: Please submit a bug report"
 
2115
                        " to http://bugs.mysql.com\n",
 
2116
                        old_lsn, new_lsn);
2405
2117
        }
2406
2118
 
2407
2119
        old_lsn = new_lsn;
2414
2126
        }
2415
2127
 
2416
2128
        /* Update the statistics collected for deciding LRU
2417
 
        eviction policy. */
 
2129
        eviction policy. */
2418
2130
        buf_LRU_stat_update();
2419
2131
 
2420
 
        /* Update the statistics collected for flush rate policy. */
2421
 
        buf_flush_stat_update();
2422
 
 
2423
2132
        /* In case mutex_exit is not a memory barrier, it is
2424
2133
        theoretically possible some threads are left waiting though
2425
2134
        the semaphore is already released. Wake up those threads: */
2426
 
 
 
2135
        
2427
2136
        sync_arr_wake_threads_if_sema_free();
2428
2137
 
2429
2138
        if (sync_array_print_long_waits()) {
2448
2157
 
2449
2158
        fflush(stderr);
2450
2159
 
2451
 
        sig_count = os_event_reset(srv_error_event);
2452
 
 
2453
 
        os_event_wait_time_low(srv_error_event, 1000000, sig_count);
 
2160
        os_thread_sleep(1000000);
2454
2161
 
2455
2162
        if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
2456
2163
 
2467
2174
        OS_THREAD_DUMMY_RETURN;
2468
2175
}
2469
2176
 
2470
 
/**********************************************************************//**
2471
 
Check whether any background thread is active.
2472
 
@return FALSE if all are are suspended or have exited. */
2473
 
UNIV_INTERN
2474
 
ibool
2475
 
srv_is_any_background_thread_active(void)
2476
 
/*=====================================*/
2477
 
{
2478
 
        ulint   i;
2479
 
        ibool   ret = FALSE;
2480
 
 
2481
 
        mutex_enter(&kernel_mutex);
2482
 
 
2483
 
        for (i = SRV_COM; i <= SRV_MASTER; ++i) {
2484
 
                if (srv_n_threads_active[i] != 0) {
2485
 
                        ret = TRUE;
2486
 
                        break;
2487
 
                }
2488
 
        }
2489
 
 
2490
 
        mutex_exit(&kernel_mutex);
2491
 
 
2492
 
        return(ret);
2493
 
}
2494
 
 
2495
 
/*******************************************************************//**
 
2177
/***********************************************************************
2496
2178
Tells the InnoDB server that there has been activity in the database
2497
2179
and wakes up the master thread if it is suspended (not sleeping). Used
2498
2180
in the MySQL interface. Note that there is a small chance that the master
2499
 
thread stays suspended (we do not protect our operation with the
2500
 
srv_sys_t->mutex, for performance reasons). */
 
2181
thread stays suspended (we do not protect our operation with the kernel
 
2182
mutex, for performace reasons). */
2501
2183
UNIV_INTERN
2502
2184
void
2503
2185
srv_active_wake_master_thread(void)
2515
2197
        }
2516
2198
}
2517
2199
 
2518
 
/*******************************************************************//**
2519
 
Tells the purge thread that there has been activity in the database
2520
 
and wakes up the purge thread if it is suspended (not sleeping).  Note
2521
 
that there is a small chance that the purge thread stays suspended
2522
 
(we do not protect our operation with the kernel mutex, for
2523
 
performace reasons). */
2524
 
UNIV_INTERN
2525
 
void
2526
 
srv_wake_purge_thread_if_not_active(void)
2527
 
/*=====================================*/
2528
 
{
2529
 
        ut_ad(!mutex_own(&kernel_mutex));
2530
 
 
2531
 
        if (srv_n_purge_threads > 0
2532
 
            && srv_n_threads_active[SRV_WORKER] == 0) {
2533
 
 
2534
 
                mutex_enter(&kernel_mutex);
2535
 
 
2536
 
                srv_release_threads(SRV_WORKER, 1);
2537
 
 
2538
 
                mutex_exit(&kernel_mutex);
2539
 
        }
2540
 
}
2541
 
 
2542
 
/*******************************************************************//**
 
2200
/***********************************************************************
2543
2201
Wakes up the master thread if it is suspended or being suspended. */
2544
2202
UNIV_INTERN
2545
2203
void
2555
2213
        mutex_exit(&kernel_mutex);
2556
2214
}
2557
2215
 
2558
 
/*******************************************************************//**
2559
 
Wakes up the purge thread if it's not already awake. */
2560
 
UNIV_INTERN
2561
 
void
2562
 
srv_wake_purge_thread(void)
2563
 
/*=======================*/
2564
 
{
2565
 
        ut_ad(!mutex_own(&kernel_mutex));
2566
 
 
2567
 
        if (srv_n_purge_threads > 0) {
2568
 
 
2569
 
                mutex_enter(&kernel_mutex);
2570
 
 
2571
 
                srv_release_threads(SRV_WORKER, 1);
2572
 
 
2573
 
                mutex_exit(&kernel_mutex);
2574
 
        }
2575
 
}
2576
 
 
2577
 
/**********************************************************************
2578
 
The master thread is tasked to ensure that flush of log file happens
2579
 
once every second in the background. This is to ensure that not more
2580
 
than one second of trxs are lost in case of crash when
2581
 
innodb_flush_logs_at_trx_commit != 1 */
2582
 
static
2583
 
void
2584
 
srv_sync_log_buffer_in_background(void)
2585
 
/*===================================*/
2586
 
{
2587
 
        time_t  current_time = time(NULL);
2588
 
 
2589
 
        srv_main_thread_op_info = "flushing log";
2590
 
        if (difftime(current_time, srv_last_log_flush_time) >= 1) {
2591
 
                log_buffer_sync_in_background(TRUE);
2592
 
                srv_last_log_flush_time = current_time;
2593
 
                srv_log_writes_and_flush++;
2594
 
        }
2595
 
}
2596
 
 
2597
 
/********************************************************************//**
2598
 
Do a full purge, reconfigure the purge sub-system if a dynamic
2599
 
change is detected. */
2600
 
static
2601
 
void
2602
 
srv_master_do_purge(void)
2603
 
/*=====================*/
2604
 
{
2605
 
        ulint   n_pages_purged;
2606
 
 
2607
 
        ut_ad(!mutex_own(&kernel_mutex));
2608
 
 
2609
 
        ut_a(srv_n_purge_threads == 0);
2610
 
 
2611
 
        do {
2612
 
                /* Check for shutdown and change in purge config. */
2613
 
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2614
 
                        /* Nothing to purge. */
2615
 
                        n_pages_purged = 0;
2616
 
                } else {
2617
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
2618
 
                }
2619
 
 
2620
 
                srv_sync_log_buffer_in_background();
2621
 
 
2622
 
        } while (n_pages_purged > 0);
2623
 
}
2624
 
 
2625
 
/*********************************************************************//**
2626
 
The master thread controlling the server.
2627
 
@return a dummy parameter */
 
2216
/*************************************************************************
 
2217
The master thread controlling the server. */
2628
2218
UNIV_INTERN
2629
2219
os_thread_ret_t
2630
2220
srv_master_thread(
2631
2221
/*==============*/
2632
 
        void*   /*arg __attribute__((unused))*/)
2633
 
                        /*!< in: a dummy parameter required by
 
2222
                        /* out: a dummy parameter */
 
2223
        void*   arg __attribute__((unused)))
 
2224
                        /* in: a dummy parameter required by
2634
2225
                        os_thread_create */
2635
2226
{
2636
 
        buf_pool_stat_t buf_stat;
2637
2227
        os_event_t      event;
 
2228
        time_t          last_flush_time;
 
2229
        time_t          current_time;
2638
2230
        ulint           old_activity_count;
2639
2231
        ulint           n_pages_purged  = 0;
2640
2232
        ulint           n_bytes_merged;
2645
2237
        ulint           n_ios_old;
2646
2238
        ulint           n_ios_very_old;
2647
2239
        ulint           n_pend_ios;
2648
 
        ulint           next_itr_time;
 
2240
        ibool           skip_sleep      = FALSE;
2649
2241
        ulint           i;
2650
2242
 
2651
2243
#ifdef UNIV_DEBUG_THREAD_CREATION
2652
2244
        fprintf(stderr, "Master thread starts, id %lu\n",
2653
2245
                os_thread_pf(os_thread_get_curr_id()));
2654
2246
#endif
2655
 
 
2656
 
#ifdef UNIV_PFS_THREAD
2657
 
        pfs_register_thread(srv_master_thread_key);
2658
 
#endif
2659
 
 
2660
2247
        srv_main_thread_process_no = os_proc_get_number();
2661
2248
        srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2662
2249
 
2675
2262
 
2676
2263
        srv_main_thread_op_info = "reserving kernel mutex";
2677
2264
 
2678
 
        buf_get_total_stat(&buf_stat);
2679
 
        n_ios_very_old = log_sys->n_log_ios + buf_stat.n_pages_read
2680
 
                + buf_stat.n_pages_written;
 
2265
        n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2266
                + buf_pool->n_pages_written;
2681
2267
        mutex_enter(&kernel_mutex);
2682
2268
 
2683
2269
        /* Store the user activity counter at the start of this loop */
2693
2279
        /* ---- We run the following loop approximately once per second
2694
2280
        when there is database activity */
2695
2281
 
2696
 
        srv_last_log_flush_time = time(NULL);
2697
 
 
2698
 
        /* Sleep for 1 second on entrying the for loop below the first time. */
2699
 
        next_itr_time = ut_time_ms() + 1000;
 
2282
        skip_sleep = FALSE;
2700
2283
 
2701
2284
        for (i = 0; i < 10; i++) {
2702
 
                ulint   cur_time = ut_time_ms();
 
2285
                n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2286
                        + buf_pool->n_pages_written;
 
2287
                srv_main_thread_op_info = "sleeping";
 
2288
 
 
2289
                if (!skip_sleep) {
 
2290
 
 
2291
                        os_thread_sleep(1000000);
 
2292
                }
 
2293
 
 
2294
                skip_sleep = FALSE;
2703
2295
 
2704
2296
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2705
2297
                can drop tables lazily after there no longer are SELECT
2716
2308
                        goto background_loop;
2717
2309
                }
2718
2310
 
2719
 
                buf_get_total_stat(&buf_stat);
2720
 
 
2721
 
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2722
 
                        + buf_stat.n_pages_written;
2723
 
 
2724
 
                srv_main_thread_op_info = "sleeping";
2725
 
                srv_main_1_second_loops++;
2726
 
 
2727
 
                if (next_itr_time > cur_time
2728
 
                    && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2729
 
 
2730
 
                        /* Get sleep interval in micro seconds. We use
2731
 
                        ut_min() to avoid long sleep in case of
2732
 
                        wrap around. */
2733
 
                        os_thread_sleep(ut_min(1000000,
2734
 
                                        (next_itr_time - cur_time)
2735
 
                                         * 1000));
2736
 
                        srv_main_sleeps++;
2737
 
                }
2738
 
 
2739
 
                /* Each iteration should happen at 1 second interval. */
2740
 
                next_itr_time = ut_time_ms() + 1000;
2741
 
 
2742
 
                /* Flush logs if needed */
2743
 
                srv_sync_log_buffer_in_background();
 
2311
                /* We flush the log once in a second even if no commit
 
2312
                is issued or the we have specified in my.cnf no flush
 
2313
                at transaction commit */
 
2314
 
 
2315
                srv_main_thread_op_info = "flushing log";
 
2316
                log_buffer_flush_to_disk();
2744
2317
 
2745
2318
                srv_main_thread_op_info = "making checkpoint";
2746
2319
                log_free_check();
2747
2320
 
2748
 
                /* If i/os during one second sleep were less than 5% of
2749
 
                capacity, we assume that there is free disk i/o capacity
2750
 
                available, and it makes sense to do an insert buffer merge. */
 
2321
                /* If there were less than 5 i/os during the
 
2322
                one second sleep, we assume that there is free
 
2323
                disk i/o capacity available, and it makes sense to
 
2324
                do an insert buffer merge. */
2751
2325
 
2752
 
                buf_get_total_stat(&buf_stat);
2753
2326
                n_pend_ios = buf_get_n_pending_ios()
2754
2327
                        + log_sys->n_pending_writes;
2755
 
                n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2756
 
                        + buf_stat.n_pages_written;
2757
 
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2758
 
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
 
2328
                n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2329
                        + buf_pool->n_pages_written;
 
2330
                if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) {
2759
2331
                        srv_main_thread_op_info = "doing insert buffer merge";
2760
 
                        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
2761
 
 
2762
 
                        /* Flush logs if needed */
2763
 
                        srv_sync_log_buffer_in_background();
 
2332
                        ibuf_contract_for_n_pages(
 
2333
                                TRUE, srv_insert_buffer_batch_size / 4);
 
2334
 
 
2335
                        srv_main_thread_op_info = "flushing log";
 
2336
 
 
2337
                        log_buffer_flush_to_disk();
2764
2338
                }
2765
2339
 
2766
2340
                if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
2769
2343
                        /* Try to keep the number of modified pages in the
2770
2344
                        buffer pool under the limit wished by the user */
2771
2345
 
2772
 
                        srv_main_thread_op_info =
2773
 
                                "flushing buffer pool pages";
2774
 
                        n_pages_flushed = buf_flush_list(
2775
 
                                PCT_IO(100), IB_ULONGLONG_MAX);
2776
 
 
2777
 
                } else if (srv_adaptive_flushing) {
2778
 
 
2779
 
                        /* Try to keep the rate of flushing of dirty
2780
 
                        pages such that redo log generation does not
2781
 
                        produce bursts of IO at checkpoint time. */
2782
 
                        ulint n_flush = buf_flush_get_desired_flush_rate();
2783
 
 
2784
 
                        if (n_flush) {
2785
 
                                srv_main_thread_op_info =
2786
 
                                        "flushing buffer pool pages";
2787
 
                                n_flush = ut_min(PCT_IO(100), n_flush);
2788
 
                                n_pages_flushed =
2789
 
                                        buf_flush_list(
2790
 
                                                n_flush,
2791
 
                                                IB_ULONGLONG_MAX);
2792
 
                        }
 
2346
                        n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2347
                                                          IB_ULONGLONG_MAX);
 
2348
 
 
2349
                        /* If we had to do the flush, it may have taken
 
2350
                        even more than 1 second, and also, there may be more
 
2351
                        to flush. Do not sleep 1 second during the next
 
2352
                        iteration of this loop. */
 
2353
 
 
2354
                        skip_sleep = TRUE;
2793
2355
                }
2794
2356
 
2795
2357
                if (srv_activity_count == old_activity_count) {
2809
2371
        seconds */
2810
2372
        mem_validate_all_blocks();
2811
2373
#endif
2812
 
        /* If i/os during the 10 second period were less than 200% of
2813
 
        capacity, we assume that there is free disk i/o capacity
2814
 
        available, and it makes sense to flush srv_io_capacity pages.
2815
 
 
2816
 
        Note that this is done regardless of the fraction of dirty
2817
 
        pages relative to the max requested by the user. The one second
2818
 
        loop above requests writes for that case. The writes done here
2819
 
        are not required, and may be disabled. */
2820
 
 
2821
 
        buf_get_total_stat(&buf_stat);
 
2374
        /* If there were less than 200 i/os during the 10 second period,
 
2375
        we assume that there is free disk i/o capacity available, and it
 
2376
        makes sense to flush 100 pages. */
 
2377
 
2822
2378
        n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
2823
 
        n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2824
 
                + buf_stat.n_pages_written;
2825
 
 
2826
 
        srv_main_10_second_loops++;
2827
 
        if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2828
 
            && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
 
2379
        n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2380
                + buf_pool->n_pages_written;
 
2381
        if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) {
2829
2382
 
2830
2383
                srv_main_thread_op_info = "flushing buffer pool pages";
2831
 
                buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
 
2384
                buf_flush_batch(BUF_FLUSH_LIST, 100, IB_ULONGLONG_MAX);
2832
2385
 
2833
 
                /* Flush logs if needed */
2834
 
                srv_sync_log_buffer_in_background();
 
2386
                srv_main_thread_op_info = "flushing log";
 
2387
                log_buffer_flush_to_disk();
2835
2388
        }
2836
2389
 
2837
2390
        /* We run a batch of insert buffer merge every 10 seconds,
2838
2391
        even if the server were active */
2839
2392
 
2840
2393
        srv_main_thread_op_info = "doing insert buffer merge";
2841
 
        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
2842
 
 
2843
 
        /* Flush logs if needed */
2844
 
        srv_sync_log_buffer_in_background();
2845
 
 
2846
 
        if (srv_n_purge_threads == 0) {
2847
 
                srv_main_thread_op_info = "master purging";
2848
 
 
2849
 
                srv_master_do_purge();
 
2394
        ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4);
 
2395
 
 
2396
        srv_main_thread_op_info = "flushing log";
 
2397
        log_buffer_flush_to_disk();
 
2398
 
 
2399
        /* We run a full purge every 10 seconds, even if the server
 
2400
        were active */
 
2401
 
 
2402
        last_flush_time = time(NULL);
 
2403
 
 
2404
        do {
2850
2405
 
2851
2406
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2852
2407
 
2853
2408
                        goto background_loop;
2854
2409
                }
2855
 
        }
 
2410
 
 
2411
                srv_main_thread_op_info = "purging";
 
2412
                n_pages_purged = trx_purge();
 
2413
 
 
2414
                current_time = time(NULL);
 
2415
 
 
2416
                if (difftime(current_time, last_flush_time) > 1) {
 
2417
                        srv_main_thread_op_info = "flushing log";
 
2418
 
 
2419
                        log_buffer_flush_to_disk();
 
2420
                        last_flush_time = current_time;
 
2421
                }
 
2422
        } while (n_pages_purged);
2856
2423
 
2857
2424
        srv_main_thread_op_info = "flushing buffer pool pages";
2858
2425
 
2864
2431
                (> 70 %), we assume we can afford reserving the disk(s) for
2865
2432
                the time it requires to flush 100 pages */
2866
2433
 
2867
 
                n_pages_flushed = buf_flush_list(
2868
 
                        PCT_IO(100), IB_ULONGLONG_MAX);
 
2434
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2435
                                                  IB_ULONGLONG_MAX);
2869
2436
        } else {
2870
2437
                /* Otherwise, we only flush a small number of pages so that
2871
2438
                we do not unnecessarily use much disk i/o capacity from
2872
2439
                other work */
2873
2440
 
2874
 
                n_pages_flushed = buf_flush_list(
2875
 
                          PCT_IO(10), IB_ULONGLONG_MAX);
 
2441
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10,
 
2442
                                                  IB_ULONGLONG_MAX);
2876
2443
        }
2877
2444
 
2878
2445
        srv_main_thread_op_info = "making checkpoint";
2905
2472
 
2906
2473
        /* The server has been quiet for a while: start running background
2907
2474
        operations */
2908
 
        srv_main_background_loops++;
 
2475
 
2909
2476
        srv_main_thread_op_info = "doing background drop tables";
2910
2477
 
2911
2478
        n_tables_to_drop = row_drop_tables_for_mysql_in_background();
2916
2483
                MySQL tries to drop a table while there are still open handles
2917
2484
                to it and we had to put it to the background drop queue.) */
2918
2485
 
2919
 
                if (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2920
 
                        os_thread_sleep(100000);
2921
 
                }
2922
 
        }
2923
 
 
2924
 
        if (srv_n_purge_threads == 0) {
2925
 
                srv_main_thread_op_info = "master purging";
2926
 
 
2927
 
                srv_master_do_purge();
2928
 
        }
 
2486
                os_thread_sleep(100000);
 
2487
        }
 
2488
 
 
2489
        srv_main_thread_op_info = "purging";
 
2490
 
 
2491
        /* Run a full purge */
 
2492
 
 
2493
        last_flush_time = time(NULL);
 
2494
 
 
2495
        do {
 
2496
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
 
2497
 
 
2498
                        break;
 
2499
                }
 
2500
 
 
2501
                srv_main_thread_op_info = "purging";
 
2502
                n_pages_purged = trx_purge();
 
2503
 
 
2504
                current_time = time(NULL);
 
2505
 
 
2506
                if (difftime(current_time, last_flush_time) > 1) {
 
2507
                        srv_main_thread_op_info = "flushing log";
 
2508
 
 
2509
                        log_buffer_flush_to_disk();
 
2510
                        last_flush_time = current_time;
 
2511
                }
 
2512
        } while (n_pages_purged);
2929
2513
 
2930
2514
        srv_main_thread_op_info = "reserving kernel mutex";
2931
2515
 
2941
2525
        if (srv_fast_shutdown && srv_shutdown_state > 0) {
2942
2526
                n_bytes_merged = 0;
2943
2527
        } else {
2944
 
                /* This should do an amount of IO similar to the number of
2945
 
                dirty pages that will be flushed in the call to
2946
 
                buf_flush_list below. Otherwise, the system favors
2947
 
                clean pages over cleanup throughput. */
2948
 
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2949
 
                                                           PCT_IO(100));
 
2528
                n_bytes_merged = ibuf_contract_for_n_pages(
 
2529
                        TRUE, srv_insert_buffer_batch_size);
2950
2530
        }
2951
2531
 
2952
2532
        srv_main_thread_op_info = "reserving kernel mutex";
2960
2540
 
2961
2541
flush_loop:
2962
2542
        srv_main_thread_op_info = "flushing buffer pool pages";
2963
 
        srv_main_flush_loops++;
 
2543
 
2964
2544
        if (srv_fast_shutdown < 2) {
2965
 
                n_pages_flushed = buf_flush_list(
2966
 
                          PCT_IO(100), IB_ULONGLONG_MAX);
 
2545
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2546
                                                  IB_ULONGLONG_MAX);
2967
2547
        } else {
2968
2548
                /* In the fastest shutdown we do not flush the buffer pool
2969
2549
                to data files: we set n_pages_flushed to 0 artificially. */
2981
2561
        mutex_exit(&kernel_mutex);
2982
2562
 
2983
2563
        srv_main_thread_op_info = "waiting for buffer pool flush to end";
2984
 
        buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
2985
 
 
2986
 
        /* Flush logs if needed */
2987
 
        srv_sync_log_buffer_in_background();
 
2564
        buf_flush_wait_batch_end(BUF_FLUSH_LIST);
 
2565
 
 
2566
        srv_main_thread_op_info = "flushing log";
 
2567
 
 
2568
        log_buffer_flush_to_disk();
2988
2569
 
2989
2570
        srv_main_thread_op_info = "making checkpoint";
2990
2571
 
3068
2649
                already when the event wait ends */
3069
2650
 
3070
2651
                os_thread_exit(NULL);
3071
 
 
3072
2652
        }
3073
2653
 
3074
2654
        /* When there is user activity, InnoDB will set the event and the
3077
2657
        goto loop;
3078
2658
 
3079
2659
 
3080
 
#if !defined(__SUNPRO_C)
 
2660
#ifndef UNIV_SOLARIS
3081
2661
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3082
2662
#endif
3083
2663
}
3084
 
 
3085
 
/*********************************************************************//**
3086
 
Asynchronous purge thread.
3087
 
@return a dummy parameter */
3088
 
UNIV_INTERN
3089
 
os_thread_ret_t
3090
 
srv_purge_thread(
3091
 
/*=============*/
3092
 
        void*   /*arg __attribute__((unused))*/)        /*!< in: a dummy parameter
3093
 
                                                required by os_thread_create */
3094
 
{
3095
 
        srv_slot_t*     slot;
3096
 
        ulint           slot_no = ULINT_UNDEFINED;
3097
 
        ulint           n_total_purged = ULINT_UNDEFINED;
3098
 
 
3099
 
        ut_a(srv_n_purge_threads == 1);
3100
 
 
3101
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3102
 
        fprintf(stderr, "InnoDB: Purge thread running, id %lu\n",
3103
 
                os_thread_pf(os_thread_get_curr_id()));
3104
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3105
 
 
3106
 
        mutex_enter(&kernel_mutex);
3107
 
 
3108
 
        slot_no = srv_table_reserve_slot(SRV_WORKER);
3109
 
 
3110
 
        slot = srv_table_get_nth_slot(slot_no);
3111
 
 
3112
 
        ++srv_n_threads_active[SRV_WORKER];
3113
 
 
3114
 
        mutex_exit(&kernel_mutex);
3115
 
 
3116
 
        while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
3117
 
 
3118
 
                ulint   n_pages_purged;
3119
 
 
3120
 
                /* If there are very few records to purge or the last
3121
 
                purge didn't purge any records then wait for activity.
3122
 
                We peek at the history len without holding any mutex
3123
 
                because in the worst case we will end up waiting for
3124
 
                the next purge event. */
3125
 
                if (trx_sys->rseg_history_len < srv_purge_batch_size
3126
 
                    || n_total_purged == 0) {
3127
 
 
3128
 
                        os_event_t      event;
3129
 
 
3130
 
                        mutex_enter(&kernel_mutex);
3131
 
 
3132
 
                        event = srv_suspend_thread();
3133
 
 
3134
 
                        mutex_exit(&kernel_mutex);
3135
 
 
3136
 
                        os_event_wait(event);
3137
 
                }
3138
 
 
3139
 
                /* Check for shutdown and whether we should do purge at all. */
3140
 
                if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
3141
 
                    || srv_shutdown_state != 0
3142
 
                    || srv_fast_shutdown) {
3143
 
 
3144
 
                        break;
3145
 
                }
3146
 
 
3147
 
                n_total_purged = 0;
3148
 
 
3149
 
                /* Purge until there are no more records to purge and there is
3150
 
                no change in configuration or server state. */
3151
 
                do {
3152
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
3153
 
 
3154
 
                        n_total_purged += n_pages_purged;
3155
 
 
3156
 
                } while (n_pages_purged > 0 && !srv_fast_shutdown);
3157
 
 
3158
 
                srv_sync_log_buffer_in_background();
3159
 
        }
3160
 
 
3161
 
        mutex_enter(&kernel_mutex);
3162
 
 
3163
 
        ut_ad(srv_table_get_nth_slot(slot_no) == slot);
3164
 
 
3165
 
        /* Decrement the active count. */
3166
 
        srv_suspend_thread();
3167
 
 
3168
 
        slot->in_use = FALSE;
3169
 
 
3170
 
        /* Free the thread local memory. */
3171
 
        thr_local_free(os_thread_get_curr_id());
3172
 
 
3173
 
        mutex_exit(&kernel_mutex);
3174
 
 
3175
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3176
 
        fprintf(stderr, "InnoDB: Purge thread exiting, id %lu\n",
3177
 
                os_thread_pf(os_thread_get_curr_id()));
3178
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3179
 
 
3180
 
        /* We count the number of threads in os_thread_exit(). A created
3181
 
        thread should always use that to exit and not use return() to exit. */
3182
 
        os_thread_exit(NULL);
3183
 
 
3184
 
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3185
 
}
3186
 
 
3187
 
/**********************************************************************//**
3188
 
Enqueues a task to server task queue and releases a worker thread, if there
3189
 
is a suspended one. */
3190
 
UNIV_INTERN
3191
 
void
3192
 
srv_que_task_enqueue_low(
3193
 
/*=====================*/
3194
 
        que_thr_t*      thr)    /*!< in: query thread */
3195
 
{
3196
 
        ut_ad(thr);
3197
 
 
3198
 
        mutex_enter(&kernel_mutex);
3199
 
 
3200
 
        UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
3201
 
 
3202
 
        srv_release_threads(SRV_WORKER, 1);
3203
 
 
3204
 
        mutex_exit(&kernel_mutex);
3205
 
}
 
2664
#endif /* !UNIV_HOTBACKUP */