1 /* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
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
24 /**
25 @file storage/perfschema/pfs_account.cc
26 Performance schema account (implementation).
27 */
28
29 #include "storage/perfschema/pfs_account.h"
30
31 #include "my_compiler.h"
32 #include "my_dbug.h"
33 #include "my_sys.h"
34 #include "sql/mysqld.h" // global_status_var
35 #include "storage/perfschema/pfs.h"
36 #include "storage/perfschema/pfs_buffer_container.h"
37 #include "storage/perfschema/pfs_global.h"
38 #include "storage/perfschema/pfs_host.h"
39 #include "storage/perfschema/pfs_instr.h"
40 #include "storage/perfschema/pfs_instr_class.h"
41 #include "storage/perfschema/pfs_setup_actor.h"
42 #include "storage/perfschema/pfs_stat.h"
43 #include "storage/perfschema/pfs_user.h"
44
45 /**
46 @addtogroup performance_schema_buffers
47 @{
48 */
49
50 LF_HASH account_hash;
51 static bool account_hash_inited = false;
52
53 /**
54 Initialize the user buffers.
55 @param param sizing parameters
56 @return 0 on success
57 */
init_account(const PFS_global_param * param)58 int init_account(const PFS_global_param *param) {
59 if (global_account_container.init(param->m_account_sizing)) {
60 return 1;
61 }
62
63 return 0;
64 }
65
66 /** Cleanup all the account buffers. */
cleanup_account(void)67 void cleanup_account(void) { global_account_container.cleanup(); }
68
account_hash_get_key(const uchar * entry,size_t * length)69 static const uchar *account_hash_get_key(const uchar *entry, size_t *length) {
70 const PFS_account *const *typed_entry;
71 const PFS_account *account;
72 const void *result;
73 typed_entry = reinterpret_cast<const PFS_account *const *>(entry);
74 DBUG_ASSERT(typed_entry != nullptr);
75 account = *typed_entry;
76 DBUG_ASSERT(account != nullptr);
77 *length = account->m_key.m_key_length;
78 result = account->m_key.m_hash_key;
79 return reinterpret_cast<const uchar *>(result);
80 }
81
82 /**
83 Initialize the user hash.
84 @return 0 on success
85 */
init_account_hash(const PFS_global_param * param)86 int init_account_hash(const PFS_global_param *param) {
87 if ((!account_hash_inited) && (param->m_account_sizing != 0)) {
88 lf_hash_init(&account_hash, sizeof(PFS_account *), LF_HASH_UNIQUE, 0, 0,
89 account_hash_get_key, &my_charset_bin);
90 account_hash_inited = true;
91 }
92 return 0;
93 }
94
95 /** Cleanup the user hash. */
cleanup_account_hash(void)96 void cleanup_account_hash(void) {
97 if (account_hash_inited) {
98 lf_hash_destroy(&account_hash);
99 account_hash_inited = false;
100 }
101 }
102
get_account_hash_pins(PFS_thread * thread)103 static LF_PINS *get_account_hash_pins(PFS_thread *thread) {
104 if (unlikely(thread->m_account_hash_pins == nullptr)) {
105 if (!account_hash_inited) {
106 return nullptr;
107 }
108 thread->m_account_hash_pins = lf_hash_get_pins(&account_hash);
109 }
110 return thread->m_account_hash_pins;
111 }
112
set_account_key(PFS_account_key * key,const char * user,uint user_length,const char * host,uint host_length)113 static void set_account_key(PFS_account_key *key, const char *user,
114 uint user_length, const char *host,
115 uint host_length) {
116 DBUG_ASSERT(user_length <= USERNAME_LENGTH);
117 DBUG_ASSERT(host_length <= HOSTNAME_LENGTH);
118
119 char *ptr = &key->m_hash_key[0];
120 if (user_length > 0) {
121 memcpy(ptr, user, user_length);
122 ptr += user_length;
123 }
124 ptr[0] = 0;
125 ptr++;
126 if (host_length > 0) {
127 memcpy(ptr, host, host_length);
128 ptr += host_length;
129 }
130 ptr[0] = 0;
131 ptr++;
132 key->m_key_length = ptr - &key->m_hash_key[0];
133 }
134
find_or_create_account(PFS_thread * thread,const char * username,uint username_length,const char * hostname,uint hostname_length)135 PFS_account *find_or_create_account(PFS_thread *thread, const char *username,
136 uint username_length, const char *hostname,
137 uint hostname_length) {
138 LF_PINS *pins = get_account_hash_pins(thread);
139 if (unlikely(pins == nullptr)) {
140 global_account_container.m_lost++;
141 return nullptr;
142 }
143
144 PFS_account_key key;
145 set_account_key(&key, username, username_length, hostname, hostname_length);
146
147 PFS_account **entry;
148 PFS_account *pfs;
149 uint retry_count = 0;
150 const uint retry_max = 3;
151 pfs_dirty_state dirty_state;
152
153 search:
154 entry = reinterpret_cast<PFS_account **>(
155 lf_hash_search(&account_hash, pins, key.m_hash_key, key.m_key_length));
156 if (entry && (entry != MY_LF_ERRPTR)) {
157 pfs = *entry;
158 pfs->inc_refcount();
159 lf_hash_search_unpin(pins);
160 return pfs;
161 }
162
163 lf_hash_search_unpin(pins);
164
165 pfs = global_account_container.allocate(&dirty_state);
166 if (pfs != nullptr) {
167 pfs->m_key = key;
168 if (username_length > 0) {
169 pfs->m_username = &pfs->m_key.m_hash_key[0];
170 } else {
171 pfs->m_username = nullptr;
172 }
173 pfs->m_username_length = username_length;
174
175 if (hostname_length > 0) {
176 pfs->m_hostname = &pfs->m_key.m_hash_key[username_length + 1];
177 } else {
178 pfs->m_hostname = nullptr;
179 }
180 pfs->m_hostname_length = hostname_length;
181
182 pfs->m_user = find_or_create_user(thread, username, username_length);
183 pfs->m_host = find_or_create_host(thread, hostname, hostname_length);
184
185 pfs->init_refcount();
186 pfs->reset_stats();
187 pfs->m_disconnected_count = 0;
188
189 if (username_length > 0 && hostname_length > 0) {
190 lookup_setup_actor(thread, username, username_length, hostname,
191 hostname_length, &pfs->m_enabled, &pfs->m_history);
192 } else {
193 pfs->m_enabled = true;
194 pfs->m_history = true;
195 }
196
197 int res;
198 pfs->m_lock.dirty_to_allocated(&dirty_state);
199 res = lf_hash_insert(&account_hash, pins, &pfs);
200 if (likely(res == 0)) {
201 return pfs;
202 }
203
204 if (pfs->m_user) {
205 pfs->m_user->release();
206 pfs->m_user = nullptr;
207 }
208 if (pfs->m_host) {
209 pfs->m_host->release();
210 pfs->m_host = nullptr;
211 }
212
213 global_account_container.deallocate(pfs);
214
215 if (res > 0) {
216 if (++retry_count > retry_max) {
217 global_account_container.m_lost++;
218 return nullptr;
219 }
220 goto search;
221 }
222
223 global_account_container.m_lost++;
224 return nullptr;
225 }
226
227 return nullptr;
228 }
229
aggregate(bool alive,PFS_user * safe_user,PFS_host * safe_host)230 void PFS_account::aggregate(bool alive, PFS_user *safe_user,
231 PFS_host *safe_host) {
232 aggregate_waits(safe_user, safe_host);
233 aggregate_stages(safe_user, safe_host);
234 aggregate_statements(safe_user, safe_host);
235 aggregate_transactions(safe_user, safe_host);
236 aggregate_errors(safe_user, safe_host);
237 aggregate_memory(alive, safe_user, safe_host);
238 aggregate_status(safe_user, safe_host);
239 aggregate_stats(safe_user, safe_host);
240 }
241
aggregate_waits(PFS_user * safe_user,PFS_host * safe_host)242 void PFS_account::aggregate_waits(PFS_user *safe_user, PFS_host *safe_host) {
243 if (read_instr_class_waits_stats() == nullptr) {
244 return;
245 }
246
247 if (likely(safe_user != nullptr && safe_host != nullptr)) {
248 /*
249 Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
250 - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
251 - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
252 in parallel.
253 */
254 aggregate_all_event_names(write_instr_class_waits_stats(),
255 safe_user->write_instr_class_waits_stats(),
256 safe_host->write_instr_class_waits_stats());
257 return;
258 }
259
260 if (safe_user != nullptr) {
261 /*
262 Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
263 - EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME
264 */
265 aggregate_all_event_names(write_instr_class_waits_stats(),
266 safe_user->write_instr_class_waits_stats());
267 return;
268 }
269
270 if (safe_host != nullptr) {
271 /*
272 Aggregate EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
273 - EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME
274 */
275 aggregate_all_event_names(write_instr_class_waits_stats(),
276 safe_host->write_instr_class_waits_stats());
277 return;
278 }
279
280 /* Orphan account, no parent to aggregate to. */
281 reset_waits_stats();
282 return;
283 }
284
aggregate_stages(PFS_user * safe_user,PFS_host * safe_host)285 void PFS_account::aggregate_stages(PFS_user *safe_user, PFS_host *safe_host) {
286 if (read_instr_class_stages_stats() == nullptr) {
287 return;
288 }
289
290 if (likely(safe_user != nullptr && safe_host != nullptr)) {
291 /*
292 Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
293 - EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME
294 - EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME
295 in parallel.
296 */
297 aggregate_all_stages(write_instr_class_stages_stats(),
298 safe_user->write_instr_class_stages_stats(),
299 safe_host->write_instr_class_stages_stats());
300 return;
301 }
302
303 if (safe_user != nullptr) {
304 /*
305 Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
306 - EVENTS_STAGES_SUMMARY_BY_USER_BY_EVENT_NAME
307 - EVENTS_STAGES_SUMMARY_GLOBAL_BY_EVENT_NAME
308 in parallel.
309 */
310 aggregate_all_stages(write_instr_class_stages_stats(),
311 safe_user->write_instr_class_stages_stats(),
312 global_instr_class_stages_array);
313 return;
314 }
315
316 if (safe_host != nullptr) {
317 /*
318 Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
319 - EVENTS_STAGES_SUMMARY_BY_HOST_BY_EVENT_NAME
320 */
321 aggregate_all_stages(write_instr_class_stages_stats(),
322 safe_host->write_instr_class_stages_stats());
323 return;
324 }
325
326 /*
327 Aggregate EVENTS_STAGES_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
328 - EVENTS_STAGES_SUMMARY_GLOBAL_BY_EVENT_NAME
329 */
330 aggregate_all_stages(write_instr_class_stages_stats(),
331 global_instr_class_stages_array);
332 return;
333 }
334
aggregate_statements(PFS_user * safe_user,PFS_host * safe_host)335 void PFS_account::aggregate_statements(PFS_user *safe_user,
336 PFS_host *safe_host) {
337 if (read_instr_class_statements_stats() == nullptr) {
338 return;
339 }
340
341 if (likely(safe_user != nullptr && safe_host != nullptr)) {
342 /*
343 Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
344 - EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME
345 - EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME
346 in parallel.
347 */
348 aggregate_all_statements(write_instr_class_statements_stats(),
349 safe_user->write_instr_class_statements_stats(),
350 safe_host->write_instr_class_statements_stats());
351 return;
352 }
353
354 if (safe_user != nullptr) {
355 /*
356 Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
357 - EVENTS_STATEMENTS_SUMMARY_BY_USER_BY_EVENT_NAME
358 - EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_EVENT_NAME
359 in parallel.
360 */
361 aggregate_all_statements(write_instr_class_statements_stats(),
362 safe_user->write_instr_class_statements_stats(),
363 global_instr_class_statements_array);
364 return;
365 }
366
367 if (safe_host != nullptr) {
368 /*
369 Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
370 - EVENTS_STATEMENTS_SUMMARY_BY_HOST_BY_EVENT_NAME
371 */
372 aggregate_all_statements(write_instr_class_statements_stats(),
373 safe_host->write_instr_class_statements_stats());
374 return;
375 }
376
377 /*
378 Aggregate EVENTS_STATEMENTS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
379 - EVENTS_STATEMENTS_SUMMARY_GLOBAL_BY_EVENT_NAME
380 */
381 aggregate_all_statements(write_instr_class_statements_stats(),
382 global_instr_class_statements_array);
383 return;
384 }
385
aggregate_transactions(PFS_user * safe_user,PFS_host * safe_host)386 void PFS_account::aggregate_transactions(PFS_user *safe_user,
387 PFS_host *safe_host) {
388 if (read_instr_class_transactions_stats() == nullptr) {
389 return;
390 }
391
392 if (likely(safe_user != nullptr && safe_host != nullptr)) {
393 /*
394 Aggregate EVENTS_TRANSACTIONS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
395 - EVENTS_TRANSACTIONS_SUMMARY_BY_USER_BY_EVENT_NAME
396 - EVENTS_TRANSACTIONS_SUMMARY_BY_HOST_BY_EVENT_NAME
397 in parallel.
398 */
399 aggregate_all_transactions(
400 write_instr_class_transactions_stats(),
401 safe_user->write_instr_class_transactions_stats(),
402 safe_host->write_instr_class_transactions_stats());
403 return;
404 }
405
406 if (safe_user != nullptr) {
407 /*
408 Aggregate EVENTS_TRANSACTIONS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
409 - EVENTS_TRANSACTIONS_SUMMARY_BY_USER_BY_EVENT_NAME
410 - EVENTS_TRANSACTIONS_SUMMARY_GLOBAL_BY_EVENT_NAME
411 in parallel.
412 */
413 aggregate_all_transactions(
414 write_instr_class_transactions_stats(),
415 safe_user->write_instr_class_transactions_stats(),
416 &global_transaction_stat);
417 return;
418 }
419
420 if (safe_host != nullptr) {
421 /*
422 Aggregate EVENTS_TRANSACTIONS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
423 - EVENTS_TRANSACTIONS_SUMMARY_BY_HOST_BY_EVENT_NAME
424 */
425 aggregate_all_transactions(
426 write_instr_class_transactions_stats(),
427 safe_host->write_instr_class_transactions_stats());
428 return;
429 }
430
431 /*
432 Aggregate EVENTS_TRANSACTIONS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
433 - EVENTS_TRANSACTIONS_SUMMARY_GLOBAL_BY_EVENT_NAME
434 */
435 aggregate_all_transactions(write_instr_class_transactions_stats(),
436 &global_transaction_stat);
437 return;
438 }
439
aggregate_errors(PFS_user * safe_user,PFS_host * safe_host)440 void PFS_account::aggregate_errors(PFS_user *safe_user, PFS_host *safe_host) {
441 if (read_instr_class_errors_stats() == nullptr) {
442 return;
443 }
444
445 if (likely(safe_user != nullptr && safe_host != nullptr)) {
446 /*
447 Aggregate EVENTS_ERRORS_SUMMARY_BY_ACCOUNT_BY_ERROR to:
448 - EVENTS_ERRORS_SUMMARY_BY_USER_BY_ERROR
449 - EVENTS_ERRORS_SUMMARY_BY_HOST_BY_ERROR
450 in parallel.
451 */
452 aggregate_all_errors(write_instr_class_errors_stats(),
453 safe_user->write_instr_class_errors_stats(),
454 safe_host->write_instr_class_errors_stats());
455 return;
456 }
457
458 if (safe_user != nullptr) {
459 /*
460 Aggregate EVENTS_ERRORS_SUMMARY_BY_ACCOUNT_BY_ERROR to:
461 - EVENTS_ERRORS_SUMMARY_BY_USER_BY_ERROR
462 - EVENTS_ERRORS_SUMMARY_GLOBAL_BY_ERROR
463 in parallel.
464 */
465 aggregate_all_errors(write_instr_class_errors_stats(),
466 safe_user->write_instr_class_errors_stats(),
467 &global_error_stat);
468 return;
469 }
470
471 if (safe_host != nullptr) {
472 /*
473 Aggregate EVENTS_ERRORS_SUMMARY_BY_ACCOUNT_BY_ERROR to:
474 - EVENTS_ERRORS_SUMMARY_BY_HOST_BY_ERROR
475 */
476 aggregate_all_errors(write_instr_class_errors_stats(),
477 safe_host->write_instr_class_errors_stats());
478 return;
479 }
480
481 /*
482 Aggregate EVENTS_ERRORS_SUMMARY_BY_ACCOUNT_BY_ERROR to:
483 - EVENTS_ERRORS_SUMMARY_GLOBAL_BY_ERROR
484 */
485 aggregate_all_errors(write_instr_class_errors_stats(), &global_error_stat);
486 return;
487 }
488
aggregate_memory(bool alive,PFS_user * safe_user,PFS_host * safe_host)489 void PFS_account::aggregate_memory(bool alive, PFS_user *safe_user,
490 PFS_host *safe_host) {
491 if (read_instr_class_memory_stats() == nullptr) {
492 return;
493 }
494
495 if (likely(safe_user != nullptr && safe_host != nullptr)) {
496 /*
497 Aggregate MEMORY_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
498 - MEMORY_SUMMARY_BY_USER_BY_EVENT_NAME
499 - MEMORY_SUMMARY_BY_HOST_BY_EVENT_NAME
500 in parallel.
501 */
502 aggregate_all_memory(alive, write_instr_class_memory_stats(),
503 safe_user->write_instr_class_memory_stats(),
504 safe_host->write_instr_class_memory_stats());
505 return;
506 }
507
508 if (safe_user != nullptr) {
509 /*
510 Aggregate MEMORY_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
511 - MEMORY_SUMMARY_BY_USER_BY_EVENT_NAME
512 - MEMORY_SUMMARY_GLOBAL_BY_EVENT_NAME
513 in parallel.
514 */
515 aggregate_all_memory(alive, write_instr_class_memory_stats(),
516 safe_user->write_instr_class_memory_stats(),
517 global_instr_class_memory_array);
518 return;
519 }
520
521 if (safe_host != nullptr) {
522 /*
523 Aggregate MEMORY_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
524 - MEMORY_SUMMARY_BY_HOST_BY_EVENT_NAME
525 */
526 aggregate_all_memory(alive, write_instr_class_memory_stats(),
527 safe_host->write_instr_class_memory_stats());
528 return;
529 }
530
531 /*
532 Aggregate MEMORY_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME to:
533 - MEMORY_SUMMARY_GLOBAL_BY_EVENT_NAME
534 */
535 aggregate_all_memory(alive, write_instr_class_memory_stats(),
536 global_instr_class_memory_array);
537 return;
538 }
539
aggregate_status(PFS_user * safe_user,PFS_host * safe_host)540 void PFS_account::aggregate_status(PFS_user *safe_user, PFS_host *safe_host) {
541 if (likely(safe_user != nullptr && safe_host != nullptr)) {
542 /*
543 Aggregate STATUS_BY_ACCOUNT to:
544 - STATUS_BY_USER
545 - STATUS_BY_HOST
546 */
547 safe_user->m_status_stats.aggregate(&m_status_stats);
548 safe_host->m_status_stats.aggregate(&m_status_stats);
549 m_status_stats.reset();
550 return;
551 }
552
553 if (safe_user != nullptr) {
554 /*
555 Aggregate STATUS_BY_ACCOUNT to:
556 - STATUS_BY_USER
557 - GLOBAL_STATUS
558 */
559 safe_user->m_status_stats.aggregate(&m_status_stats);
560 m_status_stats.aggregate_to(&global_status_var);
561 m_status_stats.reset();
562 return;
563 }
564
565 if (safe_host != nullptr) {
566 /*
567 Aggregate STATUS_BY_ACCOUNT to:
568 - STATUS_BY_HOST
569 */
570 safe_host->m_status_stats.aggregate(&m_status_stats);
571 m_status_stats.reset();
572 return;
573 }
574
575 /*
576 Aggregate STATUS_BY_ACCOUNT to:
577 - GLOBAL_STATUS
578 */
579 m_status_stats.aggregate_to(&global_status_var);
580 m_status_stats.reset();
581 return;
582 }
583
aggregate_stats(PFS_user * safe_user,PFS_host * safe_host)584 void PFS_account::aggregate_stats(PFS_user *safe_user, PFS_host *safe_host) {
585 if (likely(safe_user != nullptr && safe_host != nullptr)) {
586 safe_user->m_disconnected_count += m_disconnected_count;
587 safe_host->m_disconnected_count += m_disconnected_count;
588 m_disconnected_count = 0;
589 return;
590 }
591
592 if (safe_user != nullptr) {
593 safe_user->m_disconnected_count += m_disconnected_count;
594 m_disconnected_count = 0;
595 return;
596 }
597
598 if (safe_host != nullptr) {
599 safe_host->m_disconnected_count += m_disconnected_count;
600 m_disconnected_count = 0;
601 return;
602 }
603
604 m_disconnected_count = 0;
605 return;
606 }
607
release()608 void PFS_account::release() { dec_refcount(); }
609
rebase_memory_stats()610 void PFS_account::rebase_memory_stats() {
611 PFS_memory_shared_stat *stat = m_instr_class_memory_stats;
612 PFS_memory_shared_stat *stat_last = stat + memory_class_max;
613 for (; stat < stat_last; stat++) {
614 stat->reset();
615 }
616 }
617
carry_memory_stat_delta(PFS_memory_stat_delta * delta,uint index)618 void PFS_account::carry_memory_stat_delta(PFS_memory_stat_delta *delta,
619 uint index) {
620 PFS_memory_shared_stat *event_name_array;
621 PFS_memory_shared_stat *stat;
622 PFS_memory_stat_delta delta_buffer;
623 PFS_memory_stat_delta *remaining_delta;
624
625 event_name_array = write_instr_class_memory_stats();
626 stat = &event_name_array[index];
627 remaining_delta = stat->apply_delta(delta, &delta_buffer);
628
629 if (remaining_delta == nullptr) {
630 return;
631 }
632
633 if (m_user != nullptr) {
634 m_user->carry_memory_stat_delta(remaining_delta, index);
635 /* do not return, need to process m_host below */
636 }
637
638 if (m_host != nullptr) {
639 m_host->carry_memory_stat_delta(remaining_delta, index);
640 return;
641 }
642
643 carry_global_memory_stat_delta(remaining_delta, index);
644 }
645
sanitize_account(PFS_account * unsafe)646 PFS_account *sanitize_account(PFS_account *unsafe) {
647 return global_account_container.sanitize(unsafe);
648 }
649
purge_account(PFS_thread * thread,PFS_account * account)650 static void purge_account(PFS_thread *thread, PFS_account *account) {
651 LF_PINS *pins = get_account_hash_pins(thread);
652 if (unlikely(pins == nullptr)) {
653 return;
654 }
655
656 PFS_account **entry;
657 entry = reinterpret_cast<PFS_account **>(
658 lf_hash_search(&account_hash, pins, account->m_key.m_hash_key,
659 account->m_key.m_key_length));
660 if (entry && (entry != MY_LF_ERRPTR)) {
661 DBUG_ASSERT(*entry == account);
662 if (account->get_refcount() == 0) {
663 lf_hash_delete(&account_hash, pins, account->m_key.m_hash_key,
664 account->m_key.m_key_length);
665 account->aggregate(false, account->m_user, account->m_host);
666 if (account->m_user != nullptr) {
667 account->m_user->release();
668 account->m_user = nullptr;
669 }
670 if (account->m_host != nullptr) {
671 account->m_host->release();
672 account->m_host = nullptr;
673 }
674 global_account_container.deallocate(account);
675 }
676 }
677
678 lf_hash_search_unpin(pins);
679 }
680
681 class Proc_purge_account : public PFS_buffer_processor<PFS_account> {
682 public:
Proc_purge_account(PFS_thread * thread)683 Proc_purge_account(PFS_thread *thread) : m_thread(thread) {}
684
operator ()(PFS_account * pfs)685 virtual void operator()(PFS_account *pfs) {
686 PFS_user *user = sanitize_user(pfs->m_user);
687 PFS_host *host = sanitize_host(pfs->m_host);
688 pfs->aggregate(true, user, host);
689
690 if (pfs->get_refcount() == 0) {
691 purge_account(m_thread, pfs);
692 }
693 }
694
695 private:
696 PFS_thread *m_thread;
697 };
698
699 /** Purge non connected accounts, reset stats of connected account. */
purge_all_account(void)700 void purge_all_account(void) {
701 PFS_thread *thread = PFS_thread::get_current_thread();
702 if (unlikely(thread == nullptr)) {
703 return;
704 }
705
706 Proc_purge_account proc(thread);
707 global_account_container.apply(proc);
708 }
709
710 class Proc_update_accounts_derived_flags
711 : public PFS_buffer_processor<PFS_account> {
712 public:
Proc_update_accounts_derived_flags(PFS_thread * thread)713 Proc_update_accounts_derived_flags(PFS_thread *thread) : m_thread(thread) {}
714
operator ()(PFS_account * pfs)715 virtual void operator()(PFS_account *pfs) {
716 if (pfs->m_username_length > 0 && pfs->m_hostname_length > 0) {
717 lookup_setup_actor(m_thread, pfs->m_username, pfs->m_username_length,
718 pfs->m_hostname, pfs->m_hostname_length,
719 &pfs->m_enabled, &pfs->m_history);
720 } else {
721 pfs->m_enabled = true;
722 pfs->m_history = true;
723 }
724 }
725
726 private:
727 PFS_thread *m_thread;
728 };
729
update_accounts_derived_flags(PFS_thread * thread)730 void update_accounts_derived_flags(PFS_thread *thread) {
731 Proc_update_accounts_derived_flags proc(thread);
732 global_account_container.apply(proc);
733 }
734
735 /** @} */
736