~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-03-25 18:24:15 UTC
  • mto: This revision was merged to the branch mainline in revision 963.
  • Revision ID: brian@tangent.org-20090325182415-opf2720c1hidtfgk
Cut down on shutdown loop of plugins (cutting stuff out in order to simplify
old lock system).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, 2009 Google Inc.
5
 
Copyright (c) 2009, Percona Inc.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, Google Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
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
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
26
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27
19
 
28
20
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
 
21
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
22
Place, Suite 330, Boston, MA 02111-1307 USA
31
23
 
32
24
*****************************************************************************/
33
25
 
34
 
/**************************************************//**
35
 
@file srv/srv0srv.c
 
26
/******************************************************
36
27
The database server main program
37
28
 
38
29
NOTE: SQL Server 7 uses something which the documentation
68
59
#include "sync0sync.h"
69
60
#include "thr0loc.h"
70
61
#include "que0que.h"
 
62
#include "srv0que.h"
71
63
#include "log0recv.h"
72
64
#include "pars0pars.h"
73
65
#include "usr0sess.h"
83
75
#include "row0mysql.h"
84
76
#include "ha_prototypes.h"
85
77
#include "trx0i_s.h"
86
 
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
87
78
 
88
79
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
89
80
affects only FOREIGN KEY definition parsing */
100
91
in microseconds, in order to reduce the lagging of the purge thread. */
101
92
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
102
93
 
103
 
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
104
 
UNIV_INTERN ibool       srv_monitor_active = FALSE;
 
94
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
105
95
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
106
96
 
107
97
UNIV_INTERN const char* srv_main_thread_op_info = "";
108
98
 
109
 
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
 
99
/* Prefix used by MySQL to indicate pre-5.1 table name encoding */
110
100
UNIV_INTERN const char  srv_mysql50_table_name_prefix[9] = "#mysql50#";
111
101
 
112
102
/* Server parameters which are read from the initfile */
119
109
UNIV_INTERN char*       srv_arch_dir    = NULL;
120
110
#endif /* UNIV_LOG_ARCHIVE */
121
111
 
122
 
/** store to its own file each table created by an user; data
 
112
/* store to its own file each table created by an user; data
123
113
dictionary tables are in the system tablespace 0 */
124
114
UNIV_INTERN my_bool     srv_file_per_table;
125
 
/** The file format to use on new *.ibd files. */
 
115
/* The file format to use on new *.ibd files. */
126
116
UNIV_INTERN ulint       srv_file_format = 0;
127
 
/** Whether to check file format during startup.  A value of
 
117
/* Whether to check file format during startup a value of 
128
118
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
129
119
set it to the highest format we support. */
130
 
UNIV_INTERN ulint       srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
 
120
UNIV_INTERN ulint       srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
131
121
 
132
122
#if DICT_TF_FORMAT_51
133
123
# error "DICT_TF_FORMAT_51 must be 0!"
134
124
#endif
135
 
/** Place locks to records only i.e. do not use next-key locking except
 
125
/* Place locks to records only i.e. do not use next-key locking except
136
126
on duplicate key checking and foreign key checking */
137
127
UNIV_INTERN ibool       srv_locks_unsafe_for_binlog = FALSE;
138
128
 
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
129
UNIV_INTERN ulint       srv_n_data_files = 0;
161
130
UNIV_INTERN char**      srv_data_file_names = NULL;
162
131
/* size in database pages */
169
138
UNIV_INTERN ulint       srv_last_file_size_max  = 0;
170
139
/* If the last data file is auto-extended, we add this
171
140
many pages to it at a time */
172
 
UNIV_INTERN unsigned int srv_auto_extend_increment = 8;
 
141
UNIV_INTERN ulong       srv_auto_extend_increment = 8;
173
142
UNIV_INTERN ulint*      srv_data_file_is_raw_partition = NULL;
174
143
 
175
144
/* If the following is TRUE we do not allow inserts etc. This protects
187
156
UNIV_INTERN ulint       srv_log_buffer_size     = ULINT_MAX;
188
157
UNIV_INTERN ulong       srv_flush_log_at_trx_commit = 1;
189
158
 
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
 
159
/* The sort order table of the MySQL latin1_swedish_ci character set
205
160
collation */
206
 
#if defined(BUILD_DRIZZLE)
207
161
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
208
162
                                        character set. The following table is
209
163
                                        the MySQL order as of Feb 10th, 2002 */
241
195
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xF7
242
196
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
243
197
};
244
 
#else
245
 
UNIV_INTERN const byte*        srv_latin1_ordering;
246
 
#endif /* BUILD_DRIZZLE */
247
198
 
248
199
 
249
200
/* use os/external memory allocator */
250
201
UNIV_INTERN my_bool     srv_use_sys_malloc      = TRUE;
251
202
/* requested size in kilobytes */
252
203
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;
255
204
/* previously requested size */
256
205
UNIV_INTERN ulint       srv_buf_pool_old_size;
257
206
/* current size in kilobytes */
260
209
UNIV_INTERN ulint       srv_mem_pool_size       = ULINT_MAX;
261
210
UNIV_INTERN ulint       srv_lock_table_size     = ULINT_MAX;
262
211
 
263
 
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
264
 
instead. */
265
212
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
213
 
274
214
#ifdef UNIV_LOG_ARCHIVE
275
215
UNIV_INTERN ibool               srv_log_archive_on      = FALSE;
293
233
 
294
234
UNIV_INTERN ulint       srv_max_n_open_files      = 300;
295
235
 
296
 
/* Number of IO operations per second the server can do */
297
 
UNIV_INTERN ulong       srv_io_capacity         = 200;
298
 
 
299
236
/* The InnoDB main thread tries to keep the ratio of modified pages
300
237
in the buffer pool to all database pages in the buffer pool smaller than
301
238
the following number. But it is not guaranteed that the value stays below
302
239
that during a time of heavy update/insert activity. */
303
240
 
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;
 
241
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 90;
311
242
 
312
243
/* variable counts amount of data read in total (in bytes) */
313
244
UNIV_INTERN ulint srv_data_read = 0;
351
282
pool to the disk */
352
283
UNIV_INTERN ulint srv_buf_pool_flushed = 0;
353
284
 
354
 
/** Number of buffer pool reads that led to the
 
285
/* variable to count the number of buffer pool reads that led to the
355
286
reading of a disk page */
356
287
UNIV_INTERN ulint srv_buf_pool_reads = 0;
357
288
 
 
289
/* variable to count the number of sequential read-aheads */
 
290
UNIV_INTERN ulint srv_read_ahead_seq = 0;
 
291
 
 
292
/* variable to count the number of random read-aheads */
 
293
UNIV_INTERN ulint srv_read_ahead_rnd = 0;
 
294
 
358
295
/* structure to pass status variables to MySQL */
359
296
UNIV_INTERN export_struc export_vars;
360
297
 
378
315
concurrency check. */
379
316
 
380
317
UNIV_INTERN ulong       srv_thread_concurrency  = 0;
 
318
UNIV_INTERN ulong       srv_commit_concurrency  = 0;
381
319
 
382
320
/* this mutex protects srv_conc data structures */
383
321
UNIV_INTERN os_fast_mutex_t     srv_conc_mutex;
392
330
 
393
331
typedef struct srv_conc_slot_struct     srv_conc_slot_t;
394
332
struct srv_conc_slot_struct{
395
 
        os_event_t                      event;          /*!< event to wait */
396
 
        ibool                           reserved;       /*!< TRUE if slot
 
333
        os_event_t                      event;          /* event to wait */
 
334
        ibool                           reserved;       /* TRUE if slot
397
335
                                                        reserved */
398
 
        ibool                           wait_ended;     /*!< TRUE when another
 
336
        ibool                           wait_ended;     /* TRUE when another
399
337
                                                        thread has already set
400
338
                                                        the event and the
401
339
                                                        thread in this slot is
402
340
                                                        free to proceed; but
403
341
                                                        reserved may still be
404
342
                                                        TRUE at that point */
405
 
        UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /*!< queue node */
 
343
        UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
406
344
};
407
345
 
408
346
/* queue of threads waiting to get in */
431
369
UNIV_INTERN ibool       srv_use_doublewrite_buf = TRUE;
432
370
UNIV_INTERN ibool       srv_use_checksums = TRUE;
433
371
 
 
372
UNIV_INTERN ibool       srv_set_thread_priorities = TRUE;
 
373
UNIV_INTERN int srv_query_thread_priority = 0;
 
374
 
434
375
UNIV_INTERN ulong       srv_replication_delay           = 0;
435
376
 
436
377
/*-------------------------------------------*/
437
 
UNIV_INTERN ulong       srv_n_spin_wait_rounds  = 30;
 
378
UNIV_INTERN ulong       srv_n_spin_wait_rounds  = 20;
438
379
UNIV_INTERN ulong       srv_n_free_tickets_to_enter = 500;
439
380
UNIV_INTERN ulong       srv_thread_sleep_delay = 10000;
440
 
UNIV_INTERN ulong       srv_spin_wait_delay     = 6;
 
381
UNIV_INTERN ulint       srv_spin_wait_delay     = 5;
441
382
UNIV_INTERN ibool       srv_priority_boost      = TRUE;
442
383
 
443
384
#ifdef UNIV_DEBUG
452
393
UNIV_INTERN ulint               srv_n_rows_updated              = 0;
453
394
UNIV_INTERN ulint               srv_n_rows_deleted              = 0;
454
395
UNIV_INTERN ulint               srv_n_rows_read                 = 0;
455
 
 
 
396
#ifndef UNIV_HOTBACKUP
456
397
static ulint    srv_n_rows_inserted_old         = 0;
457
398
static ulint    srv_n_rows_updated_old          = 0;
458
399
static ulint    srv_n_rows_deleted_old          = 0;
459
400
static ulint    srv_n_rows_read_old             = 0;
 
401
#endif /* !UNIV_HOTBACKUP */
460
402
 
