~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Stewart Smith
  • Date: 2010-09-23 05:33:01 UTC
  • mto: (1804.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1806.
  • Revision ID: stewart@flamingspork.com-20100923053301-b2b528g2dm5owa97
HailDB test suite loads the HailDB plugin (not the old name, which was 'embedded_innodb')

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, 2009 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
*****************************************************************************/
 
25
/***********************************************************************
 
26
 
 
27
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
28
Copyright (c) 2009, Percona Inc.
 
29
 
 
30
Portions of this file contain modifications contributed and copyrighted
 
31
by Percona Inc.. Those modifications are
 
32
gratefully acknowledged and are described briefly in the InnoDB
 
33
documentation. The contributions by Percona Inc. are incorporated with
 
34
their permission, and subject to the conditions contained in the file
 
35
COPYING.Percona.
 
36
 
 
37
This program is free software; you can redistribute it and/or modify it
 
38
under the terms of the GNU General Public License as published by the
 
39
Free Software Foundation; version 2 of the License.
 
40
 
 
41
This program is distributed in the hope that it will be useful, but
 
42
WITHOUT ANY WARRANTY; without even the implied warranty of
 
43
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 
44
Public License for more details.
 
45
 
 
46
You should have received a copy of the GNU General Public License along
 
47
with this program; if not, write to the Free Software Foundation, Inc.,
 
48
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
49
 
 
50
***********************************************************************/
33
51
 
34
52
/**************************************************//**
35
53
@file srv/srv0srv.c
60
78
/* Dummy comment */
61
79
#include "srv0srv.h"
62
80
 
63
 
#include <drizzled/error.h>
64
 
#include <drizzled/errmsg_print.h>
65
 
 
66
81
#include "ut0mem.h"
67
82
#include "ut0ut.h"
68
83
#include "os0proc.h"
71
86
#include "sync0sync.h"
72
87
#include "thr0loc.h"
73
88
#include "que0que.h"
 
89
#include "srv0que.h"
74
90
#include "log0recv.h"
75
91
#include "pars0pars.h"
76
92
#include "usr0sess.h"
86
102
#include "row0mysql.h"
87
103
#include "ha_prototypes.h"
88
104
#include "trx0i_s.h"
89
 
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
90
105
 
91
106
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
92
107
affects only FOREIGN KEY definition parsing */
103
118
in microseconds, in order to reduce the lagging of the purge thread. */
104
119
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
105
120
 
106
 
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
107
 
UNIV_INTERN ibool       srv_monitor_active = FALSE;
 
121
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
108
122
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
109
123
 
110
124
UNIV_INTERN const char* srv_main_thread_op_info = "";
111
125
 
 
126
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
 
127
UNIV_INTERN const char  srv_mysql50_table_name_prefix[9] = "#mysql50#";
 
128
 
112
129
/* Server parameters which are read from the initfile */
113
130
 
114
131
/* The following three are dir paths which are catenated before file
127
144
/** Whether to check file format during startup.  A value of
128
145
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
129
146
set it to the highest format we support. */
130
 
UNIV_INTERN ulint       srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
 
147
UNIV_INTERN ulint       srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
131
148
 
132
149
#if DICT_TF_FORMAT_51
133
150
# error "DICT_TF_FORMAT_51 must be 0!"
136
153
on duplicate key checking and foreign key checking */
137
154
UNIV_INTERN ibool       srv_locks_unsafe_for_binlog = FALSE;
138
155
 
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
156
UNIV_INTERN ulint       srv_n_data_files = 0;
161
157
UNIV_INTERN char**      srv_data_file_names = NULL;
162
158
/* size in database pages */
191
187
the checkpoints. */
192
188
UNIV_INTERN bool        srv_adaptive_flushing   = TRUE;
193
189
 
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
 
190
/* The sort order table of the MySQL latin1_swedish_ci character set
205
191
collation */
206
192
#if defined(BUILD_DRIZZLE)
207
 
const byte      srv_latin1_ordering[256]        /* The sort order table of the latin1
 
193
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
208
194
                                        character set. The following table is
209
195
                                        the MySQL order as of Feb 10th, 2002 */
210
196
= {
250
236
UNIV_INTERN my_bool     srv_use_sys_malloc      = TRUE;
251
237
/* requested size in kilobytes */
252
238
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
239
/* previously requested size */
256
240
UNIV_INTERN ulint       srv_buf_pool_old_size;
257
241
/* current size in kilobytes */
303
287
 
304
288
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 75;
305
289
 
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;
311
 
 
312
290
/* variable counts amount of data read in total (in bytes) */
313
291
UNIV_INTERN ulint srv_data_read = 0;
314
292
 
355
333
reading of a disk page */
356
334
UNIV_INTERN ulint srv_buf_pool_reads = 0;
357
335
 
 
336
/** Number of sequential read-aheads */
 
337
UNIV_INTERN ulint srv_read_ahead_seq = 0;
 
338
 
 
339
/** Number of random read-aheads */
 
340
UNIV_INTERN ulint srv_read_ahead_rnd = 0;
 
341
 
358
342
/* structure to pass status variables to MySQL */
359
343
UNIV_INTERN export_struc export_vars;
360
344
 
463
447
UNIV_INTERN ib_int64_t  srv_n_lock_wait_time            = 0;
464
448
UNIV_INTERN ulint               srv_n_lock_max_wait_time        = 0;
465
449
 
466
 
UNIV_INTERN ulint               srv_truncated_status_writes     = 0;
467
450
 
468
451
/*
469
452
  Set the following to 0 if you want InnoDB to write messages on
487
470
 
488
471
/* Mutex for locking srv_monitor_file */
489
472
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
473
/* Temporary file for innodb monitor output */
507
474
UNIV_INTERN FILE*       srv_monitor_file;
508
475
/* Mutex for locking srv_dict_tmpfile.
535
502
static ulint   srv_main_flush_loops             = 0;
536
503
/* Log writes involving flush. */
537
504
static ulint   srv_log_writes_and_flush         = 0;
 
505
/* Log writes not including flush. */
 
506
static ulint   srv_log_buffer_writes            = 0;
538
507
 
539
508
/* This is only ever touched by the master thread. It records the
540
509
time when the last flush of log file has happened. The master
736
705
/* Table for MySQL threads where they will be suspended to wait for locks */
737
706
UNIV_INTERN srv_slot_t* srv_mysql_table = NULL;
738
707
 
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
708
UNIV_INTERN os_event_t  srv_lock_timeout_thread_event;
746
709
 
747
710
UNIV_INTERN srv_sys_t*  srv_sys = NULL;
751
714
UNIV_INTERN byte        srv_pad1[64];
752
715
/* mutex protecting the server, trx structs, query threads, and lock table */
753
716
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
717
/* padding to prevent other memory update hotspots from residing on
758
718
the same memory cache line */
759
719
UNIV_INTERN byte        srv_pad2[64];
772
732
static ulint    srv_meter_foreground[SRV_MASTER + 1];
773
733
#endif
774
734
 
 
735
/* The following values give info about the activity going on in
 
736
the database. They are protected by the server mutex. The arrays
 
737
are indexed by the type of the thread. */
 
738
 
 
739
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
 
740
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
 
741
 
775
742
/***********************************************************************
776
743
Prints counters for work done by srv_master_thread. */
777
744
static
785
752
                srv_main_1_second_loops, srv_main_sleeps,
786
753
                srv_main_10_second_loops, srv_main_background_loops,
787
754
                srv_main_flush_loops);
788
 
        fprintf(file, "srv_master_thread log flush and writes: %lu\n",
789
 
                      srv_log_writes_and_flush);
 
755
        fprintf(file, "srv_master_thread log flush and writes: %lu "
 
756
                      " log writes only: %lu\n",
 
757
                      srv_log_writes_and_flush, srv_log_buffer_writes);
790
758
}
791
759
 
