1 /* Copyright (c) 2012, 2021, 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 Foundation,
21   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 /**
24   @file storage/perfschema/pfs_autosize.cc
25   Private interface for the server (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "sql_const.h"
30 #include "pfs_server.h"
31 
32 #include <my_thread.h> /* For pthread_t */
33 /* Make sure HAVE_PSI_XXX_INTERFACE flags are set */
34 #include "mysql/psi/psi.h"
35 
36 #include <algorithm>
37 using std::min;
38 using std::max;
39 
40 /** Performance schema sizing heuristics. */
41 struct PFS_sizing_data
42 {
43   /** Default value for @c PFS_param.m_events_waits_history_sizing. */
44   ulong m_events_waits_history_sizing;
45   /** Default value for @c PFS_param.m_events_waits_history_long_sizing. */
46   ulong m_events_waits_history_long_sizing;
47   /** Default value for @c PFS_param.m_events_stages_history_sizing. */
48   ulong m_events_stages_history_sizing;
49   /** Default value for @c PFS_param.m_events_stages_history_long_sizing. */
50   ulong m_events_stages_history_long_sizing;
51   /** Default value for @c PFS_param.m_events_statements_history_sizing. */
52   ulong m_events_statements_history_sizing;
53   /** Default value for @c PFS_param.m_events_statements_history_long_sizing. */
54   ulong m_events_statements_history_long_sizing;
55   /** Default value for @c PFS_param.m_events_transactions_history_sizing. */
56   ulong m_events_transactions_history_sizing;
57   /** Default value for @c PFS_param.m_events_transactions_history_long_sizing. */
58   ulong m_events_transactions_history_long_sizing;
59   /** Default value for @c PFS_param.m_digest_sizing. */
60   ulong m_digest_sizing;
61   /** Default value for @c PFS_param.m_session_connect_attrs_sizing. */
62   ulong m_session_connect_attrs_sizing;
63 };
64 
65 PFS_sizing_data small_data=
66 {
67   /* History sizes */
68   5, 100, 5, 100, 5, 100, 5, 100,
69   /* Digests */
70   1000,
71   /* Session connect attrs. */
72   512
73 };
74 
75 PFS_sizing_data medium_data=
76 {
77   /* History sizes */
78   10, 1000, 10, 1000, 10, 1000, 10, 1000,
79   /* Digests */
80   5000,
81   /* Session connect attrs. */
82   512
83 };
84 
85 PFS_sizing_data large_data=
86 {
87   /* History sizes */
88   10, 10000, 10, 10000, 10, 10000, 10, 10000,
89   /* Digests */
90   10000,
91   /* Session connect attrs. */
92   512
93 };
94 
estimate_hints(PFS_global_param * param)95 PFS_sizing_data *estimate_hints(PFS_global_param *param)
96 {
97   if ((param->m_hints.m_max_connections <= MAX_CONNECTIONS_DEFAULT) &&
98       (param->m_hints.m_table_definition_cache <= TABLE_DEF_CACHE_DEFAULT) &&
99       (param->m_hints.m_table_open_cache <= TABLE_OPEN_CACHE_DEFAULT))
100   {
101     /* The my.cnf used is either unchanged, or lower than factory defaults. */
102     return & small_data;
103   }
104 
105   if ((param->m_hints.m_max_connections <= MAX_CONNECTIONS_DEFAULT * 2) &&
106       (param->m_hints.m_table_definition_cache <= TABLE_DEF_CACHE_DEFAULT * 2) &&
107       (param->m_hints.m_table_open_cache <= TABLE_OPEN_CACHE_DEFAULT * 2))
108   {
109     /* Some defaults have been increased, to "moderate" values. */
110     return & medium_data;
111   }
112 
113   /* Looks like a server in production. */
114   return & large_data;
115 }
116 
apply_heuristic(PFS_global_param * p,PFS_sizing_data * h)117 static void apply_heuristic(PFS_global_param *p, PFS_sizing_data *h)
118 {
119   if (p->m_events_waits_history_sizing < 0)
120   {
121     p->m_events_waits_history_sizing= h->m_events_waits_history_sizing;
122   }
123 
124   if (p->m_events_waits_history_long_sizing < 0)
125   {
126     p->m_events_waits_history_long_sizing= h->m_events_waits_history_long_sizing;
127   }
128 
129   if (p->m_events_stages_history_sizing < 0)
130   {
131     p->m_events_stages_history_sizing= h->m_events_stages_history_sizing;
132   }
133 
134   if (p->m_events_stages_history_long_sizing < 0)
135   {
136     p->m_events_stages_history_long_sizing= h->m_events_stages_history_long_sizing;
137   }
138 
139   if (p->m_events_statements_history_sizing < 0)
140   {
141     p->m_events_statements_history_sizing= h->m_events_statements_history_sizing;
142   }
143 
144   if (p->m_events_statements_history_long_sizing < 0)
145   {
146     p->m_events_statements_history_long_sizing= h->m_events_statements_history_long_sizing;
147   }
148 
149   if (p->m_digest_sizing < 0)
150   {
151     p->m_digest_sizing= h->m_digest_sizing;
152   }
153 
154   if (p->m_events_transactions_history_sizing < 0)
155   {
156     p->m_events_transactions_history_sizing= h->m_events_transactions_history_sizing;
157   }
158 
159   if (p->m_events_transactions_history_long_sizing < 0)
160   {
161     p->m_events_transactions_history_long_sizing= h->m_events_transactions_history_long_sizing;
162   }
163 
164   if (p->m_session_connect_attrs_sizing < 0)
165   {
166     p->m_session_connect_attrs_sizing= h->m_session_connect_attrs_sizing;
167   }
168 }
169 
pfs_automated_sizing(PFS_global_param * param)170 void pfs_automated_sizing(PFS_global_param *param)
171 {
172   if (param->m_enabled)
173   {
174 #ifndef HAVE_PSI_MUTEX_INTERFACE
175     param->m_mutex_class_sizing= 0;
176     param->m_mutex_sizing= 0;
177 #endif
178 
179 #ifndef HAVE_PSI_RWLOCK_INTERFACE
180     param->m_rwlock_class_sizing= 0;
181     param->m_rwlock_sizing= 0;
182 #endif
183 
184 #ifndef HAVE_PSI_COND_INTERFACE
185     param->m_cond_class_sizing= 0;
186     param->m_cond_sizing= 0;
187 #endif
188 
189 #ifndef HAVE_PSI_FILE_INTERFACE
190     param->m_file_class_sizing= 0;
191     param->m_file_sizing= 0;
192     param->m_file_handle_sizing= 0;
193 #endif
194 
195 #ifndef HAVE_PSI_TABLE_INTERFACE
196     param->m_table_share_sizing= 0;
197     param->m_table_sizing= 0;
198     param->m_table_lock_stat_sizing= 0;
199     param->m_index_stat_sizing= 0;
200 #endif
201 
202 #ifndef HAVE_PSI_SOCKET_INTERFACE
203     param->m_socket_class_sizing= 0;
204     param->m_socket_sizing= 0;
205 #endif
206 
207 #ifndef HAVE_PSI_STAGE_INTERFACE
208     param->m_stage_class_sizing= 0;
209     param->m_events_stages_history_sizing= 0;
210     param->m_events_stages_history_long_sizing= 0;
211 #endif
212 
213 #ifndef HAVE_PSI_STATEMENT_INTERFACE
214     param->m_statement_class_sizing= 0;
215     param->m_events_statements_history_sizing= 0;
216     param->m_events_statements_history_long_sizing= 0;
217 #endif
218 
219 #ifndef HAVE_PSI_SP_INTERFACE
220     param->m_program_sizing= 0;
221     if (param->m_statement_stack_sizing > 1)
222       param->m_statement_stack_sizing= 1;
223 #endif
224 
225 #ifndef HAVE_PSI_PS_INTERFACE
226     param->m_prepared_stmt_sizing= 0;
227 #endif
228 
229 #ifndef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
230     param->m_digest_sizing= 0;
231 #endif
232 
233 #ifndef HAVE_PSI_METADATA_INTERFACE
234     param->m_metadata_lock_sizing= 0;
235 #endif
236 
237 #ifndef HAVE_PSI_MEMORY_INTERFACE
238     param->m_memory_class_sizing= 0;
239 #endif
240 
241     PFS_sizing_data *heuristic;
242     heuristic= estimate_hints(param);
243     apply_heuristic(param, heuristic);
244 
245     assert(param->m_events_waits_history_sizing >= 0);
246     assert(param->m_events_waits_history_long_sizing >= 0);
247     assert(param->m_events_stages_history_sizing >= 0);
248     assert(param->m_events_stages_history_long_sizing >= 0);
249     assert(param->m_events_statements_history_sizing >= 0);
250     assert(param->m_events_statements_history_long_sizing >= 0);
251     assert(param->m_events_transactions_history_sizing >= 0);
252     assert(param->m_events_transactions_history_long_sizing >= 0);
253     assert(param->m_session_connect_attrs_sizing >= 0);
254   }
255   else
256   {
257     /*
258       The Performance Schema is disabled. Set the instrument sizings to zero to
259       disable all instrumentation while retaining support for the status and
260       system variable tables, the host cache table and the replication tables.
261     */
262     param->m_mutex_class_sizing= 0;
263     param->m_rwlock_class_sizing= 0;
264     param->m_cond_class_sizing= 0;
265     param->m_thread_class_sizing= 0;
266     param->m_table_share_sizing= 0;
267     param->m_table_lock_stat_sizing= 0;
268     param->m_index_stat_sizing= 0;
269     param->m_file_class_sizing= 0;
270     param->m_mutex_sizing= 0;
271     param->m_rwlock_sizing= 0;
272     param->m_cond_sizing= 0;
273     param->m_thread_sizing= 0;
274     param->m_table_sizing= 0;
275     param->m_file_sizing= 0;
276     param->m_file_handle_sizing= 0;
277     param->m_socket_sizing= 0;
278     param->m_socket_class_sizing= 0;
279     param->m_events_waits_history_sizing= 0;
280     param->m_events_waits_history_long_sizing= 0;
281     param->m_setup_actor_sizing= 0;
282     param->m_setup_object_sizing= 0;
283     param->m_host_sizing= 0;
284     param->m_user_sizing= 0;
285     param->m_account_sizing= 0;
286     param->m_stage_class_sizing= 0;
287     param->m_events_stages_history_sizing= 0;
288     param->m_events_stages_history_long_sizing= 0;
289     param->m_statement_class_sizing= 0;
290     param->m_events_statements_history_sizing= 0;
291     param->m_events_statements_history_long_sizing= 0;
292     param->m_digest_sizing= 0;
293     param->m_program_sizing= 0;
294     param->m_prepared_stmt_sizing= 0;
295     param->m_events_transactions_history_sizing= 0;
296     param->m_events_transactions_history_long_sizing= 0;
297     param->m_session_connect_attrs_sizing= 0;
298     param->m_statement_stack_sizing= 0;
299     param->m_memory_class_sizing= 0;
300     param->m_metadata_lock_sizing= 0;
301     param->m_max_digest_length= 0;
302     param->m_max_sql_text_length= 0;
303   }
304 }
305 
306