461
403
UNIV_INTERN ulint               srv_n_lock_wait_count           = 0;
462
404
UNIV_INTERN ulint               srv_n_lock_wait_current_count   = 0;
463
405
UNIV_INTERN ib_int64_t  srv_n_lock_wait_time            = 0;
464
406
UNIV_INTERN ulint               srv_n_lock_max_wait_time        = 0;
465
407
 
466
 
UNIV_INTERN ulint               srv_truncated_status_writes     = 0;
467
408
 
468
409
/*
469
410
  Set the following to 0 if you want InnoDB to write messages on
487
428
 
488
429
/* Mutex for locking srv_monitor_file */
489
430
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 register srv_innodb_monitor_mutex with performance schema */
495
 
UNIV_INTERN mysql_pfs_key_t     srv_innodb_monitor_mutex_key;
496
 
/* Key to register srv_monitor_file_mutex with performance schema */
497
 
UNIV_INTERN mysql_pfs_key_t     srv_monitor_file_mutex_key;
498
 
/* Key to register srv_dict_tmpfile_mutex with performance schema */
499
 
UNIV_INTERN mysql_pfs_key_t     srv_dict_tmpfile_mutex_key;
500
 
/* Key to register the mutex with performance schema */
501
 
UNIV_INTERN mysql_pfs_key_t     srv_misc_tmpfile_mutex_key;
502
 
#endif /* UNIV_PFS_MUTEX */
503
 
 
504
431
/* Temporary file for innodb monitor output */
505
432
UNIV_INTERN FILE*       srv_monitor_file;
506
433
/* Mutex for locking srv_dict_tmpfile.
519
446
UNIV_INTERN ulint       srv_main_thread_process_no      = 0;
520
447
UNIV_INTERN ulint       srv_main_thread_id              = 0;
521
448
 
522
 
/* The following count work done by srv_master_thread. */
523
 
 
524
 
/* Iterations by the 'once per second' loop. */
525
 
static ulint   srv_main_1_second_loops          = 0;
526
 
/* Calls to sleep by the 'once per second' loop. */
527
 
static ulint   srv_main_sleeps                  = 0;
528
 
/* Iterations by the 'once per 10 seconds' loop. */
529
 
static ulint   srv_main_10_second_loops         = 0;
530
 
/* Iterations of the loop bounded by the 'background_loop' label. */
531
 
static ulint   srv_main_background_loops        = 0;
532
 
/* Iterations of the loop bounded by the 'flush_loop' label. */
533
 
static ulint   srv_main_flush_loops             = 0;
534
 
/* Log writes involving flush. */
535
 
static ulint   srv_log_writes_and_flush         = 0;
536
 
 
537
 
/* This is only ever touched by the master thread. It records the
538
 
time when the last flush of log file has happened. The master
539
 
thread ensures that we flush the log files at least once per
540
 
second. */
541
 
static time_t   srv_last_log_flush_time;
542
 
 
543
 
/* The master thread performs various tasks based on the current
544
 
state of IO activity and the level of IO utilization is past
545
 
intervals. Following macros define thresholds for these conditions. */
546
 
#define SRV_PEND_IO_THRESHOLD   (PCT_IO(3))
547
 
#define SRV_RECENT_IO_ACTIVITY  (PCT_IO(5))
548
 
#define SRV_PAST_IO_ACTIVITY    (PCT_IO(200))
549
 
 
550
449
/*
551
450
        IMPLEMENTATION OF THE SERVER MAIN PROGRAM
552
451
        =========================================
717
616
 
718
617
/* Thread slot in the thread table */
719
618
struct srv_slot_struct{
720
 
        os_thread_id_t  id;             /*!< thread id */
721
 
        os_thread_t     handle;         /*!< thread handle */
722
 
        unsigned        type:3;         /*!< thread type: user, utility etc. */
723
 
        unsigned        in_use:1;       /*!< TRUE if this slot is in use */
724
 
        unsigned        suspended:1;    /*!< TRUE if the thread is waiting
 
619
        os_thread_id_t  id;             /* thread id */
 
620
        os_thread_t     handle;         /* thread handle */
 
621
        unsigned        type:3;         /* thread type: user, utility etc. */
 
622
        unsigned        in_use:1;       /* TRUE if this slot is in use */
 
623
        unsigned        suspended:1;    /* TRUE if the thread is waiting
725
624
                                        for the event of this slot */
726
 
        ib_time_t       suspend_time;   /*!< time when the thread was
 
625
        ib_time_t       suspend_time;   /* time when the thread was
727
626
                                        suspended */
728
 
        os_event_t      event;          /*!< event used in suspending the
 
627
        os_event_t      event;          /* event used in suspending the
729
628
                                        thread when it has nothing to do */
730
 
        que_thr_t*      thr;            /*!< suspended query thread (only
 
629
        que_thr_t*      thr;            /* suspended query thread (only
731
630
                                        used for MySQL threads) */
732
631
};
733
632
 
761
660
static ulint    srv_meter_foreground[SRV_MASTER + 1];
762
661
#endif
763
662
 
764
 
/***********************************************************************
765
 
Prints counters for work done by srv_master_thread. */
766
 
static
767
 
void
768
 
srv_print_master_thread_info(
769
 
/*=========================*/
770
 
        FILE  *file)    /* in: output stream */
771
 
{
772
 
        fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
773
 
                "%lu 10_second, %lu background, %lu flush\n",
774
 
                srv_main_1_second_loops, srv_main_sleeps,
775
 
                srv_main_10_second_loops, srv_main_background_loops,
776
 
                srv_main_flush_loops);
777
 
        fprintf(file, "srv_master_thread log flush and writes: %lu\n",
778
 
                      srv_log_writes_and_flush);
779
 
}
780
 
 
781
663
/* The following values give info about the activity going on in
782
664
the database. They are protected by the server mutex. The arrays
783
665
are indexed by the type of the thread. */
785
667
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
786
668
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
787
669
 
788
 
/*********************************************************************//**
 
670
/*************************************************************************
789
671
Sets the info describing an i/o thread current state. */
790
672
UNIV_INTERN
791
673
void
792
674
srv_set_io_thread_op_info(
793
675
/*======================*/
794
 
        ulint           i,      /*!< in: the 'segment' of the i/o thread */
795
 
        const char*     str)    /*!< in: constant char string describing the
 
676
        ulint           i,      /* in: the 'segment' of the i/o thread */
 
677
        const char*     str)    /* in: constant char string describing the
796
678
                                state */
797
679
{
798
680
        ut_a(i < SRV_MAX_N_IO_THREADS);
800
682
        srv_io_thread_op_info[i] = str;
801
683
}
802
684
 
803
 
/*********************************************************************//**
 
685
/*************************************************************************
804
686
Accessor function to get pointer to n'th slot in the server thread
805
 
table.
806
 
@return pointer to the slot */
 
687
table. */
807
688
static
808
689
srv_slot_t*
809
690
srv_table_get_nth_slot(
810
691
/*===================*/
811
 
        ulint   index)          /*!< in: index of the slot */
 
692
                                /* out: pointer to the slot */
 
693
        ulint   index)          /* in: index of the slot */
812
694
{
813
695
        ut_a(index < OS_THREAD_MAX_N);
814
696
 
815
697
        return(srv_sys->threads + index);
816
698
}
817
699
 
818
 
/*********************************************************************//**
819
 
Gets the number of threads in the system.
820
 
@return sum of srv_n_threads[] */
 
700
#ifndef UNIV_HOTBACKUP
 
701
/*************************************************************************
 
702
Gets the number of threads in the system. */
821
703
UNIV_INTERN
822
704
ulint
823
705
srv_get_n_threads(void)
838
720
        return(n_threads);
839
721
}
840
722
 
841
 
/*********************************************************************//**
 
723
/*************************************************************************
842
724
Reserves a slot in the thread table for the current thread. Also creates the
843
725
thread local storage struct for the current thread. NOTE! The server mutex
844
 
has to be reserved by the caller!
845
 
@return reserved slot index */
 
726
has to be reserved by the caller! */
846
727
static
847
728
ulint
848
729
srv_table_reserve_slot(
849
730
/*===================*/
850
 
        enum srv_thread_type    type)   /*!< in: type of the thread */
 
731
                                        /* out: reserved slot index */
 
732
        enum srv_thread_type    type)   /* in: type of the thread */
851
733
{
852
734
        srv_slot_t*     slot;
853
735
        ulint           i;
878
760
        return(i);
879
761
}
880
762
 
881
 
/*********************************************************************//**
 
763
/*************************************************************************
882
764
Suspends the calling thread to wait for the event in its thread slot.
883
 
NOTE! The server mutex has to be reserved by the caller!
884
 
@return event for the calling thread to wait */
 
765
NOTE! The server mutex has to be reserved by the caller! */
885
766
static
886
767
os_event_t
887
768
srv_suspend_thread(void)
888
769
/*====================*/
 
770
                        /* out: event for the calling thread to wait */
889
771
{
890
772
        srv_slot_t*             slot;
891
773
        os_event_t              event;
921
803
 
922
804
        return(event);
923
805
}
 
806
#endif /* !UNIV_HOTBACKUP */
924
807
 
925
 
/*********************************************************************//**
 
808
/*************************************************************************
926
809
Releases threads of the type given from suspension in the thread table.
927
 
NOTE! The server mutex has to be reserved by the caller!
928
 
@return number of threads released: this may be less than n if not
929
 
enough threads were suspended at the moment */
 
810
NOTE! The server mutex has to be reserved by the caller! */
930
811
UNIV_INTERN
931
812
ulint
932
813
srv_release_threads(
933
814
/*================*/
934
 
        enum srv_thread_type    type,   /*!< in: thread type */
935
 
        ulint                   n)      /*!< in: number of threads to release */
 
815
                                        /* out: number of threads
 
816
                                        released: this may be < n if
 
817
                                        not enough threads were
 
818
                                        suspended at the moment */
 
819
        enum srv_thread_type    type,   /* in: thread type */
 
820
        ulint                   n)      /* in: number of threads to release */