792
 
/* The following values give info about the activity going on in
793
 
the database. They are protected by the server mutex. The arrays
794
 
are indexed by the type of the thread. */
795
 
 
796
 
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
797
 
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
798
 
 
799
760
/*********************************************************************//**
800
761
Sets the info describing an i/o thread current state. */
801
762
UNIV_INTERN
915
876
 
916
877
        slot = srv_table_get_nth_slot(slot_no);
917
878
 
918
 
        type = static_cast<srv_thread_type>(slot->type);
 
879
        type = slot->type;
919
880
 
920
881
        ut_ad(type >= SRV_WORKER);
921
882
        ut_ad(type <= SRV_MASTER);
958
919
 
959
920
                slot = srv_table_get_nth_slot(i);
960
921
 
961
 
                if (slot->in_use &&
962
 
                    (static_cast<srv_thread_type>(slot->type) == type) &&
963
 
                    slot->suspended) {
 
922
                if (slot->in_use && slot->type == type && slot->suspended) {
964
923
 
965
924
                        slot->suspended = FALSE;
966
925
 
1005
964
 
1006
965
        slot = srv_table_get_nth_slot(slot_no);
1007
966
 
1008
 
        type = static_cast<srv_thread_type>(slot->type);
 
967
        type = slot->type;
1009
968
 
1010
969
        ut_ad(type >= SRV_WORKER);
1011
970
        ut_ad(type <= SRV_MASTER);
1026
985
        srv_slot_t*             slot;
1027
986
        ulint                   i;
1028
987
 
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)));
 
988
        srv_sys = mem_alloc(sizeof(srv_sys_t));
 
989
 
 
990
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
 
991
        mutex_create(&kernel_mutex, SYNC_KERNEL);
 
992
 
 
993
        mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
994
 
 
995
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1041
996
 
1042
997
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1043
998
                slot = srv_table_get_nth_slot(i);
1047
1002
                ut_a(slot->event);
1048
1003
        }
1049
1004
 
1050
 
        srv_mysql_table = static_cast<srv_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
 
1005
        srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1051
