MySQL  8.0.22
Source Code Documentation
mysqld_thd_manager.h
Go to the documentation of this file.
1 /* Copyright (c) 2013, 2020, Oracle and/or its affiliates.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef MYSQLD_THD_MANAGER_INCLUDED
24 #define MYSQLD_THD_MANAGER_INCLUDED
25 
26 #include <stddef.h>
27 #include <sys/types.h>
28 #include <atomic>
29 
30 #include "my_dbug.h"
31 #include "my_inttypes.h"
32 #include "my_thread_local.h" // my_thread_id
35 #include "prealloced_array.h"
36 
37 class THD;
38 
41 
42 /**
43  Base class to perform actions on all thds in the thd list.
44  Users of do_for_all_thd() need to subclass this and override operator().
45 */
46 
47 class Do_THD_Impl {
48  public:
49  virtual ~Do_THD_Impl() {}
50  virtual void operator()(THD *) = 0;
51 };
52 
53 /**
54  Base class to find specific thd from the thd list.
55  Users of find_thd() need to subclass this and override operator()
56  to provide implementation to find thd from thd list.
57 */
58 
60  public:
61  virtual ~Find_THD_Impl() {}
62  /**
63  Override this operator to provide implementation to find specific thd.
64 
65  @param thd THD of one element in global thread list
66 
67  @returns bool
68  @retval true for matching thd
69  false otherwise
70  */
71  virtual bool operator()(THD *thd) = 0;
72 };
73 
74 /**
75  Callback function used by kill_one_thread and timer_notify functions
76  to find "thd" based on the thread id.
77 
78  @note It acquires LOCK_thd_data mutex when it finds matching thd.
79  It is the responsibility of the caller to release this mutex.
80 */
82  public:
83  Find_thd_with_id(my_thread_id value) : m_thread_id(value) {}
84  bool operator()(THD *thd) override;
85 
87 };
88 
89 /**
90  This class maintains THD object of all registered threads.
91  It provides interface to perform functions such as find, count,
92  perform some action for each THD object in the list.
93 
94  It also provide mutators for inserting, and removing an element:
95  add_thd() inserts a THD into the set, and increments the counter.
96  remove_thd() removes a THD from the set, and decrements the counter.
97  Method remove_thd() also broadcasts COND_thd_list.
98 */
99 
101  public:
102  /**
103  Value for thread_id reserved for THDs which does not have an
104  assigned value yet. get_new_thread_id() will never return this
105  value.
106  */
108 
109  /**
110  Retrieves singleton instance
111  */
113  DBUG_ASSERT(thd_manager != nullptr);
114  return thd_manager;
115  }
116 
117  /**
118  Initializes the thd manager.
119  Must be called before get_instance() can be used.
120 
121  @return true if initialization failed, false otherwise.
122  */
123  static bool create_instance();
124 
125  /**
126  Destroys the singleton instance.
127  */
128  static void destroy_instance();
129 
130  /**
131  Internally used to bypass code.
132  It enables unit test scripts to create dummy THD object for testing.
133  */
134  void set_unit_test() { unit_test = true; }
135 
136  /**
137  Adds THD to global THD list.
138 
139  @param thd THD object
140  */
141  void add_thd(THD *thd);
142 
143  /**
144  Removes THD from global THD list.
145 
146  @param thd THD object
147  */
148  void remove_thd(THD *thd);
149 
150  /**
151  Retrieves thread running statistic variable.
152  @return int Returns the total number of threads currently running
153  */
154  int get_num_thread_running() const { return atomic_num_thread_running; }
155 
156  /**
157  Increments thread running statistic variable.
158  */
159  void inc_thread_running() { atomic_num_thread_running++; }
160 
161  /**
162  Decrements thread running statistic variable.
163  */
164  void dec_thread_running() { atomic_num_thread_running--; }
165 
166  /**
167  Retrieves thread created statistic variable.
168  @return ulonglong Returns the total number of threads created
169  after server start
170  */
171  ulonglong get_num_thread_created() const { return atomic_thread_created; }
172 
173  /**
174  Increments thread created statistic variable.
175  */
176  void inc_thread_created() { atomic_thread_created++; }
177 
178  /**
179  Returns an unused thread id.
180  */
181  my_thread_id get_new_thread_id();
182 
183  /**
184  Releases a thread id so that it can be reused.
185  Note that this is done automatically by remove_thd().
186  */
187  void release_thread_id(my_thread_id thread_id);
188 
189  /**
190  Retrieves thread id counter value.
191  @return my_thread_id Returns the thread id counter value
192  @note This is a dirty read.
193  */
194  my_thread_id get_thread_id() const { return thread_id_counter; }
195 
196  /**
197  Sets thread id counter value. Only used in testing for now.
198  @param new_id The next ID to hand out (if it's unused).
199  */
200  void set_thread_id_counter(my_thread_id new_id);
201 
202  /**
203  Retrieves total number of items in global THD lists (all partitions).
204  @return uint Returns the count of items in global THD lists.
205  */
206  static uint get_thd_count() { return atomic_global_thd_count; }
207 
208  /**
209  Waits until all THDs are removed from global THD lists (all partitions).
210  In other words, get_thd_count() to become zero.
211  */
212  void wait_till_no_thd();
213 
214  /**
215  This function calls func() for all THDs in every thd list partition
216  after taking local copy of the THD list partition. It acquires
217  LOCK_thd_remove to prevent removal of the THD.
218  @param func Object of class which overrides operator()
219  */
220  void do_for_all_thd_copy(Do_THD_Impl *func);
221 
222  /**
223  This function calls func() for all THDs in all THD list partitions.
224  @param func Object of class which overrides operator()
225  @note One list partition is unlocked before the next partition is locked.
226  */
227  void do_for_all_thd(Do_THD_Impl *func);
228 
229  /**
230  Returns a pointer to the first THD for which operator() returns true.
231  @param func Object of class which overrides operator()
232  @return THD
233  @retval THD* Matching THD
234  @retval NULL When THD is not found
235  */
236  THD *find_thd(Find_THD_Impl *func);
237 
238  THD *find_thd(Find_thd_with_id *func);
239 
240  // Declared static as it is referenced in handle_fatal_signal()
241  static std::atomic<uint> atomic_global_thd_count;
242 
243  // Number of THD list partitions.
244  static const int NUM_PARTITIONS = 8;
245 
246  private:
249 
250  // Singleton instance.
252 
253  // Array of current THDs. Protected by LOCK_thd_list.
255  THD_array thd_list[NUM_PARTITIONS];
256 
257  // Array of thread ID in current use. Protected by LOCK_thread_ids.
259  Thread_id_array thread_ids;
260 
261  mysql_cond_t COND_thd_list[NUM_PARTITIONS];
262 
263  // Mutexes that guard thd_list partitions
264  mysql_mutex_t LOCK_thd_list[NUM_PARTITIONS];
265  // Mutexes used to guard removal of elements from thd_list partitions.
266  mysql_mutex_t LOCK_thd_remove[NUM_PARTITIONS];
267  // Mutex protecting thread_ids
269 
270  // Count of active threads which are running queries in the system.
271  std::atomic<int> atomic_num_thread_running;
272 
273  // Cumulative number of threads created by mysqld daemon.
274  std::atomic<ulonglong> atomic_thread_created;
275 
276  // Counter to assign thread id.
278 
279  // Used during unit test to bypass creating real THD object.
280  bool unit_test;
281 
282  friend void thd_lock_thread_count();
283  friend void thd_unlock_thread_count();
284 };
285 
286 #endif /* MYSQLD_INCLUDED */
Find_thd_with_id(my_thread_id value)
Definition: mysqld_thd_manager.h:83
my_thread_id thread_id_counter
Definition: mysqld_thd_manager.h:277
This class maintains THD object of all registered threads.
Definition: mysqld_thd_manager.h:100
unsigned long long int ulonglong
Definition: my_inttypes.h:55
Callback function used by kill_one_thread and timer_notify functions to find "thd" based on the threa...
Definition: mysqld_thd_manager.h:81
std::atomic< int > atomic_num_thread_running
Definition: mysqld_thd_manager.h:271
my_thread_id get_thread_id() const
Retrieves thread id counter value.
Definition: mysqld_thd_manager.h:194
Thread_id_array thread_ids
Definition: mysqld_thd_manager.h:259
An instrumented cond structure.
Definition: mysql_cond_bits.h:49
Prealloced_array< THD *, 60 > THD_array
Definition: mysqld_thd_manager.h:254
mysql_mutex_t LOCK_thread_ids
Definition: mysqld_thd_manager.h:268
Some integer typedefs for easier portability.
void dec_thread_running()
Decrements thread running statistic variable.
Definition: mysqld_thd_manager.h:164
static uint get_thd_count()
Retrieves total number of items in global THD lists (all partitions).
Definition: mysqld_thd_manager.h:206
Instrumentation helpers for conditions.
void inc_thread_running()
Increments thread running statistic variable.
Definition: mysqld_thd_manager.h:159
#define create_instance
Definition: embedded_default_engine.c:7
static Global_THD_manager * get_instance()
Retrieves singleton instance.
Definition: mysqld_thd_manager.h:112
static std::atomic< uint > atomic_global_thd_count
Definition: mysqld_thd_manager.h:241
#define DBUG_ASSERT(A)
Definition: my_dbug.h:199
Base class to perform actions on all thds in the thd list.
Definition: mysqld_thd_manager.h:47
int get_num_thread_running() const
Retrieves thread running statistic variable.
Definition: mysqld_thd_manager.h:154
virtual void operator()(THD *)=0
unsigned int uint
Definition: uca-dump.cc:29
void thd_lock_thread_count()
Definition: mysqld_thd_manager.cc:322
const my_thread_id m_thread_id
Definition: mysqld_thd_manager.h:86
void set_unit_test()
Internally used to bypass code.
Definition: mysqld_thd_manager.h:134
bool unit_test
Definition: mysqld_thd_manager.h:280
ulonglong get_num_thread_created() const
Retrieves thread created statistic variable.
Definition: mysqld_thd_manager.h:171
void do_for_all_thd(do_thd_impl_uint64, uint64)
Definition: mysqld_thd_manager.cc:349
uint32_t new_id()
Create a new (hopefully unique) ID.
Definition: xcom_base.cc:1497
void inc_thread_created()
Increments thread created statistic variable.
Definition: mysqld_thd_manager.h:176
uint32 my_thread_id
Definition: my_thread_local.h:33
void thd_unlock_thread_count()
Definition: mysqld_thd_manager.cc:327
An instrumented mutex structure.
Definition: mysql_mutex_bits.h:49
ABI for instrumented mutexes.
static const my_thread_id reserved_thread_id
Value for thread_id reserved for THDs which does not have an assigned value yet.
Definition: mysqld_thd_manager.h:107
Base class to find specific thd from the thd list.
Definition: mysqld_thd_manager.h:59
Prealloced_array< my_thread_id, 1000 > Thread_id_array
Definition: mysqld_thd_manager.h:258
virtual ~Do_THD_Impl()
Definition: mysqld_thd_manager.h:49
std::atomic< ulonglong > atomic_thread_created
Definition: mysqld_thd_manager.h:274
const string value("\alue\)
static Global_THD_manager * thd_manager
Definition: mysqld_thd_manager.h:251
virtual ~Find_THD_Impl()
Definition: mysqld_thd_manager.h:61
static my_thread_id thread_id
Definition: my_thr_init.cc:62
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:803