936
821
{
937
822
        srv_slot_t*     slot;
938
823
        ulint           i;
974
859
        return(count);
975
860
}
976
861
 
977
 
/*********************************************************************//**
978
 
Returns the calling thread type.
979
 
@return SRV_COM, ... */
 
862
/*************************************************************************
 
863
Returns the calling thread type. */
980
864
UNIV_INTERN
981
865
enum srv_thread_type
982
866
srv_get_thread_type(void)
983
867
/*=====================*/
 
868
                        /* out: SRV_COM, ... */
984
869
{
985
870
        ulint                   slot_no;
986
871
        srv_slot_t*             slot;
1002
887
        return(type);
1003
888
}
1004
889
 
1005
 
/*********************************************************************//**
 
890
/*************************************************************************
1006
891
Initializes the server. */
1007
892
UNIV_INTERN
1008
893
void
1011
896
{
1012
897
        srv_conc_slot_t*        conc_slot;
1013
898
        srv_slot_t*             slot;
 
899
        dict_table_t*           table;
1014
900
        ulint                   i;
1015
901
 
1016
902
        srv_sys = mem_alloc(sizeof(srv_sys_t));
1017
903
 
1018
904
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
1019
 
        mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
 
905
        mutex_create(&kernel_mutex, SYNC_KERNEL);
1020
906
 
1021
 
        mutex_create(srv_innodb_monitor_mutex_key,
1022
 
                     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
907
        mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
1023
908
 
1024
909
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1025
910
 
1057
942
 
1058
943
        UT_LIST_INIT(srv_sys->tasks);
1059
944
 
1060
 
        /* Create dummy indexes for infimum and supremum records */
1061
 
 
1062
 
        dict_ind_init();
 
945
        /* create dummy table and index for old-style infimum and supremum */
 
946
        table = dict_mem_table_create("SYS_DUMMY1",
 
947
                                      DICT_HDR_SPACE, 1, 0);
 
948
        dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
 
949
                               DATA_ENGLISH | DATA_NOT_NULL, 8);
 
950
 
 
951
        srv_sys->dummy_ind1 = dict_mem_index_create(
 
952
                "SYS_DUMMY1", "SYS_DUMMY1", DICT_HDR_SPACE, 0, 1);
 
953
        dict_index_add_col(srv_sys->dummy_ind1, table,
 
954
                           dict_table_get_nth_col(table, 0), 0);
 
955
        srv_sys->dummy_ind1->table = table;
 
956
        /* create dummy table and index for new-style infimum and supremum */
 
957
        table = dict_mem_table_create("SYS_DUMMY2",
 
958
                                      DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
 
959
        dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
 
960
                               DATA_ENGLISH | DATA_NOT_NULL, 8);
 
961
        srv_sys->dummy_ind2 = dict_mem_index_create(
 
962
                "SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
 
963
        dict_index_add_col(srv_sys->dummy_ind2, table,
 
964
                           dict_table_get_nth_col(table, 0), 0);
 
965
        srv_sys->dummy_ind2->table = table;
 
966
 
 
967
        /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
 
968
        srv_sys->dummy_ind1->cached = srv_sys->dummy_ind2->cached = TRUE;
1063
969
 
1064
970
        /* Init the server concurrency restriction data structures */
1065
971
 
1080
986
        trx_i_s_cache_init(trx_i_s_cache);
1081
987
}
1082
988
 
1083
 
/*********************************************************************//**
1084
 
Frees the data structures created in srv_init(). */
 
989
/*************************************************************************
 
990
Frees the OS fast mutex created in srv_init(). */
1085
991
UNIV_INTERN
1086
992
void
1087
993
srv_free(void)
1088
994
/*==========*/
1089
995
{
1090
996
        os_fast_mutex_free(&srv_conc_mutex);
1091
 
        mem_free(srv_conc_slots);
1092
 
        srv_conc_slots = NULL;
1093
 
 
1094
 
        mem_free(srv_sys->threads);
1095
 
        mem_free(srv_sys);
1096
 
        srv_sys = NULL;
1097
 
 
1098
 
        mem_free(kernel_mutex_temp);
1099
 
        kernel_mutex_temp = NULL;
1100
 
        mem_free(srv_mysql_table);
1101
 
        srv_mysql_table = NULL;
1102
 
 
1103
 
        trx_i_s_cache_free(trx_i_s_cache);
1104
997
}
1105
998
 
1106
 
/*********************************************************************//**
 
999
/*************************************************************************
1107
1000
Initializes the synchronization primitives, memory system, and the thread
1108
1001
local storage. */
1109
1002
UNIV_INTERN
1112
1005
/*==================*/
1113
1006
{
1114
1007
        ut_mem_init();
1115
 
        /* Reset the system variables in the recovery module. */
1116
 
        recv_sys_var_init();
1117
1008
        os_sync_init();
1118
1009
        sync_init();
1119
1010
        mem_init(srv_mem_pool_size);
1125
1016
/* Maximum allowable purge history length.  <=0 means 'infinite'. */
1126
1017
UNIV_INTERN ulong       srv_max_purge_lag               = 0;
1127
1018
 
1128
 
/*********************************************************************//**
 
1019
/*************************************************************************
1129
1020
Puts an OS thread to wait if there are too many concurrent threads
1130
1021
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
1131
1022
UNIV_INTERN
1132
1023
void
1133
1024
srv_conc_enter_innodb(
1134
1025
/*==================*/
1135
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1026
        trx_t*  trx)    /* in: transaction object associated with the
1136
1027
                        thread */
1137
1028
{
1138
1029
        ibool                   has_slept = FALSE;
1285
1176
        os_fast_mutex_unlock(&srv_conc_mutex);
1286
1177
}
1287
1178
 
1288
 
/*********************************************************************//**
 
1179
/*************************************************************************
1289
1180
This lets a thread enter InnoDB regardless of the number of threads inside
1290
1181
InnoDB. This must be called when a thread ends a lock wait. */
1291
1182
UNIV_INTERN
1292
1183
void
1293
1184
srv_conc_force_enter_innodb(
1294
1185
/*========================*/
1295
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1186
        trx_t*  trx)    /* in: transaction object associated with the
1296
1187
                        thread */
1297
1188
{
1298
1189
        if (UNIV_LIKELY(!srv_thread_concurrency)) {
1311
1202
        os_fast_mutex_unlock(&srv_conc_mutex);
1312
1203
}
1313
1204
 
1314
 
/*********************************************************************//**
 
1205
/*************************************************************************
1315
1206
This must be called when a thread exits InnoDB in a lock wait or at the
1316
1207
end of an SQL statement. */
1317
1208
UNIV_INTERN
1318
1209
void
1319
1210
srv_conc_force_exit_innodb(
1320
1211
/*=======================*/
1321
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1212
        trx_t*  trx)    /* in: transaction object associated with the
1322
1213
                        thread */
1323
1214
{
1324
1215
        srv_conc_slot_t*        slot    = NULL;
1368
1259
        }
1369
1260
}
1370
1261
 
1371
 
/*********************************************************************//**
 
1262
/*************************************************************************
1372
1263
This must be called when a thread exits InnoDB. */
1373
1264
UNIV_INTERN
1374
1265
void
1375
1266
srv_conc_exit_innodb(
1376
1267
/*=================*/
1377
 
        trx_t*  trx)    /*!< in: transaction object associated with the
 
1268
        trx_t*  trx)    /* in: transaction object associated with the
1378
1269
                        thread */
1379
1270
{
1380
1271
        if (trx->n_tickets_to_enter_innodb > 0) {
1393
1284
 
1394
1285
/*========================================================================*/
1395
1286
 
1396
 
/*********************************************************************//**
1397
 
Normalizes init parameter values to use units we use inside InnoDB.
1398
 
@return DB_SUCCESS or error code */
 
1287
/*************************************************************************
 
1288
Normalizes init parameter values to use units we use inside InnoDB. */
1399
1289
static
1400
1290
ulint
1401
1291
srv_normalize_init_values(void)
1402
1292
/*===========================*/
 
1293
                                /* out: DB_SUCCESS or error code */
1403
1294
{
1404
1295
        ulint   n;
1405
1296
        ulint   i;
1423
1314
        return(DB_SUCCESS);
1424
1315
}
1425
1316
 
1426
 
/*********************************************************************//**
1427
 
Boots the InnoDB server.
1428
 
@return DB_SUCCESS or error code */
 
1317
/*************************************************************************
 
1318
Boots the InnoDB server. */
1429
1319
UNIV_INTERN
1430
1320
ulint
1431
1321
srv_boot(void)
1432
1322
/*==========*/
 
1323
                        /* out: DB_SUCCESS or error code */
1433
1324
{
1434
1325
        ulint   err;
1435
1326
 
1454
1345
        return(DB_SUCCESS);
1455
1346
}
1456
1347
 
1457
 
/*********************************************************************//**
 
1348
#ifndef UNIV_HOTBACKUP
 
1349
/*************************************************************************
1458
1350
Reserves a slot in the thread table for the current MySQL OS thread.
1459
 
NOTE! The kernel mutex has to be reserved by the caller!
1460
 
@return reserved slot */
 
1351
NOTE! The kernel mutex has to be reserved by the caller! */
1461
1352
static
1462
1353
srv_slot_t*
1463
1354
srv_table_reserve_slot_for_mysql(void)
1464
1355
/*==================================*/
 
1356
                        /* out: reserved slot */
1465
1357
{
1466
1358
        srv_slot_t*     slot;
1467
1359
        ulint           i;
1518
1410
 
1519
1411
        return(slot);
1520
1412
}
 
1413
#endif /* !UNIV_HOTBACKUP */
1521
1414
 
1522
 
/***************************************************************//**
 
1415
/*******************************************************************
1523
1416
Puts a MySQL OS thread to wait for a lock to be released. If an error
1524
1417
occurs during the wait trx->error_state associated with thr is
1525
1418
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
1529
1422
void
1530
1423
srv_suspend_mysql_thread(
1531
1424
/*=====================*/
1532
 
        que_thr_t*      thr)    /*!< in: query thread associated with the MySQL
 
1425
        que_thr_t*      thr)    /* in: query thread associated with the MySQL
1533
1426
                                OS thread */
1534
1427
{
 
1428
#ifndef UNIV_HOTBACKUP
1535
1429
        srv_slot_t*     slot;
1536
1430
        os_event_t      event;
1537
1431
        double          wait_time;
1620
1514
                row_mysql_unfreeze_data_dictionary(trx);
1621
1515
                break;
1622
1516
        case RW_X_LATCH:
1623
 
                /* There should never be a lock wait when the
1624
 
                dictionary latch is reserved in X mode.  Dictionary
1625
 
                transactions should only acquire locks on dictionary
1626
 
                tables, not other tables. All access to dictionary
1627
 
                tables should be covered by dictionary
1628
 
                transactions. */
1629
 
                ut_print_timestamp(stderr);
1630
 
                fputs("  InnoDB: Error: dict X latch held in "
1631
 
                      "srv_suspend_mysql_thread\n", stderr);
1632
 
                /* This should never occur. This incorrect handling
1633
 
                was added in the early development of
1634
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1635
1517
                /* Release fast index creation latch */
1636
1518
                row_mysql_unlock_data_dictionary(trx);
1637
1519
                break;
1651
1533
                row_mysql_freeze_data_dictionary(trx);
1652
1534
                break;
1653
1535
        case RW_X_LATCH:
1654
 
                /* This should never occur. This incorrect handling
1655
 
                was added in the early development of
1656
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1657
1536
                row_mysql_lock_data_dictionary(trx);
1658
1537
                break;
1659
1538
        }
1690
1569
                    start_time != -1 && finish_time != -1) {
1691
1570
                        srv_n_lock_max_wait_time = diff_time;
1692
1571
                }
1693
 
 
1694
 
                /* Record the lock wait time for this thread */
1695
 
                thd_set_lock_wait_time(trx->mysql_thd, diff_time);
1696
1572
        }
1697
1573
 
1698
1574
        if (trx->was_chosen_as_deadlock_victim) {
1714
1590
 
1715
1591
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1716
1592
        }
1717
 
 
1718
 
        if (trx_is_interrupted(trx)) {
1719
 
 
1720
 
                trx->error_state = DB_INTERRUPTED;
1721
 
        }
 
1593
#else /* UNIV_HOTBACKUP */
 
1594
        /* This function depends on MySQL code that is not included in
 
1595
        InnoDB Hot Backup builds.  Besides, this function should never
 
1596
        be called in InnoDB Hot Backup. */
 
1597
        ut_error;
 
1598
#endif /* UNIV_HOTBACKUP */
1722
1599
}
1723
1600
 
1724
 
/********************************************************************//**
 
1601
/************************************************************************
1725
1602
Releases a MySQL OS thread waiting for a lock to be released, if the
1726
1603
thread is already suspended. */
1727
1604
UNIV_INTERN
1728
1605
void
1729
1606
srv_release_mysql_thread_if_suspended(
1730
1607
/*==================================*/
1731
 
        que_thr_t*      thr)    /*!< in: query thread associated with the
 
1608
        que_thr_t*      thr)    /* in: query thread associated with the
1732
1609
                                MySQL OS thread  */
1733
1610
{
 
1611
#ifndef UNIV_HOTBACKUP
1734
1612
        srv_slot_t*     slot;
1735
1613
        ulint           i;
1736
1614
 
1750
1628
        }
1751
1629
 
1752
1630
        /* not found */
 
1631
#else /* UNIV_HOTBACKUP */
 
1632
        /* This function depends on MySQL code that is not included in
 
1633
        InnoDB Hot Backup builds.  Besides, this function should never
 
1634
        be called in InnoDB Hot Backup. */
 
1635
        ut_error;
 
1636
#endif /* UNIV_HOTBACKUP */
1753
1637
}
1754
1638
 