1006
 
1052
1007
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1053
1008
                slot = srv_mysql_table + i;
1057
1012
                ut_a(slot->event);
1058
1013
        }
1059
1014
 
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
1015
        srv_lock_timeout_thread_event = os_event_create(NULL);
1067
1016
 
1068
1017
        for (i = 0; i < SRV_MASTER + 1; i++) {
1089
1038
 
1090
1039
        UT_LIST_INIT(srv_conc_queue);
1091
1040
 
1092
 
        srv_conc_slots = static_cast<srv_conc_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t)));
 
1041
        srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
1093
1042
 
1094
1043
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1095
1044
                conc_slot = srv_conc_slots + i;
1103
1052
}
1104
1053
 
1105
1054
/*********************************************************************//**
1106
 
Frees the data structures created in srv_init(). */
 
1055
Frees the OS fast mutex created in srv_init(). */
1107
1056
UNIV_INTERN
1108
1057
void
1109
1058
srv_free(void)
1110
1059
/*==========*/
1111
1060
{
1112
1061
        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
1062
}
1130
1063
 
1131
1064
/*********************************************************************//**
1137
1070
/*==================*/
1138
1071
{
1139
1072
        ut_mem_init();
1140
 
        /* Reset the system variables in the recovery module. */
1141
 
        recv_sys_var_init();
1142
1073
        os_sync_init();
1143
1074
        sync_init();
1144
1075
        mem_init(srv_mem_pool_size);
1645
1576
                row_mysql_unfreeze_data_dictionary(trx);
1646
1577
                break;
1647
1578
        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
1579
                /* Release fast index creation latch */
1661
1580
                row_mysql_unlock_data_dictionary(trx);
1662
1581
                break;
1676
1595
                row_mysql_freeze_data_dictionary(trx);
1677
1596
                break;
1678
1597
        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
1598
                row_mysql_lock_data_dictionary(trx);
1683
1599
                break;
1684
1600
        }
1715
1631
                    start_time != -1 && finish_time != -1) {
1716
1632
                        srv_n_lock_max_wait_time = diff_time;
1717
1633
                }
1718
 
 
1719
 
                /* Record the lock wait time for this thread */
1720
 
                thd_set_lock_wait_time(trx->mysql_thd, diff_time);
1721
1634
        }
1722
1635
 
1723
1636
        if (trx->was_chosen_as_deadlock_victim) {
1739
1652
 
1740
1653
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1741
1654
        }
1742
 
 
1743
 
        if (trx_is_interrupted(trx)) {
1744
 
 
1745
 
                trx->error_state = DB_INTERRUPTED;
1746
 
        }
1747
1655
}
1748
1656
 
1749
1657
/********************************************************************//**
1795
1703
 
1796
1704
        log_refresh_stats();
1797
1705
 
1798
 
        buf_refresh_io_stats_all();
 
1706
        buf_refresh_io_stats();
1799
1707
 
1800
1708
        srv_n_rows_inserted_old = srv_n_rows_inserted;
1801
1709
        srv_n_rows_updated_old = srv_n_rows_updated;
1806
1714
}
1807
1715
 
1808
1716
/******************************************************************//**
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 */
 
1717
Outputs to a file the output of the InnoDB Monitor. */
1812
1718
UNIV_INTERN
1813
 
ibool
 
