1 /* Copyright (c) 2011, 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 @file storage/perfschema/table_users.cc
25 TABLE USERS.
26 */
27
28 #include "storage/perfschema/table_users.h"
29
30 #include <stddef.h>
31
32 #include "my_dbug.h"
33 #include "my_thread.h"
34 #include "sql/field.h"
35 #include "sql/plugin_table.h"
36 #include "sql/table.h"
37 #include "storage/perfschema/pfs_account.h"
38 #include "storage/perfschema/pfs_events_transactions.h"
39 #include "storage/perfschema/pfs_instr.h"
40 #include "storage/perfschema/pfs_instr_class.h"
41 #include "storage/perfschema/pfs_memory.h"
42 #include "storage/perfschema/pfs_status.h"
43 #include "storage/perfschema/pfs_user.h"
44 #include "storage/perfschema/pfs_visitor.h"
45
46 THR_LOCK table_users::m_table_lock;
47
48 Plugin_table table_users::m_table_def(
49 /* Schema name */
50 "performance_schema",
51 /* Name */
52 "users",
53 /* Definition */
54 " USER CHAR(32) collate utf8mb4_bin default null,\n"
55 " CURRENT_CONNECTIONS bigint not null,\n"
56 " TOTAL_CONNECTIONS bigint not null,\n"
57 " UNIQUE KEY (USER) USING HASH\n",
58 /* Options */
59 " ENGINE=PERFORMANCE_SCHEMA",
60 /* Tablespace */
61 nullptr);
62
63 PFS_engine_table_share table_users::m_share = {
64 &pfs_truncatable_acl,
65 table_users::create,
66 nullptr, /* write_row */
67 table_users::delete_all_rows,
68 cursor_by_user::get_row_count,
69 sizeof(PFS_simple_index), /* ref length */
70 &m_table_lock,
71 &m_table_def,
72 false, /* perpetual */
73 PFS_engine_table_proxy(),
74 {0},
75 false /* m_in_purgatory */
76 };
77
match(PFS_user * pfs)78 bool PFS_index_users_by_user::match(PFS_user *pfs) {
79 if (m_fields >= 1) {
80 if (!m_key.match(pfs)) {
81 return false;
82 }
83 }
84
85 return true;
86 }
87
create(PFS_engine_table_share *)88 PFS_engine_table *table_users::create(PFS_engine_table_share *) {
89 return new table_users();
90 }
91
delete_all_rows(void)92 int table_users::delete_all_rows(void) {
93 reset_events_waits_by_thread();
94 reset_events_waits_by_account();
95 reset_events_waits_by_user();
96 reset_events_stages_by_thread();
97 reset_events_stages_by_account();
98 reset_events_stages_by_user();
99 reset_events_statements_by_thread();
100 reset_events_statements_by_account();
101 reset_events_statements_by_user();
102 reset_events_transactions_by_thread();
103 reset_events_transactions_by_account();
104 reset_events_transactions_by_user();
105 reset_memory_by_thread();
106 reset_memory_by_account();
107 reset_memory_by_user();
108 reset_status_by_thread();
109 reset_status_by_account();
110 reset_status_by_user();
111 purge_all_account();
112 purge_all_user();
113 return 0;
114 }
115
table_users()116 table_users::table_users() : cursor_by_user(&m_share) {}
117
index_init(uint,bool)118 int table_users::index_init(uint, bool) {
119 PFS_index_users *result = nullptr;
120 result = PFS_NEW(PFS_index_users_by_user);
121 m_opened_index = result;
122 m_index = result;
123 return 0;
124 }
125
make_row(PFS_user * pfs)126 int table_users::make_row(PFS_user *pfs) {
127 pfs_optimistic_state lock;
128
129 pfs->m_lock.begin_optimistic_lock(&lock);
130
131 if (m_row.m_user.make_row(pfs)) {
132 return HA_ERR_RECORD_DELETED;
133 }
134
135 PFS_connection_stat_visitor visitor;
136 PFS_connection_iterator::visit_user(pfs, true, /* accounts */
137 true, /* threads */
138 false, /* THDs */
139 &visitor);
140
141 if (!pfs->m_lock.end_optimistic_lock(&lock)) {
142 return HA_ERR_RECORD_DELETED;
143 }
144
145 m_row.m_connection_stat.set(&visitor.m_stat);
146 return 0;
147 }
148
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)149 int table_users::read_row_values(TABLE *table, unsigned char *buf,
150 Field **fields, bool read_all) {
151 Field *f;
152
153 /* Set the null bits */
154 DBUG_ASSERT(table->s->null_bytes == 1);
155 buf[0] = 0;
156
157 for (; (f = *fields); fields++) {
158 if (read_all || bitmap_is_set(table->read_set, f->field_index())) {
159 switch (f->field_index()) {
160 case 0: /* USER */
161 m_row.m_user.set_field(f);
162 break;
163 case 1: /* CURRENT_CONNECTIONS */
164 case 2: /* TOTAL_CONNECTIONS */
165 m_row.m_connection_stat.set_field(f->field_index() - 1, f);
166 break;
167 default:
168 DBUG_ASSERT(false);
169 }
170 }
171 }
172 return 0;
173 }
174