1755
 
/******************************************************************//**
 
1639
#ifndef UNIV_HOTBACKUP
 
1640
/**********************************************************************
1756
1641
Refreshes the values used to calculate per-second averages. */
1757
1642
static
1758
1643
void
1770
1655
 
1771
1656
        log_refresh_stats();
1772
1657
 
1773
 
        buf_refresh_io_stats_all();
 
1658
        buf_refresh_io_stats();
1774
1659
 
1775
1660
        srv_n_rows_inserted_old = srv_n_rows_inserted;
1776
1661
        srv_n_rows_updated_old = srv_n_rows_updated;
1780
1665
        mutex_exit(&srv_innodb_monitor_mutex);
1781
1666
}
1782
1667
 
1783
 
/******************************************************************//**
1784
 
Outputs to a file the output of the InnoDB Monitor.
1785
 
@return FALSE if not all information printed
1786
 
due to failure to obtain necessary mutex */
 
1668
/**********************************************************************
 
1669
Outputs to a file the output of the InnoDB Monitor. */
1787
1670
UNIV_INTERN
1788
 
ibool
 
1671
void
1789
1672
srv_printf_innodb_monitor(
1790
1673
/*======================*/
1791
 
        FILE*   file,           /*!< in: output stream */
1792
 
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1793
 
        ulint*  trx_start,      /*!< out: file position of the start of
 
1674
        FILE*   file,           /* in: output stream */
 
1675
        ulint*  trx_start,      /* out: file position of the start of
1794
1676
                                the list of active transactions */
1795
 
        ulint*  trx_end)        /*!< out: file position of the end of
 
1677
        ulint*  trx_end)        /* out: file position of the end of
1796
1678
                                the list of active transactions */
1797
1679
{
1798
1680
        double  time_elapsed;
1799
1681
        time_t  current_time;
1800
1682
        ulint   n_reserved;
1801
 
        ibool   ret;
1802
1683
 
1803
1684
        mutex_enter(&srv_innodb_monitor_mutex);
1804
1685
 
1822
1703
                "Per second averages calculated from the last %lu seconds\n",
1823
1704
                (ulong)time_elapsed);
1824
1705
 
1825
 
        fputs("-----------------\n"
1826
 
              "BACKGROUND THREAD\n"
1827
 
              "-----------------\n", file);
1828
 
        srv_print_master_thread_info(file);
1829
 
 
1830
1706
        fputs("----------\n"
1831
1707
              "SEMAPHORES\n"
1832
1708
              "----------\n", file);
1848
1724
 
1849
1725
        mutex_exit(&dict_foreign_err_mutex);
1850
1726
 
1851
 
        /* Only if lock_print_info_summary proceeds correctly,
1852
 
        before we call the lock_print_info_all_transactions
1853
 
        to print all the lock information. */
1854
 
        ret = lock_print_info_summary(file, nowait);
1855
 
 
1856
 
        if (ret) {
1857
 
                if (trx_start) {
1858
 
                        long    t = ftell(file);
1859
 
                        if (t < 0) {
1860
 
                                *trx_start = ULINT_UNDEFINED;
1861
 
                        } else {
1862
 
                                *trx_start = (ulint) t;
1863
 
                        }
1864
 
                }
1865
 
                lock_print_info_all_transactions(file);
1866
 
                if (trx_end) {
1867
 
                        long    t = ftell(file);
1868
 
                        if (t < 0) {
1869
 
                                *trx_end = ULINT_UNDEFINED;
1870
 
                        } else {
1871
 
                                *trx_end = (ulint) t;
1872
 
                        }
1873
 
                }
1874
 
        }
1875
 
 
 
1727
        lock_print_info_summary(file);
 
1728
        if (trx_start) {
 
1729
                long    t = ftell(file);
 
1730
                if (t < 0) {
 
1731
                        *trx_start = ULINT_UNDEFINED;
 
1732
                } else {
 
1733
                        *trx_start = (ulint) t;
 
1734
                }
 
1735
        }
 
1736
        lock_print_info_all_transactions(file);
 
1737
        if (trx_end) {
 
1738
                long    t = ftell(file);
 
1739
                if (t < 0) {
 
1740
                        *trx_end = ULINT_UNDEFINED;
 
1741
                } else {
 
1742
                        *trx_end = (ulint) t;
 
1743
                }
 
1744
        }
1876
1745
        fputs("--------\n"
1877
1746
              "FILE I/O\n"
1878
1747
              "--------\n", file);
1970
1839
              "============================\n", file);
1971
1840
        mutex_exit(&srv_innodb_monitor_mutex);
1972
1841
        fflush(file);
1973
 
 
1974
 
        return(ret);
1975
1842
}
1976
1843
 
1977
 
/******************************************************************//**
 
1844
/**********************************************************************
1978
1845
Function to pass InnoDB status variables to MySQL */
1979
1846
UNIV_INTERN
1980
1847
void
1981
1848
srv_export_innodb_status(void)
1982
 