1719
void
1814
1720
srv_printf_innodb_monitor(
1815
1721
/*======================*/
1816
1722
        FILE*   file,           /*!< in: output stream */
1817
 
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1818
1723
        ulint*  trx_start,      /*!< out: file position of the start of
1819
1724
                                the list of active transactions */
1820
1725
        ulint*  trx_end)        /*!< out: file position of the end of
1823
1728
        double  time_elapsed;
1824
1729
        time_t  current_time;
1825
1730
        ulint   n_reserved;
1826
 
        ibool   ret;
1827
1731
 
1828
1732
        mutex_enter(&srv_innodb_monitor_mutex);
1829
1733
 
1847
1751
                "Per second averages calculated from the last %lu seconds\n",
1848
1752
                (ulong)time_elapsed);
1849
1753
 
1850
 
        fputs("-----------------\n"
1851
 
              "BACKGROUND THREAD\n"
1852
 
              "-----------------\n", file);
 
1754
        fputs("----------\n"
 
1755
                "BACKGROUND THREAD\n"
 
1756
                "----------\n", file);
1853
1757
        srv_print_master_thread_info(file);
1854
1758
 
1855
1759
        fputs("----------\n"
1873
1777
 
1874
1778
        mutex_exit(&dict_foreign_err_mutex);
1875
1779
 
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
 
 
 
1780
        lock_print_info_summary(file);
 
1781
        if (trx_start) {
 
1782
                long    t = ftell(file);
 
1783
                if (t < 0) {
 
1784
                        *trx_start = ULINT_UNDEFINED;
 
1785
                } else {
 
1786
                        *trx_start = (ulint) t;
 
1787
                }
 
1788
        }
 
1789
        lock_print_info_all_transactions(file);
 
1790
        if (trx_end) {
 
1791
                long    t = ftell(file);
 
1792
                if (t < 0) {
 
1793
                        *trx_end = ULINT_UNDEFINED;
 
1794
                } else {
 
1795
                        *trx_end = (ulint) t;
 
1796
                }
 
1797
        }
1901
1798
        fputs("--------\n"
1902
1799
              "FILE I/O\n"
1903
1800
              "--------\n", file);
1945
1842
                (ulong) srv_conc_n_waiting_threads);
1946
1843
 
1947
1844
        fprintf(file, "%lu read views open inside InnoDB\n",
1948
 
                static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)));
 
1845
                UT_LIST_GET_LEN(trx_sys->view_list));
1949
1846
 
1950
1847
        n_reserved = fil_space_get_n_reserved_extents(0);
1951
1848
        if (n_reserved > 0) {
1995
1892
              "============================\n", file);
1996
1893
        mutex_exit(&srv_innodb_monitor_mutex);
1997
1894
        fflush(file);
1998
 
 
1999
 
        return(ret);
2000
1895
}
2001
1896
 
2002
1897
/******************************************************************//**
2006
1901
srv_export_innodb_status(void)
2007
1902
/*==========================*/
2008
1903
{
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
1904
        mutex_enter(&srv_innodb_monitor_mutex);
2018
1905
 
2019
1906
        export_vars.innodb_data_pending_reads
2028
1915
        export_vars.innodb_data_reads = os_n_file_reads;
2029
1916
        export_vars.innodb_data_writes = os_n_file_writes;
2030
1917
        export_vars.innodb_data_written = srv_data_written;
2031
 
        export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
 
1918
        export_vars.innodb_buffer_pool_read_requests = buf_pool->n_page_gets;
2032
1919
        export_vars.innodb_buffer_pool_write_requests
2033
1920
                = srv_buf_pool_write_requests;
2034
1921
        export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
2035
1922
        export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
2036
1923
        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;
 
1924
        export_vars.innodb_buffer_pool_read_ahead_rnd = srv_read_ahead_rnd;
 
1925
        export_vars.innodb_buffer_pool_read_ahead_seq = srv_read_ahead_seq;
 
1926
        export_vars.innodb_buffer_pool_pages_data
 
1927
                = UT_LIST_GET_LEN(buf_pool->LRU);
 
1928
        export_vars.innodb_buffer_pool_pages_dirty
 
1929
                = UT_LIST_GET_LEN(buf_pool->flush_list);
 
1930
        export_vars.innodb_buffer_pool_pages_free
 
1931
                = UT_LIST_GET_LEN(buf_pool->free);
2044
1932
#ifdef UNIV_DEBUG
2045
1933
        export_vars.innodb_buffer_pool_pages_latched
2046
1934
                = buf_get_latched_pages_number();
2047
1935
#endif /* UNIV_DEBUG */
2048
 
        export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
 
1936
        export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
2049
1937
 
2050
 
        export_vars.innodb_buffer_pool_pages_misc
2051
 
                = buf_pool_get_n_pages() - LRU_len - free_len;
 
1938
        export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
 
1939
                - UT_LIST_GET_LEN(buf_pool->LRU)
 
1940
                - UT_LIST_GET_LEN(buf_pool->free);
2052
1941
#ifdef HAVE_ATOMIC_BUILTINS
2053
1942
        export_vars.innodb_have_atomic_builtins = 1;
2054
1943
#else
2064
1953
        export_vars.innodb_log_writes = srv_log_writes;
2065
1954
        export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
2066
1955
        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;
 
1956
        export_vars.innodb_pages_created = buf_pool->n_pages_created;
 
1957
        export_vars.innodb_pages_read = buf_pool->n_pages_read;
 
1958
        export_vars.innodb_pages_written = buf_pool->n_pages_written;
2070
1959
        export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
2071
1960
        export_vars.innodb_row_lock_current_waits
2072
1961
                = srv_n_lock_wait_current_count;
2083
1972
        export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2084
1973
        export_vars.innodb_rows_updated = srv_n_rows_updated;
2085
1974
        export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2086
 
        export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
2087
1975
 
2088
1976
        mutex_exit(&srv_innodb_monitor_mutex);
2089
1977
}
2090
1978
 
2091
1979
/*********************************************************************//**
2092
 
A thread which prints the info output by various InnoDB monitors.
 
1980
A thread which wakes up threads whose lock wait may have lasted too long.
 
1981
This also prints the info output by various InnoDB monitors.
2093
1982
@return a dummy parameter */
2094
1983
UNIV_INTERN
2095
1984
os_thread_ret_t
2096
 
srv_monitor_thread(
2097
 
/*===============*/
2098
 
        void*   /*arg __attribute__((unused))*/)
 
1985
srv_lock_timeout_and_monitor_thread(
 
1986
/*================================*/
 
1987
        void*   arg __attribute__((unused)))
2099
1988
                        /*!< in: a dummy parameter required by
2100
1989
                        os_thread_create */
