1 /* Copyright (c) 2011, 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/table_mems_by_account_by_event_name.cc
25   Table MEMORY_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_mems_by_account_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_memory.h"
37 #include "pfs_buffer_container.h"
38 #include "field.h"
39 
40 THR_LOCK table_mems_by_account_by_event_name::m_table_lock;
41 
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44  {
45     { C_STRING_WITH_LEN("USER") },
46     { C_STRING_WITH_LEN("char(" USERNAME_CHAR_LENGTH_STR ")") },
47     { NULL, 0}
48   },
49   {
50     { C_STRING_WITH_LEN("HOST") },
51     { C_STRING_WITH_LEN("char(60)") },
52     { NULL, 0}
53   },
54   {
55     { C_STRING_WITH_LEN("EVENT_NAME") },
56     { C_STRING_WITH_LEN("varchar(128)") },
57     { NULL, 0}
58   },
59   {
60     { C_STRING_WITH_LEN("COUNT_ALLOC") },
61     { C_STRING_WITH_LEN("bigint(20)") },
62     { NULL, 0}
63   },
64   {
65     { C_STRING_WITH_LEN("COUNT_FREE") },
66     { C_STRING_WITH_LEN("bigint(20)") },
67     { NULL, 0}
68   },
69   {
70     { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_ALLOC") },
71     { C_STRING_WITH_LEN("bigint(20)") },
72     { NULL, 0}
73   },
74   {
75     { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_FREE") },
76     { C_STRING_WITH_LEN("bigint(20)") },
77     { NULL, 0}
78   },
79   {
80     { C_STRING_WITH_LEN("LOW_COUNT_USED") },
81     { C_STRING_WITH_LEN("bigint(20)") },
82     { NULL, 0}
83   },
84   {
85     { C_STRING_WITH_LEN("CURRENT_COUNT_USED") },
86     { C_STRING_WITH_LEN("bigint(20)") },
87     { NULL, 0}
88   },
89   {
90     { C_STRING_WITH_LEN("HIGH_COUNT_USED") },
91     { C_STRING_WITH_LEN("bigint(20)") },
92     { NULL, 0}
93   },
94   {
95     { C_STRING_WITH_LEN("LOW_NUMBER_OF_BYTES_USED") },
96     { C_STRING_WITH_LEN("bigint(20)") },
97     { NULL, 0}
98   },
99   {
100     { C_STRING_WITH_LEN("CURRENT_NUMBER_OF_BYTES_USED") },
101     { C_STRING_WITH_LEN("bigint(20)") },
102     { NULL, 0}
103   },
104   {
105     { C_STRING_WITH_LEN("HIGH_NUMBER_OF_BYTES_USED") },
106     { C_STRING_WITH_LEN("bigint(20)") },
107     { NULL, 0}
108   }
109 };
110 
111 TABLE_FIELD_DEF
112 table_mems_by_account_by_event_name::m_field_def=
113 { 13, field_types };
114 
115 PFS_engine_table_share
116 table_mems_by_account_by_event_name::m_share=
117 {
118   { C_STRING_WITH_LEN("memory_summary_by_account_by_event_name") },
119   &pfs_readonly_acl,
120   table_mems_by_account_by_event_name::create,
121   NULL, /* write_row */
122   table_mems_by_account_by_event_name::delete_all_rows,
123   table_mems_by_account_by_event_name::get_row_count,
124   sizeof(pos_mems_by_account_by_event_name),
125   &m_table_lock,
126   &m_field_def,
127   false, /* checked */
128   false  /* perpetual */
129 };
130 
create(void)131 PFS_engine_table* table_mems_by_account_by_event_name::create(void)
132 {
133   return new table_mems_by_account_by_event_name();
134 }
135 
136 int
delete_all_rows(void)137 table_mems_by_account_by_event_name::delete_all_rows(void)
138 {
139   reset_memory_by_thread();
140   reset_memory_by_account();
141   return 0;
142 }
143 
144 ha_rows
get_row_count(void)145 table_mems_by_account_by_event_name::get_row_count(void)
146 {
147   return global_account_container.get_row_count() * memory_class_max;
148 }
149 
table_mems_by_account_by_event_name()150 table_mems_by_account_by_event_name::table_mems_by_account_by_event_name()
151   : PFS_engine_table(&m_share, &m_pos),
152   m_row_exists(false), m_pos(), m_next_pos()
153 {}
154 
reset_position(void)155 void table_mems_by_account_by_event_name::reset_position(void)
156 {
157   m_pos.reset();
158   m_next_pos.reset();
159 }
160 
rnd_next(void)161 int table_mems_by_account_by_event_name::rnd_next(void)
162 {
163   PFS_account *account;
164   PFS_memory_class *memory_class;
165   bool has_more_account= true;
166 
167   for (m_pos.set_at(&m_next_pos);
168        has_more_account;
169        m_pos.next_account())
170   {
171     account= global_account_container.get(m_pos.m_index_1, & has_more_account);
172     if (account != NULL)
173     {
174       do
175       {
176         memory_class= find_memory_class(m_pos.m_index_2);
177         if (memory_class != NULL)
178         {
179           if (! memory_class->is_global())
180           {
181             make_row(account, memory_class);
182             m_next_pos.set_after(&m_pos);
183             return 0;
184           }
185 
186           m_pos.next_class();
187         }
188       }
189       while (memory_class != NULL);
190     }
191   }
192 
193   return HA_ERR_END_OF_FILE;
194 }
195 
rnd_pos(const void * pos)196 int table_mems_by_account_by_event_name::rnd_pos(const void *pos)
197 {
198   PFS_account *account;
199   PFS_memory_class *memory_class;
200 
201   set_position(pos);
202 
203   account= global_account_container.get(m_pos.m_index_1);
204   if (account != NULL)
205   {
206     memory_class= find_memory_class(m_pos.m_index_2);
207     if (memory_class != NULL)
208     {
209       if (! memory_class->is_global())
210       {
211         make_row(account, memory_class);
212         return 0;
213       }
214     }
215   }
216 
217   return HA_ERR_RECORD_DELETED;
218 }
219 
220 void table_mems_by_account_by_event_name
make_row(PFS_account * account,PFS_memory_class * klass)221 ::make_row(PFS_account *account, PFS_memory_class *klass)
222 {
223   pfs_optimistic_state lock;
224   m_row_exists= false;
225 
226   account->m_lock.begin_optimistic_lock(&lock);
227 
228   if (m_row.m_account.make_row(account))
229     return;
230 
231   m_row.m_event_name.make_row(klass);
232 
233   PFS_connection_memory_visitor visitor(klass);
234   PFS_connection_iterator::visit_account(account,
235                                          true,  /* threads */
236                                          false, /* THDs */
237                                          & visitor);
238 
239   if (! account->m_lock.end_optimistic_lock(&lock))
240     return;
241 
242   m_row_exists= true;
243   m_row.m_stat.set(& visitor.m_stat);
244 }
245 
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)246 int table_mems_by_account_by_event_name::read_row_values(TABLE *table,
247                                                     unsigned char *buf,
248                                                     Field **fields,
249                                                     bool read_all)
250 {
251   Field *f;
252 
253   if (unlikely(! m_row_exists))
254     return HA_ERR_RECORD_DELETED;
255 
256   /* Set the null bits */
257   assert(table->s->null_bytes == 1);
258   buf[0]= 0;
259 
260   for (; (f= *fields) ; fields++)
261   {
262     if (read_all || bitmap_is_set(table->read_set, f->field_index))
263     {
264       switch(f->field_index)
265       {
266       case 0: /* USER */
267       case 1: /* HOST */
268         m_row.m_account.set_field(f->field_index, f);
269         break;
270       case 2: /* EVENT_NAME */
271         m_row.m_event_name.set_field(f);
272         break;
273       default: /* 3, ... HIGH_NUMBER_OF_BYTES_USED */
274         m_row.m_stat.set_field(f->field_index - 3, f);
275         break;
276       }
277     }
278   }
279 
280   return 0;
281 }
282 
283