/*==========================*/
1983
1849
{
1984
 
        buf_pool_stat_t stat;
1985
 
        ulint           LRU_len;
1986
 
        ulint           free_len;
1987
 
        ulint           flush_list_len;
1988
 
 
1989
 
        buf_get_total_stat(&stat);
1990
 
        buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
1991
 
 
1992
1850
        mutex_enter(&srv_innodb_monitor_mutex);
1993
1851
 
1994
1852
        export_vars.innodb_data_pending_reads
2003
1861
        export_vars.innodb_data_reads = os_n_file_reads;
2004
1862
        export_vars.innodb_data_writes = os_n_file_writes;
2005
1863
        export_vars.innodb_data_written = srv_data_written;
2006
 
        export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
 
1864
        export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
2007
1865
        export_vars.innodb_buffer_pool_write_requests
2008
1866
                = srv_buf_pool_write_requests;
2009
1867
        export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
2010
1868
        export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
2011
1869
        export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
2012
 
        export_vars.innodb_buffer_pool_read_ahead
2013
 
                = stat.n_ra_pages_read;
2014
 
        export_vars.innodb_buffer_pool_read_ahead_evicted
2015
 
                = stat.n_ra_pages_evicted;
2016
 
        export_vars.innodb_buffer_pool_pages_data = LRU_len;
2017
 
        export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
2018
 
        export_vars.innodb_buffer_pool_pages_free = free_len;
 
1870
        export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
 
1871
        export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
 
1872
        export_vars.innodb_buffer_pool_pages_data
 
1873
                = UT_LIST_GET_LEN(buf_pool->LRU);
 
1874
        export_vars.innodb_buffer_pool_pages_dirty
 
1875
                = UT_LIST_GET_LEN(buf_pool->flush_list);
 
1876
        export_vars.innodb_buffer_pool_pages_free
 
1877
                = UT_LIST_GET_LEN(buf_pool->free);
2019
1878
#ifdef UNIV_DEBUG
2020
1879
        export_vars.innodb_buffer_pool_pages_latched
2021
1880
                = buf_get_latched_pages_number();
2022
1881
#endif /* UNIV_DEBUG */
2023
 
        export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
 
1882
        export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
2024
1883
 
2025
 
        export_vars.innodb_buffer_pool_pages_misc
2026
 
                = buf_pool_get_n_pages() - LRU_len - free_len;
2027
 
#ifdef HAVE_ATOMIC_BUILTINS
 
1884
        export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
 
1885
                - UT_LIST_GET_LEN(buf_pool->LRU)
 
1886
                - UT_LIST_GET_LEN(buf_pool->free);
 
1887
#ifdef HAVE_GCC_ATOMIC_BUILTINS
2028
1888
        export_vars.innodb_have_atomic_builtins = 1;
2029
1889
#else
2030
1890
        export_vars.innodb_have_atomic_builtins = 0;
2039
1899
        export_vars.innodb_log_writes = srv_log_writes;
2040
1900
        export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
2041
1901
        export_vars.innodb_dblwr_writes = srv_dblwr_writes;
2042
 
        export_vars.innodb_pages_created = stat.n_pages_created;
2043
 
        export_vars.innodb_pages_read = stat.n_pages_read;
2044
 
        export_vars.innodb_pages_written = stat.n_pages_written;
 
1902
        export_vars.innodb_pages_created = buf_pool->n_pages_created;
 
1903
        export_vars.innodb_pages_read = buf_pool->n_pages_read;
 
1904
        export_vars.innodb_pages_written = buf_pool->n_pages_written;
2045
1905
        export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
2046
1906
        export_vars.innodb_row_lock_current_waits
2047
1907
                = srv_n_lock_wait_current_count;
2058
1918
        export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2059
1919
        export_vars.innodb_rows_updated = srv_n_rows_updated;
2060
1920
        export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2061
 
        export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
2062
1921
 
2063
1922
        mutex_exit(&srv_innodb_monitor_mutex);
2064
1923
}
2065
1924
 
2066
 
/*********************************************************************//**
2067
 
A thread which prints the info output by various InnoDB monitors.
2068
 
@return a dummy parameter */
 
1925
/*************************************************************************
 
1926
A thread which wakes up threads whose lock wait may have lasted too long.
 
1927
This also prints the info output by various InnoDB monitors. */
2069
1928
UNIV_INTERN
2070
1929
os_thread_ret_t
2071
 
srv_monitor_thread(
2072
 
/*===============*/
 
1930
srv_lock_timeout_and_monitor_thread(
 
1931
/*================================*/
 
1932
                        /* out: a dummy parameter */
2073
1933
        void*   arg __attribute__((unused)))
2074
 
                        /*!< in: a dummy parameter required by
 
1934
                        /* in: a dummy parameter required by
2075
1935
                        os_thread_create */
2076
1936
{
 
1937
        srv_slot_t*     slot;
2077
1938
        double          time_elapsed;
2078
1939
        time_t          current_time;
2079
1940
        time_t          last_table_monitor_time;
2080
1941
        time_t          last_tablespace_monitor_time;
2081
1942
        time_t          last_monitor_time;
2082
 
        ulint           mutex_skipped;
2083
 
        ibool           last_srv_print_monitor;
 
1943
        ibool           some_waits;
 
1944
        double          wait_time;
 
1945
        ulint           i;
2084
1946
 
2085
1947
#ifdef UNIV_DEBUG_THREAD_CREATION
2086
1948
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2087
1949
                os_thread_pf(os_thread_get_curr_id()));
2088
1950
#endif
2089
 
 
2090
 
#ifdef UNIV_PFS_THREAD
2091
 
        pfs_register_thread(srv_monitor_thread_key);
2092
 
#endif
2093
 
 
2094
1951
        UT_NOT_USED(arg);
2095
1952
        srv_last_monitor_time = time(NULL);
2096
1953
        last_table_monitor_time = time(NULL);
2097
1954
        last_tablespace_monitor_time = time(NULL);
2098
1955
        last_monitor_time = time(NULL);
2099
 
        mutex_skipped = 0;
2100
 
        last_srv_print_monitor = srv_print_innodb_monitor;
2101
1956
loop:
2102
 
        srv_monitor_active = TRUE;
2103
 
 
2104
 
        /* Wake up every 5 seconds to see if we need to print
2105
 
        monitor information. */
2106
 
 
2107
 
        os_thread_sleep(5000000);
 
1957
        srv_lock_timeout_and_monitor_active = TRUE;
 
1958
 
 
1959
        /* When someone is waiting for a lock, we wake up every second
 
1960
        and check if a timeout has passed for a lock wait */
 
1961
 
 
1962
        os_thread_sleep(1000000);
2108
1963
 
2109
1964
        current_time = time(NULL);
2110
1965
 
2114
1969
                last_monitor_time = time(NULL);
2115
1970
 
2116
1971
                if (srv_print_innodb_monitor) {
2117
 
                        /* Reset mutex_skipped counter everytime
2118
 
                        srv_print_innodb_monitor changes. This is to
2119
 
                        ensure we will not be blocked by kernel_mutex
2120
 
                        for short duration information printing,
2121
 
                        such as requested by sync_array_print_long_waits() */
2122
 
                        if (!last_srv_print_monitor) {
2123
 
                                mutex_skipped = 0;
2124
 
                                last_srv_print_monitor = TRUE;
2125
 
                        }
2126
 
 
2127
 
                        if (!srv_printf_innodb_monitor(stderr,
2128
 
                                                MUTEX_NOWAIT(mutex_skipped),
2129
 
                                                NULL, NULL)) {
2130
 
                                mutex_skipped++;
2131
 
                        } else {
2132
 
                                /* Reset the counter */
2133
 
                                mutex_skipped = 0;
2134
 
                        }
2135
 
                } else {
2136
 
                        last_srv_print_monitor = FALSE;
 
1972
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
2137
1973
                }
2138
1974
 
2139
 
 
2140
1975
                if (srv_innodb_status) {
2141
1976
                        mutex_enter(&srv_monitor_file_mutex);
2142
1977
                        rewind(srv_monitor_file);
2143
 
                        if (!srv_printf_innodb_monitor(srv_monitor_file,
2144
 
                                                MUTEX_NOWAIT(mutex_skipped),
2145
 
                                                NULL, NULL)) {
2146
 
                                mutex_skipped++;
2147
 
                        } else {
2148
 
                                mutex_skipped = 0;
2149
 
                        }
2150
 
 
 
1978
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
 
1979
                                                  NULL);
2151
1980
                        os_file_set_eof(srv_monitor_file);
2152
1981
                        mutex_exit(&srv_monitor_file_mutex);
2153
1982
                }
2200
2029
                }
2201
2030
        }
2202
2031
 
2203
 
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2204
 
                goto exit_func;
2205
 
        }
2206
 
 
2207
 
        if (srv_print_innodb_monitor
2208
 
            || srv_print_innodb_lock_monitor
2209
 
            || srv_print_innodb_tablespace_monitor
2210
 
            || srv_print_innodb_table_monitor) {
2211
 
                goto loop;
2212
 
        }
2213
 
 
2214
 
        srv_monitor_active = FALSE;
2215
 
 
2216
 
        goto loop;
2217
 
 
2218
 
exit_func:
2219
 
        srv_monitor_active = FALSE;
2220
 
 
2221
 
        /* We count the number of threads in os_thread_exit(). A created
2222
 
        thread should always use that to exit and not use return() to exit. */
2223
 
 
2224
 
        os_thread_exit(NULL);
2225
 
 
2226
 
        OS_THREAD_DUMMY_RETURN;
2227
 
}
2228
 
 
2229
 
/*********************************************************************//**
2230
 
A thread which wakes up threads whose lock wait may have lasted too long.
2231
 
@return a dummy parameter */
2232
 
UNIV_INTERN
2233
 
os_thread_ret_t
2234
 
srv_lock_timeout_thread(
2235
 
/*====================*/
2236
 
        void*   arg __attribute__((unused)))
2237
 
                        /* in: a dummy parameter required by
2238
 
                        os_thread_create */
2239
 