2101
1990
{
2102
 
        ib_int64_t      sig_count;
 
1991
        srv_slot_t*     slot;
2103
1992
        double          time_elapsed;
2104
1993
        time_t          current_time;
2105
1994
        time_t          last_table_monitor_time;
2106
1995
        time_t          last_tablespace_monitor_time;
2107
1996
        time_t          last_monitor_time;
2108
 
        ulint           mutex_skipped;
2109
 
        ibool           last_srv_print_monitor;
 
1997
        ibool           some_waits;
 
1998
        double          wait_time;
 
1999
        ulint           i;
2110
2000
 
2111
2001
#ifdef UNIV_DEBUG_THREAD_CREATION
2112
2002
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2113
2003
                os_thread_pf(os_thread_get_curr_id()));
2114
2004
#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;
 
2005
        UT_NOT_USED(arg);
 
2006
        srv_last_monitor_time = time(NULL);
 
2007
        last_table_monitor_time = time(NULL);
 
2008
        last_tablespace_monitor_time = time(NULL);
 
2009
        last_monitor_time = time(NULL);
2126
2010
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();
 
2011
        srv_lock_timeout_and_monitor_active = TRUE;
 
2012
 
 
2013
        /* When someone is waiting for a lock, we wake up every second
 
2014
        and check if a timeout has passed for a lock wait */
 
2015
 
 
2016
        os_thread_sleep(1000000);
 
2017
 
 
2018
        current_time = time(NULL);
2137
2019
 
2138
2020
        time_elapsed = difftime(current_time, last_monitor_time);
2139
2021
 
2140
2022
        if (time_elapsed > 15) {
2141
 
                last_monitor_time = ut_time();
 
2023
                last_monitor_time = time(NULL);
2142
2024
 
2143
2025
                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;
 
2026
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
2164
2027
                }
2165
2028
 
2166
 
 
2167
2029
                if (srv_innodb_status) {
2168
2030
                        mutex_enter(&srv_monitor_file_mutex);
2169
2031
                        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
 
 
 
2032
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
 
2033
                                                  NULL);
2178
2034
                        os_file_set_eof(srv_monitor_file);
2179
2035
                        mutex_exit(&srv_monitor_file_mutex);
2180
2036
                }
2182
2038
                if (srv_print_innodb_tablespace_monitor
2183
2039
                    && difftime(current_time,
2184
2040
                                last_tablespace_monitor_time) > 60) {
2185
 
                        last_tablespace_monitor_time = ut_time();
 
2041
                        last_tablespace_monitor_time = time(NULL);
2186
2042
 
2187
2043
                        fputs("========================"
2188
2044
                              "========================\n",
2208
2064
                if (srv_print_innodb_table_monitor
2209
2065
                    && difftime(current_time, last_table_monitor_time) > 60) {
2210
2066
 
2211
 
                        last_table_monitor_time = ut_time();
 
2067
                        last_table_monitor_time = time(NULL);
2212
2068
 
2213
2069
                        fputs("===========================================\n",
2214
2070
                              stderr);
2227
2083
                }
2228
2084
        }
2229
2085
 
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
2086
        mutex_enter(&kernel_mutex);
2289
2087
 
2290
2088
        some_waits = FALSE;
2308
2106
                        lock_wait_timeout = thd_lock_wait_timeout(
2309
2107
                                trx->mysql_thd);
2310
2108
 
2311
 
                        if (trx_is_interrupted(trx)
2312
 
                            || (lock_wait_timeout < 100000000
2313
 
                                && (wait_time > (double) lock_wait_timeout
2314
 
                                    || wait_time < 0))) {
 
2109
                        if (lock_wait_timeout < 100000000
 
2110
                            && (wait_time > (double) lock_wait_timeout
 
2111
                                || wait_time < 0)) {
2315
2112
 
2316
2113
                                /* Timeout exceeded or a wrap-around in system
2317
2114
                                time counter: cancel the lock request queued
2336
2133
                goto exit_func;
2337
2134
        }
2338
2135
 
2339
 
        if (some_waits) {
 
2136
        if (some_waits || srv_print_innodb_monitor
 
2137
            || srv_print_innodb_lock_monitor
 
2138
            || srv_print_innodb_tablespace_monitor
 
2139
            || srv_print_innodb_table_monitor) {
2340
2140
                goto loop;
2341
2141
        }
2342
2142
 
2343
 
        srv_lock_timeout_active = FALSE;
 
2143
        /* No one was waiting for a lock and no monitor was active:
 
2144
        suspend this thread */
 
2145
 
 
2146
        srv_lock_timeout_and_monitor_active = FALSE;
2344
2147
 
2345
2148
#if 0
2346
2149
        /* The following synchronisation is disabled, since
2350
2153
        goto loop;
2351
2154
 
2352
2155
exit_func:
2353
 
        srv_lock_timeout_active = FALSE;
 
2156
        srv_lock_timeout_and_monitor_active = FALSE;
2354
2157
 
2355
2158
        /* We count the number of threads in os_thread_exit(). A created
2356
2159
        thread should always use that to exit and not use return() to exit. */
2368
2171
os_thread_ret_t
2369
2172
srv_error_monitor_thread(
2370
2173
/*=====================*/
2371
 
        void*   /*arg __attribute__((unused))*/)
 
2174
        void*   arg __attribute__((unused)))
2372
2175
                        /*!< in: a dummy parameter required by
2373
2176
                        os_thread_create */
2374
2177
{
2376
2179
        ulint           fatal_cnt       = 0;
2377
2180
        ib_uint64_t     old_lsn;
2378
2181
        ib_uint64_t     new_lsn;
2379
 
        ib_int64_t      sig_count;
2380
2182
 
2381
2183
        old_lsn = srv_start_lsn;
2382
2184
 
2384
2186
        fprintf(stderr, "Error monitor thread starts, id %lu\n",
2385
2187
                os_thread_pf(os_thread_get_curr_id()));
2386
2188
#endif
2387
 
 
2388
 
#ifdef UNIV_PFS_THREAD
2389
 
        pfs_register_thread(srv_error_monitor_thread_key);
2390
 
#endif
2391
 
 
2392
2189
loop:
2393
2190
        srv_error_monitor_active = TRUE;
2394
2191
 
2398
2195
        new_lsn = log_get_lsn();
2399
2196
 
2400
2197
        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);
 
2198
                ut_print_timestamp(stderr);
 
2199
                fprintf(stderr,
 
2200
                        "  InnoDB: Error: old log sequence number %"PRIu64""
 
2201
                        " was greater\n"
 
2202
                        "InnoDB: than the new log sequence number %"PRIu64"!\n"
 
2203
                        "InnoDB: Please submit a bug report"
 
2204
                        " to http://bugs.mysql.com\n",
 
2205
                        old_lsn, new_lsn);
2405
2206
        }
2406
2207
 
2407
2208
        old_lsn = new_lsn;
2448
2249
 
2449
2250
        fflush(stderr);
2450
2251
 
2451
 
        sig_count = os_event_reset(srv_error_event);
2452
 
 
2453
 
        os_event_wait_time_low(srv_error_event, 1000000, sig_count);
 
2252
        os_thread_sleep(1000000);
2454
2253
 
2455
2254
        if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
2456
2255
 
2467
2266
        OS_THREAD_DUMMY_RETURN;
2468
2267
}
2469
2268
 
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
2269
/*******************************************************************//**
2496
2270
Tells the InnoDB server that there has been activity in the database
2497
2271
and wakes up the master thread if it is suspended (not sleeping). Used
2498
2272
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). */
 