{
2240
 
        srv_slot_t*     slot;
2241
 
        ibool           some_waits;
2242
 
        double          wait_time;
2243
 
        ulint           i;
2244
 
 
2245
 
#ifdef UNIV_PFS_THREAD
2246
 
        pfs_register_thread(srv_lock_timeout_thread_key);
2247
 
#endif
2248
 
 
2249
 
loop:
2250
 
        /* When someone is waiting for a lock, we wake up every second
2251
 
        and check if a timeout has passed for a lock wait */
2252
 
 
2253
 
        os_thread_sleep(1000000);
2254
 
 
2255
 
        srv_lock_timeout_active = TRUE;
2256
 
 
2257
2032
        mutex_enter(&kernel_mutex);
2258
2033
 
2259
2034
        some_waits = FALSE;
2277
2052
                        lock_wait_timeout = thd_lock_wait_timeout(
2278
2053
                                trx->mysql_thd);
2279
2054
 
2280
 
                        if (trx_is_interrupted(trx)
2281
 
                            || (lock_wait_timeout < 100000000
2282
 
                                && (wait_time > (double) lock_wait_timeout
2283
 
                                    || wait_time < 0))) {
 
2055
                        if (lock_wait_timeout < 100000000
 
2056
                            && (wait_time > (double) lock_wait_timeout
 
2057
                                || wait_time < 0)) {
2284
2058
 
2285
2059
                                /* Timeout exceeded or a wrap-around in system
2286
2060
                                time counter: cancel the lock request queued
2305
2079
                goto exit_func;
2306
2080
        }
2307
2081
 
2308
 
        if (some_waits) {
 
2082
        if (some_waits || srv_print_innodb_monitor
 
2083
            || srv_print_innodb_lock_monitor
 
2084
            || srv_print_innodb_tablespace_monitor
 
2085
            || srv_print_innodb_table_monitor) {
2309
2086
                goto loop;
2310
2087
        }
2311
2088
 
2312
 
        srv_lock_timeout_active = FALSE;
 
2089
        /* No one was waiting for a lock and no monitor was active:
 
2090
        suspend this thread */
 
2091
 
 
2092
        srv_lock_timeout_and_monitor_active = FALSE;
2313
2093
 
2314
2094
#if 0
2315
2095
        /* The following synchronisation is disabled, since
2319
2099
        goto loop;
2320
2100
 
2321
2101
exit_func:
2322
 
        srv_lock_timeout_active = FALSE;
 
2102
        srv_lock_timeout_and_monitor_active = FALSE;
2323
2103
 
2324
2104
        /* We count the number of threads in os_thread_exit(). A created
2325
2105
        thread should always use that to exit and not use return() to exit. */
2329
2109
        OS_THREAD_DUMMY_RETURN;
2330
2110
}
2331
2111
 
2332
 
/*********************************************************************//**
 
2112
/*************************************************************************
2333
2113
A thread which prints warnings about semaphore waits which have lasted
2334
 
too long. These can be used to track bugs which cause hangs.
2335
 
@return a dummy parameter */
 
2114
too long. These can be used to track bugs which cause hangs. */
2336
2115
UNIV_INTERN
2337
2116
os_thread_ret_t
2338
2117
srv_error_monitor_thread(
2339
2118
/*=====================*/
 
2119
                        /* out: a dummy parameter */
2340
2120
        void*   arg __attribute__((unused)))
2341
 
                        /*!< in: a dummy parameter required by
 
2121
                        /* in: a dummy parameter required by
2342
2122
                        os_thread_create */
2343
2123
{
2344
2124
        /* number of successive fatal timeouts observed */
2352
2132
        fprintf(stderr, "Error monitor thread starts, id %lu\n",
2353
2133
                os_thread_pf(os_thread_get_curr_id()));
2354
2134
#endif
2355
 
 
2356
 
#ifdef UNIV_PFS_THREAD
2357
 
        pfs_register_thread(srv_error_monitor_thread_key);
2358
 
#endif
2359
 
 
2360
2135
loop:
2361
2136
        srv_error_monitor_active = TRUE;
2362
2137
 
2386
2161
        }
2387
2162
 
2388
2163
        /* Update the statistics collected for deciding LRU
2389
 
        eviction policy. */
 
2164
        eviction policy. */
2390
2165
        buf_LRU_stat_update();
2391
2166
 
2392
 
        /* Update the statistics collected for flush rate policy. */
2393
 
        buf_flush_stat_update();
2394
 
 
2395
2167
        /* In case mutex_exit is not a memory barrier, it is
2396
2168
        theoretically possible some threads are left waiting though
2397
2169
        the semaphore is already released. Wake up those threads: */
2398
 
 
 
2170
        
2399
2171
        sync_arr_wake_threads_if_sema_free();
2400
2172
 
2401
2173
        if (sync_array_print_long_waits()) {
2437
2209
        OS_THREAD_DUMMY_RETURN;
2438
2210
}
2439
2211
 
2440
 
/**********************************************************************//**
2441
 
Check whether any background thread is active.
2442
 
@return FALSE if all are are suspended or have exited. */
2443
 
UNIV_INTERN
2444
 
ibool
2445
 
srv_is_any_background_thread_active(void)
2446
 
/*=====================================*/
2447
 
{
2448
 
        ulint   i;
2449
 
        ibool   ret = FALSE;
2450
 
 
2451
 
        mutex_enter(&kernel_mutex);
2452
 
 
2453
 
        for (i = SRV_COM; i <= SRV_MASTER; ++i) {
2454
 
                if (srv_n_threads_active[i] != 0) {
2455
 
                        ret = TRUE;
2456
 
                        break;
2457
 
                }
2458
 
        }
2459
 
 
2460
 
        mutex_exit(&kernel_mutex);
2461
 
 
2462
 
        return(ret);
2463
 
}
2464
 
 
2465
 
/*******************************************************************//**
 
2212
/***********************************************************************
2466
2213
Tells the InnoDB server that there has been activity in the database
2467
2214
and wakes up the master thread if it is suspended (not sleeping). Used
2468
2215
in the MySQL interface. Note that there is a small chance that the master
2469
 
thread stays suspended (we do not protect our operation with the
2470
 
srv_sys_t->mutex, for performance reasons). */
 
2216
thread stays suspended (we do not protect our operation with the kernel
 
2217
mutex, for performace reasons). */
2471
2218
UNIV_INTERN
2472
2219
void
2473
2220
srv_active_wake_master_thread(void)
2485
2232
        }
2486
2233
}
2487
2234
 
2488
 
/*******************************************************************//**
2489
 
Tells the purge thread that there has been activity in the database
2490
 
and wakes up the purge thread if it is suspended (not sleeping).  Note
2491
 
that there is a small chance that the purge thread stays suspended
2492
 
(we do not protect our operation with the kernel mutex, for
2493
 
performace reasons). */
2494
 
UNIV_INTERN
2495
 
void
2496
 
srv_wake_purge_thread_if_not_active(void)
2497
 
/*=====================================*/
2498
 
{
2499
 
        ut_ad(!mutex_own(&kernel_mutex));
2500
 
 
2501
 
        if (srv_n_purge_threads > 0
2502
 
            && srv_n_threads_active[SRV_WORKER] == 0) {
2503
 
 
2504
 
                mutex_enter(&kernel_mutex);
2505
 
 
2506
 
                srv_release_threads(SRV_WORKER, 1);
2507
 
 
2508
 
                mutex_exit(&kernel_mutex);
2509
 
        }
2510
 
}
2511
 
 
2512
 
/*******************************************************************//**
 
2235
/***********************************************************************
2513
2236
Wakes up the master thread if it is suspended or being suspended. */
2514
2237
UNIV_INTERN
2515
2238
void
2525
2248
        mutex_exit(&kernel_mutex);
2526
2249
}
2527
2250
 
2528
 
/*******************************************************************//**
2529
 
Wakes up the purge thread if it's not already awake. */
2530
 
UNIV_INTERN
2531
 
void
2532
 
srv_wake_purge_thread(void)
2533
 
/*=======================*/
2534
 
{
2535
 
        ut_ad(!mutex_own(&kernel_mutex));
2536
 
 
2537
 
        if (srv_n_purge_threads > 0) {
2538
 
 
2539
 
                mutex_enter(&kernel_mutex);
2540
 
 
2541
 
                srv_release_threads(SRV_WORKER, 1);
2542
 
 
2543
 
                mutex_exit(&kernel_mutex);
2544
 
        }
2545
 
}
2546
 
 
2547
 
/**********************************************************************
2548
 
The master thread is tasked to ensure that flush of log file happens
2549
 
once every second in the background. This is to ensure that not more
2550
 
than one second of trxs are lost in case of crash when
2551
 
innodb_flush_logs_at_trx_commit != 1 */
2552
 
static
2553
 
void
2554
 
srv_sync_log_buffer_in_background(void)
2555
 
/*===================================*/
2556
 
{
2557
 
        time_t  current_time = time(NULL);
2558
 
 
2559
 
        srv_main_thread_op_info = "flushing log";
2560
 
        if (difftime(current_time, srv_last_log_flush_time) >= 1) {
2561
 
                log_buffer_sync_in_background(TRUE);
2562
 
                srv_last_log_flush_time = current_time;
2563
 
                srv_log_writes_and_flush++;
2564
 
        }
2565
 
}
2566
 
 
2567
 
/********************************************************************//**
2568
 
Do a full purge, reconfigure the purge sub-system if a dynamic
2569
 
change is detected. */
2570
 
static
2571
 
void
2572
 
srv_master_do_purge(void)
2573
 
/*=====================*/
2574
 
{
2575
 
        ulint   n_pages_purged;
2576
 
 
2577
 
        ut_ad(!mutex_own(&kernel_mutex));
2578
 
 
2579
 
        ut_a(srv_n_purge_threads == 0);
2580
 
 
2581
 
        do {
2582
 
                /* Check for shutdown and change in purge config. */
2583
 
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2584
 
                        /* Nothing to purge. */
2585
 
                        n_pages_purged = 0;
2586
 
                } else {
2587
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
2588
 
                }
2589
 
 
2590
 
                srv_sync_log_buffer_in_background();
2591
 
 
2592
 
        } while (n_pages_purged > 0);
2593
 
}
2594
 
 
2595
 
/*********************************************************************//**
2596
 
The master thread controlling the server.
2597
 
@return a dummy parameter */
 
2251
/*************************************************************************
 
2252
The master thread controlling the server. */
2598
2253
UNIV_INTERN
2599
2254
os_thread_ret_t
2600
2255
srv_master_thread(
2601
2256
/*==============*/
 
2257
                        /* out: a dummy parameter */
2602
2258
        void*   arg __attribute__((unused)))
2603
 
                        /*!< in: a dummy parameter required by
 
2259
                        /* in: a dummy parameter required by
2604
2260
                        os_thread_create */
2605
2261
{
2606
 
        buf_pool_stat_t buf_stat;
2607
2262
        os_event_t      event;
 
2263
        time_t          last_flush_time;
 
2264
        time_t          current_time;
2608
2265
        ulint           old_activity_count;
2609
2266
        ulint           n_pages_purged  = 0;
2610
2267
        ulint           n_bytes_merged;
2615
2272
        ulint           n_ios_old;
2616
2273
        ulint           n_ios_very_old;
2617
2274
        ulint           n_pend_ios;
2618
 
        ulint           next_itr_time;
 
2275
        ibool           skip_sleep      = FALSE;
2619
2276
        ulint           i;
2620
2277
 
2621
2278
#ifdef UNIV_DEBUG_THREAD_CREATION
2622
2279
        fprintf(stderr, "Master thread starts, id %lu\n",
2623
2280
                os_thread_pf(os_thread_get_curr_id()));
2624
2281
#endif
2625
 
 
2626
 
#ifdef UNIV_PFS_THREAD
2627
 
        pfs_register_thread(srv_master_thread_key);
2628
 
#endif
2629
 
 
2630
2282
        srv_main_thread_process_no = os_proc_get_number();
2631
2283
        srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2632
2284
 
2645
2297
 
2646
2298
        srv_main_thread_op_info = "reserving kernel mutex";
2647
2299
 
2648
 
        buf_get_total_stat(&buf_stat);
2649
 
        n_ios_very_old = log_sys->n_log_ios + buf_stat.n_pages_read
2650
 
                + buf_stat.n_pages_written;
 
2300
        n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2301
                + buf_pool->n_pages_written;
2651
2302
        mutex_enter(&kernel_mutex);
2652
2303
 
2653
2304
        /* Store the user activity counter at the start of this loop */
2663
2314
        /* ---- We run the following loop approximately once per second
2664
2315
        when there is database activity */
2665
2316
 
2666
 
        srv_last_log_flush_time = time(NULL);
2667
 
 
2668
 
        /* Sleep for 1 second on entrying the for loop below the first time. */
2669
 
        next_itr_time = ut_time_ms() + 1000;
 
2317
        skip_sleep = FALSE;
2670
2318
 
2671
2319
        for (i = 0; i < 10; i++) {
2672
 
                ulint   cur_time = ut_time_ms();
2673
 
 
2674
 
                buf_get_total_stat(&buf_stat);
2675
 
 
2676
 
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2677
 
                        + buf_stat.n_pages_written;
2678
 
 
 
2320
                n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2321
                        + buf_pool->n_pages_written;
2679
2322
                srv_main_thread_op_info = "sleeping";
2680
 
                srv_main_1_second_loops++;
2681
 
 
2682
 
                if (next_itr_time > cur_time) {
2683
 
 
2684
 
                        /* Get sleep interval in micro seconds. We use
2685
 
                        ut_min() to avoid long sleep in case of
2686
 
                        wrap around. */
2687
 
                        os_thread_sleep(ut_min(1000000,
2688
 
                                        (next_itr_time - cur_time)
2689
 
                                         * 1000));
2690
 
                        srv_main_sleeps++;
 
2323
 
 
2324
                if (!skip_sleep) {
 
2325
 
 
2326
                        os_thread_sleep(1000000);
2691
2327
                }
2692
2328
 
2693
 
                /* Each iteration should happen at 1 second interval. */
2694
 
                next_itr_time = ut_time_ms() + 1000;
 
2329
                skip_sleep = FALSE;
2695
2330
 
2696
2331
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2697
2332
                can drop tables lazily after there no longer are SELECT
2708
2343
                        goto background_loop;
2709
2344
                }
2710
2345
 
2711
 
                /* Flush logs if needed */
2712
 
                srv_sync_log_buffer_in_background();
 
2346
                /* We flush the log once in a second even if no commit
 
2347
                is issued or the we have specified in my.cnf no flush
 
2348
                at transaction commit */
 
2349
 
 
2350
                srv_main_thread_op_info = "flushing log";
 
2351
                log_buffer_flush_to_disk();
2713
2352
 
2714
2353
                srv_main_thread_op_info = "making checkpoint";
2715
2354
                log_free_check();
2716
2355
 
2717
 
                /* If i/os during one second sleep were less than 5% of
2718
 
                capacity, we assume that there is free disk i/o capacity
2719
 
                available, and it makes sense to do an insert buffer merge. */
 
2356
                /* If there were less than 5 i/os during the
 
2357
                one second sleep, we assume that there is free
 
2358
                disk i/o capacity available, and it makes sense to
 
2359
                do an insert buffer merge. */
2720
2360
 
2721
 
                buf_get_total_stat(&buf_stat);
2722
2361
                n_pend_ios = buf_get_n_pending_ios()
2723
2362
                        + log_sys->n_pending_writes;
2724
 
                n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2725
 
                        + buf_stat.n_pages_written;
2726
 
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2727
 
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
 
2363
                n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2364
                        + buf_pool->n_pages_written;
 
2365
                if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) {
2728
2366
                        srv_main_thread_op_info = "doing insert buffer merge";
2729
 
                        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
2730
 
 
2731
 
                        /* Flush logs if needed */
2732
 
                        srv_sync_log_buffer_in_background();
 
2367
                        ibuf_contract_for_n_pages(
 
2368
                                TRUE, srv_insert_buffer_batch_size / 4);
 
2369
 
 
2370
                        srv_main_thread_op_info = "flushing log";
 
2371
 
 
2372
                        log_buffer_flush_to_disk();
2733
2373
                }
2734
2374
 
2735
2375
                if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
2738
2378
                        /* Try to keep the number of modified pages in the
2739
2379
                        buffer pool under the limit wished by the user */
2740
2380
 
2741
 
                        srv_main_thread_op_info =
2742
 
                                "flushing buffer pool pages";
2743
 
                        n_pages_flushed = buf_flush_list(
2744
 
                                PCT_IO(100), IB_ULONGLONG_MAX);
2745
 
 
2746
 
                } else if (srv_adaptive_flushing) {
2747
 
 
2748
 
                        /* Try to keep the rate of flushing of dirty
2749
 
                        pages such that redo log generation does not
2750
 
                        produce bursts of IO at checkpoint time. */
2751
 
                        ulint n_flush = buf_flush_get_desired_flush_rate();
2752
 
 
2753
 
                        if (n_flush) {
2754
 
                                srv_main_thread_op_info =
2755
 
                                        "flushing buffer pool pages";
2756
 
                                n_flush = ut_min(PCT_IO(100), n_flush);
2757
 
                                n_pages_flushed =
2758
 
                                        buf_flush_list(
2759
 
                                                n_flush,
2760
 
                                                IB_ULONGLONG_MAX);
2761
 
                        }
 
2381
                        n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2382
                                                          IB_ULONGLONG_MAX);
 
2383
 
 
2384
                        /* If we had to do the flush, it may have taken
 
2385
                        even more than 1 second, and also, there may be more
 
2386
                        to flush. Do not sleep 1 second during the next
 
2387
                        iteration of this loop. */
 
2388
 
 
2389
                        skip_sleep = TRUE;
2762
2390
                }
2763
2391
 
2764
2392
                if (srv_activity_count == old_activity_count) {
2778
2406
        seconds */
2779
2407
        mem_validate_all_blocks();
2780
2408
#endif
2781
 
        /* If i/os during the 10 second period were less than 200% of
2782
 
        capacity, we assume that there is free disk i/o capacity
2783
 
        available, and it makes sense to flush srv_io_capacity pages.
2784
 
 
2785
 
        Note that this is done regardless of the fraction of dirty
2786
 
        pages relative to the max requested by the user. The one second
2787
 
        loop above requests writes for that case. The writes done here
2788
 
        are not required, and may be disabled. */
2789
 
 
2790
 
        buf_get_total_stat(&buf_stat);
 
2409
        /* If there were less than 200 i/os during the 10 second period,
 
2410
        we assume that there is free disk i/o capacity available, and it
 
2411
        makes sense to flush 100 pages. */
 
2412
 
2791
2413
        n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
2792
 
        n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2793
 
                + buf_stat.n_pages_written;
2794
 
 
2795
 
        srv_main_10_second_loops++;
2796
 
        if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2797
 
            && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
 
2414
        n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2415
                + buf_pool->n_pages_written;
 
2416
        if (n_pend_ios < 3 && (n_ios - n_ios_very_old < 200)) {
2798
2417
 
2799
2418
                srv_main_thread_op_info = "flushing buffer pool pages";
2800
 
                buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
 
2419
                buf_flush_batch(BUF_FLUSH_LIST, 100, IB_ULONGLONG_MAX);
2801
2420
 
2802
 
                /* Flush logs if needed */
2803
 
                srv_sync_log_buffer_in_background();
 
2421
                srv_main_thread_op_info = "flushing log";
 
2422
                log_buffer_flush_to_disk();
2804
2423
        }
2805
2424
 
2806
2425
        /* We run a batch of insert buffer merge every 10 seconds,
2807
2426
        even if the server were active */
2808
2427
 
2809
2428
        srv_main_thread_op_info = "doing insert buffer merge";
2810
 
        ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
2811
 
 
2812
 
        /* Flush logs if needed */
2813
 
        srv_sync_log_buffer_in_background();
2814
 
 
2815
 
        if (srv_n_purge_threads == 0) {
2816
 
                srv_main_thread_op_info = "master purging";
2817
 
 
2818
 
                srv_master_do_purge();
 
2429
        ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4);
 
2430
 
 
2431
        srv_main_thread_op_info = "flushing log";
 
2432
        log_buffer_flush_to_disk();
 
2433
 
 
2434
        /* We run a full purge every 10 seconds, even if the server
 
2435
        were active */
 
2436
 
 
2437
        last_flush_time = time(NULL);
 
2438
 
 
2439
        do {
2819
2440
 
2820
2441
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2821
2442
 
2822
2443
                        goto background_loop;
2823
2444
                }
2824
 
        }
 
2445
 
 
2446
                srv_main_thread_op_info = "purging";
 
2447
                n_pages_purged = trx_purge();
 
2448
 
 
2449
                current_time = time(NULL);
 