2273
thread stays suspended (we do not protect our operation with the kernel
 
2274
mutex, for performace reasons). */
2501
2275
UNIV_INTERN
2502
2276
void
2503
2277
srv_active_wake_master_thread(void)
2516
2290
}
2517
2291
 
2518
2292
/*******************************************************************//**
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
 
/*******************************************************************//**
2543
2293
Wakes up the master thread if it is suspended or being suspended. */
2544
2294
UNIV_INTERN
2545
2295
void
2555
2305
        mutex_exit(&kernel_mutex);
2556
2306
}
2557
2307
 
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
2308
/**********************************************************************
2578
2309
The master thread is tasked to ensure that flush of log file happens
2579
2310
once every second in the background. This is to ensure that not more
2591
2322
                log_buffer_sync_in_background(TRUE);
2592
2323
                srv_last_log_flush_time = current_time;
2593
2324
                srv_log_writes_and_flush++;
 
2325
        } else {
 
2326
                /* Actually we don't need to write logs here.
 
2327
                We are just being extra safe here by forcing
 
2328
                the log buffer to log file. */
 
2329
                log_buffer_sync_in_background(FALSE);
 
2330
                srv_log_buffer_writes++;
2594
2331
        }
2595
2332
}
2596
2333
 
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
2334
/*********************************************************************//**
2626
2335
The master thread controlling the server.
2627
2336
@return a dummy parameter */
2629
2338
os_thread_ret_t
2630
2339
srv_master_thread(
2631
2340
/*==============*/
2632
 
        void*   /*arg __attribute__((unused))*/)
 
2341
        void*   arg __attribute__((unused)))
2633
2342
                        /*!< in: a dummy parameter required by
2634
2343
                        os_thread_create */