2450
 
 
2451
                if (difftime(current_time, last_flush_time) > 1) {
 
2452
                        srv_main_thread_op_info = "flushing log";
 
2453
 
 
2454
                        log_buffer_flush_to_disk();
 
2455
                        last_flush_time = current_time;
 
2456
                }
 
2457
        } while (n_pages_purged);
2825
2458
 
2826
2459
        srv_main_thread_op_info = "flushing buffer pool pages";
2827
2460
 
2833
2466
                (> 70 %), we assume we can afford reserving the disk(s) for
2834
2467
                the time it requires to flush 100 pages */
2835
2468
 
2836
 
                n_pages_flushed = buf_flush_list(
2837
 
                        PCT_IO(100), IB_ULONGLONG_MAX);
 
2469
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2470
                                                  IB_ULONGLONG_MAX);
2838
2471
        } else {
2839
2472
                /* Otherwise, we only flush a small number of pages so that
2840
2473
                we do not unnecessarily use much disk i/o capacity from
2841
2474
                other work */
2842
2475
 
2843
 
                n_pages_flushed = buf_flush_list(
2844
 
                          PCT_IO(10), IB_ULONGLONG_MAX);
 
2476
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10,
 
2477
                                                  IB_ULONGLONG_MAX);
2845
2478
        }
2846
2479
 
2847
2480
        srv_main_thread_op_info = "making checkpoint";
2874
2507
 
2875
2508
        /* The server has been quiet for a while: start running background
2876
2509
        operations */
2877
 
        srv_main_background_loops++;
 
2510
 
2878
2511
        srv_main_thread_op_info = "doing background drop tables";
2879
2512
 
2880
2513
        n_tables_to_drop = row_drop_tables_for_mysql_in_background();
2888
2521
                os_thread_sleep(100000);
2889
2522
        }
2890
2523
 
2891
 
        if (srv_n_purge_threads == 0) {
2892
 
                srv_main_thread_op_info = "master purging";
2893
 
 
2894
 
                srv_master_do_purge();
2895
 
        }
 
2524
        srv_main_thread_op_info = "purging";
 
2525
 
 
2526
        /* Run a full purge */
 
2527
 
 
2528
        last_flush_time = time(NULL);
 
2529
 
 
2530
        do {
 
2531
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
 
2532
 
 
2533
                        break;
 
2534
                }
 
2535
 
 
2536
                srv_main_thread_op_info = "purging";
 
2537
                n_pages_purged = trx_purge();
 
2538
 
 
2539
                current_time = time(NULL);
 
2540
 
 
2541
                if (difftime(current_time, last_flush_time) > 1) {
 
2542
                        srv_main_thread_op_info = "flushing log";
 
2543
 
 
2544
                        log_buffer_flush_to_disk();
 
2545
                        last_flush_time = current_time;
 
2546
                }
 
2547
        } while (n_pages_purged);
2896
2548
 
2897
2549
        srv_main_thread_op_info = "reserving kernel mutex";
2898
2550
 
2908
2560
        if (srv_fast_shutdown && srv_shutdown_state > 0) {
2909
2561
                n_bytes_merged = 0;
2910
2562
        } else {
2911
 
                /* This should do an amount of IO similar to the number of
2912
 
                dirty pages that will be flushed in the call to
2913
 
                buf_flush_list below. Otherwise, the system favors
2914
 
                clean pages over cleanup throughput. */
2915
 
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2916
 
                                                           PCT_IO(100));
 
2563
                n_bytes_merged = ibuf_contract_for_n_pages(
 
2564
                        TRUE, srv_insert_buffer_batch_size);
2917
2565
        }
2918
2566
 
2919
2567
        srv_main_thread_op_info = "reserving kernel mutex";
2927
2575
 
2928
2576
flush_loop:
2929
2577
        srv_main_thread_op_info = "flushing buffer pool pages";
2930
 
        srv_main_flush_loops++;
 
2578
 
2931
2579
        if (srv_fast_shutdown < 2) {
2932
 
                n_pages_flushed = buf_flush_list(
2933
 
                          PCT_IO(100), IB_ULONGLONG_MAX);
 
2580
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 100,
 
2581
                                                  IB_ULONGLONG_MAX);
2934
2582
        } else {
2935
2583
                /* In the fastest shutdown we do not flush the buffer pool
2936
2584
                to data files: we set n_pages_flushed to 0 artificially. */
2948
2596
        mutex_exit(&kernel_mutex);
2949
2597
 
2950
2598
        srv_main_thread_op_info = "waiting for buffer pool flush to end";
2951
 
        buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
2952
 
 
2953
 
        /* Flush logs if needed */
2954
 
        srv_sync_log_buffer_in_background();
 
2599
        buf_flush_wait_batch_end(BUF_FLUSH_LIST);
 
2600
 
 
2601
        srv_main_thread_op_info = "flushing log";
 
2602
 
 
2603
        log_buffer_flush_to_disk();
2955
2604
 
2956
2605
        srv_main_thread_op_info = "making checkpoint";
2957
2606
 
3035
2684
                already when the event wait ends */
3036
2685
 
3037
2686
                os_thread_exit(NULL);
3038
 
 
3039
2687
        }
3040
2688
 
3041
2689
        /* When there is user activity, InnoDB will set the event and the
3044
2692
        goto loop;
3045
2693
 
3046
2694
 
3047
 
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
 
2695
#ifndef UNIV_SOLARIS
3048
2696
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3049
2697
#endif
3050
2698
}
3051
 
 
3052
 
/*********************************************************************//**
3053
 
Asynchronous purge thread.
3054
 
@return a dummy parameter */
3055
 
UNIV_INTERN
3056
 
os_thread_ret_t
3057
 
srv_purge_thread(
3058
 
/*=============*/
3059
 
        void*   arg __attribute__((unused)))    /*!< in: a dummy parameter
3060
 
                                                required by os_thread_create */
3061
 
{
3062
 
        srv_slot_t*     slot;
3063
 
        ulint           slot_no = ULINT_UNDEFINED;
3064
 
        ulint           n_total_purged = ULINT_UNDEFINED;
3065
 
 
3066
 
        ut_a(srv_n_purge_threads == 1);
3067
 
 
3068
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3069
 
        fprintf(stderr, "InnoDB: Purge thread running, id %lu\n",
3070
 
                os_thread_pf(os_thread_get_curr_id()));
3071
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3072
 
 
3073
 
        mutex_enter(&kernel_mutex);
3074
 
 
3075
 
        slot_no = srv_table_reserve_slot(SRV_WORKER);
3076
 
 
3077
 
        slot = srv_table_get_nth_slot(slot_no);
3078
 
 
3079
 
        ++srv_n_threads_active[SRV_WORKER];
3080
 
 
3081
 
        mutex_exit(&kernel_mutex);
3082
 
 
3083
 
        while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
3084
 
 
3085
 
                ulint   n_pages_purged;
3086
 
 
3087
 
                /* If there are very few records to purge or the last
3088
 
                purge didn't purge any records then wait for activity.
3089
 
                We peek at the history len without holding any mutex
3090
 
                because in the worst case we will end up waiting for
3091
 
                the next purge event. */
3092
 
                if (trx_sys->rseg_history_len < srv_purge_batch_size
3093
 
                    || n_total_purged == 0) {
3094
 
 
3095
 
                        os_event_t      event;
3096
 
 
3097
 
                        mutex_enter(&kernel_mutex);
3098
 
 
3099
 
                        event = srv_suspend_thread();
3100
 
 
3101
 
                        mutex_exit(&kernel_mutex);
3102
 
 
3103
 
                        os_event_wait(event);
3104
 
                }
3105
 
 
3106
 
                /* Check for shutdown and whether we should do purge at all. */
3107
 
                if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
3108
 
                    || srv_shutdown_state != 0
3109
 
                    || srv_fast_shutdown) {
3110
 
 
3111
 
                        break;
3112
 
                }
3113
 
 
3114
 
                n_total_purged = 0;
3115
 
 
3116
 
                /* Purge until there are no more records to purge and there is
3117
 
                no change in configuration or server state. */
3118
 
                do {
3119
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
3120
 
 
3121
 
                        n_total_purged += n_pages_purged;
3122
 
 
3123
 
                } while (n_pages_purged > 0 && !srv_fast_shutdown);
3124
 
 
3125
 
                srv_sync_log_buffer_in_background();
3126
 
        }
3127
 
 
3128
 
        mutex_enter(&kernel_mutex);
3129
 
 
3130
 
        ut_ad(srv_table_get_nth_slot(slot_no) == slot);
3131
 
 
3132
 
        /* Decrement the active count. */
3133
 
        srv_suspend_thread();
3134
 
 
3135
 
        slot->in_use = FALSE;
3136
 
 
3137
 
        /* Free the thread local memory. */
3138
 
        thr_local_free(os_thread_get_curr_id());
3139
 
 
3140
 
        mutex_exit(&kernel_mutex);
3141
 
 
3142
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3143
 
        fprintf(stderr, "InnoDB: Purge thread exiting, id %lu\n",
3144
 
                os_thread_pf(os_thread_get_curr_id()));
3145
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3146
 
 
3147
 
        /* We count the number of threads in os_thread_exit(). A created
3148
 
        thread should always use that to exit and not use return() to exit. */
3149
 
        os_thread_exit(NULL);
3150
 
 
3151
 
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3152
 
}
3153
 
 
3154
 
/**********************************************************************//**
3155
 
Enqueues a task to server task queue and releases a worker thread, if there
3156
 
is a suspended one. */
3157
 
UNIV_INTERN
3158
 
void
3159
 
srv_que_task_enqueue_low(
3160
 
/*=====================*/
3161
 
        que_thr_t*      thr)    /*!< in: query thread */
3162
 
{
3163
 
        ut_ad(thr);
3164
 
 
3165
 
        mutex_enter(&kernel_mutex);
3166
 
 
3167
 
        UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
3168
 
 
3169
 
        srv_release_threads(SRV_WORKER, 1);
3170
 
 
3171
 
        mutex_exit(&kernel_mutex);
3172
 
}
 
2699
#endif /* !UNIV_HOTBACKUP */