2635
2344
{
2636
 
        buf_pool_stat_t buf_stat;
2637
2345
        os_event_t      event;
2638
2346
        ulint           old_activity_count;
2639
2347
        ulint           n_pages_purged  = 0;
2645
2353
        ulint           n_ios_old;
2646
2354
        ulint           n_ios_very_old;
2647
2355
        ulint           n_pend_ios;
2648
 
        ulint           next_itr_time;
 
2356
        ibool           skip_sleep      = FALSE;
2649
2357
        ulint           i;
2650
2358
 
2651
2359
#ifdef UNIV_DEBUG_THREAD_CREATION
2652
2360
        fprintf(stderr, "Master thread starts, id %lu\n",
2653
2361
                os_thread_pf(os_thread_get_curr_id()));
2654
2362
#endif
2655
 
 
2656
 
#ifdef UNIV_PFS_THREAD
2657
 
        pfs_register_thread(srv_master_thread_key);
2658
 
#endif
2659
 
 
2660
2363
        srv_main_thread_process_no = os_proc_get_number();
2661
2364
        srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2662
2365
 
2675
2378
 
2676
2379
        srv_main_thread_op_info = "reserving kernel mutex";
2677
2380
 
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;
 
2381
        n_ios_very_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2382
                + buf_pool->n_pages_written;
2681
2383
        mutex_enter(&kernel_mutex);
2682
2384
 
2683
2385
        /* Store the user activity counter at the start of this loop */
2694
2396
        when there is database activity */
2695
2397
 
2696
2398
        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;
 
2399
        skip_sleep = FALSE;
2700
2400
 
2701
2401
        for (i = 0; i < 10; i++) {
2702
 
                ulint   cur_time = ut_time_ms();
 
2402
                n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
 
2403
                        + buf_pool->n_pages_written;
 
2404
                srv_main_thread_op_info = "sleeping";
 
2405
                srv_main_1_second_loops++;
 
2406
 
 
2407
                if (!skip_sleep) {
 
2408
 
 
2409
                        os_thread_sleep(1000000);
 
2410
                        srv_main_sleeps++;
 
2411
                }
 
2412
 
 
2413
                skip_sleep = FALSE;
2703
2414
 
2704
2415
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2705
2416
                can drop tables lazily after there no longer are SELECT
2716
2427
                        goto background_loop;
2717
2428
                }
2718
2429
 
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
2430
                /* Flush logs if needed */
2743
2431
                srv_sync_log_buffer_in_background();
2744
2432
 
2746
2434
                log_free_check();
2747
2435
 
2748
2436
                /* 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. */
 
2437
                capacity, we assume that there is free disk i/o capacity
 
2438
                available, and it makes sense to do an insert buffer merge. */
2751
2439
 
2752
 
                buf_get_total_stat(&buf_stat);
2753
2440
                n_pend_ios = buf_get_n_pending_ios()
2754
2441
                        + log_sys->n_pending_writes;
2755
 
                n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2756
 
                        + buf_stat.n_pages_written;
 
2442
                n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2443
                        + buf_pool->n_pages_written;
2757
2444
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2758
2445
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
2759
2446
                        srv_main_thread_op_info = "doing insert buffer merge";
2769
2456
                        /* Try to keep the number of modified pages in the
2770
2457
                        buffer pool under the limit wished by the user */
2771
2458
 
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
 
 
 
2459
                        n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2460
                                                          PCT_IO(100),
 
2461
                                                          IB_ULONGLONG_MAX);
 
2462
 
 
2463
                        /* If we had to do the flush, it may have taken
 
2464
                        even more than 1 second, and also, there may be more
 
2465
                        to flush. Do not sleep 1 second during the next
 
2466
                        iteration of this loop. */
 
2467
 
 
2468
                        skip_sleep = TRUE;
2777
2469
                } else if (srv_adaptive_flushing) {
2778
2470
 
2779
2471
                        /* Try to keep the rate of flushing of dirty
2782
2474
                        ulint n_flush = buf_flush_get_desired_flush_rate();
2783
2475
 
2784
2476
                        if (n_flush) {
2785
 
                                srv_main_thread_op_info =
2786
 
                                        "flushing buffer pool pages";
2787
2477
                                n_flush = ut_min(PCT_IO(100), n_flush);
2788
2478
                                n_pages_flushed =
2789
 
                                        buf_flush_list(
 
2479
                                        buf_flush_batch(
 
2480
                                                BUF_FLUSH_LIST,
2790
2481
                                                n_flush,
2791
2482
                                                IB_ULONGLONG_MAX);
 
2483
                                skip_sleep = TRUE;
2792
2484
                        }
2793
2485
                }
2794
2486
 
2818
2510
        loop above requests writes for that case. The writes done here
2819
2511
        are not required, and may be disabled. */
2820
2512
 
2821
 
        buf_get_total_stat(&buf_stat);
2822
2513
        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;
 
2514
        n_ios = log_sys->n_log_ios + buf_pool->n_pages_read
 
2515
                + buf_pool->n_pages_written;
2825
2516
 
2826
2517
        srv_main_10_second_loops++;
2827
2518
        if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2828
2519
            && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
2829
2520
 
2830
2521
                srv_main_thread_op_info = "flushing buffer pool pages";
2831
 
                buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
 
2522
                buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
 
2523
                                IB_ULONGLONG_MAX);
2832
2524
 
2833
2525
                /* Flush logs if needed */
2834
2526
                srv_sync_log_buffer_in_background();
2843
2535
        /* Flush logs if needed */
2844
2536
        srv_sync_log_buffer_in_background();
2845
2537
 
2846
 
        if (srv_n_purge_threads == 0) {
2847
 
                srv_main_thread_op_info = "master purging";
2848
 
 
2849
 
                srv_master_do_purge();
 
2538
        /* We run a full purge every 10 seconds, even if the server
 
2539
        were active */
 
2540
        do {
2850
2541
 
2851
2542
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2852
2543
 
2853
2544
                        goto background_loop;
2854
2545
                }
2855
 
        }
 
2546
 
 
2547
                srv_main_thread_op_info = "purging";
 
2548
                n_pages_purged = trx_purge();
 
2549
 
 
2550
                /* Flush logs if needed */
 
2551
                srv_sync_log_buffer_in_background();
 
2552
 
 
2553
        } while (n_pages_purged);
2856
2554
 
2857
2555
        srv_main_thread_op_info = "flushing buffer pool pages";
2858
2556
 
2864
2562
                (> 70 %), we assume we can afford reserving the disk(s) for
2865
2563
                the time it requires to flush 100 pages */
2866
2564
 
2867
 
                n_pages_flushed = buf_flush_list(
2868
 
                        PCT_IO(100), IB_ULONGLONG_MAX);
 
2565
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2566
                                                  PCT_IO(100),
 
2567
                                                  IB_ULONGLONG_MAX);
2869
2568
        } else {
2870
2569
                /* Otherwise, we only flush a small number of pages so that
2871
2570
                we do not unnecessarily use much disk i/o capacity from
2872
2571
                other work */
2873
2572
 
2874
 
                n_pages_flushed = buf_flush_list(
2875
 
                          PCT_IO(10), IB_ULONGLONG_MAX);
 
2573
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2574
                                                  PCT_IO(10),
 
2575
                                                  IB_ULONGLONG_MAX);
2876
2576
        }
2877
2577
 
2878
2578
        srv_main_thread_op_info = "making checkpoint";
2916
2616
                MySQL tries to drop a table while there are still open handles
2917
2617
                to it and we had to put it to the background drop queue.) */
2918
2618
 
2919
 
                if (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
2920
 
                        os_thread_sleep(100000);
 
2619
                os_thread_sleep(100000);
 
2620
        }
 
2621
 
 
2622
        srv_main_thread_op_info = "purging";
 
2623
 
 
2624
        /* Run a full purge */
 
2625
        do {
 
2626
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
 
2627
 
 
2628
                        break;
2921
2629
                }
2922
 
        }
2923
 
 
2924
 
        if (srv_n_purge_threads == 0) {
2925
 
                srv_main_thread_op_info = "master purging";
2926
 
 
2927
 
                srv_master_do_purge();
2928
 
        }
 
2630
 
 
2631
                srv_main_thread_op_info = "purging";
 
2632
                n_pages_purged = trx_purge();
 
2633
 
 
2634
                /* Flush logs if needed */
 
2635
                srv_sync_log_buffer_in_background();
 
2636
 
 
2637
        } while (n_pages_purged);
2929
2638
 
2930
2639
        srv_main_thread_op_info = "reserving kernel mutex";
2931
2640
 
2943
2652
        } else {
2944
2653
                /* This should do an amount of IO similar to the number of
2945
2654
                dirty pages that will be flushed in the call to
2946
 
                buf_flush_list below. Otherwise, the system favors
 
2655
                buf_flush_batch below. Otherwise, the system favors
2947
2656
                clean pages over cleanup throughput. */
2948
2657
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2949
2658
                                                           PCT_IO(100));
2962
2671
        srv_main_thread_op_info = "flushing buffer pool pages";
2963
2672
        srv_main_flush_loops++;
2964
2673
        if (srv_fast_shutdown < 2) {
2965
 
                n_pages_flushed = buf_flush_list(
2966
 
                          PCT_IO(100), IB_ULONGLONG_MAX);
 
2674
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2675
                                                  PCT_IO(100),
 
2676
                                                  IB_ULONGLONG_MAX);
2967
2677
        } else {
2968
2678
                /* In the fastest shutdown we do not flush the buffer pool
2969
2679
                to data files: we set n_pages_flushed to 0 artificially. */
2981
2691
        mutex_exit(&kernel_mutex);
2982
2692
 
2983
2693
        srv_main_thread_op_info = "waiting for buffer pool flush to end";
2984
 
        buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
 
2694
        buf_flush_wait_batch_end(BUF_FLUSH_LIST);
2985
2695
 
2986
2696
        /* Flush logs if needed */
2987
2697
        srv_sync_log_buffer_in_background();
3068
2778
                already when the event wait ends */
3069
2779
 
3070
2780
                os_thread_exit(NULL);
3071
 
 
3072
2781
        }
3073
2782
 
3074
2783
        /* When there is user activity, InnoDB will set the event and the
3077
2786
        goto loop;
3078
2787
 
3079
2788
 
3080
 
#if !defined(__SUNPRO_C)
 
2789
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
3081
2790
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3082
2791
#endif
3083
2792
}
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
 
}