1 /* Copyright (c) 2010, 2012, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 /**
24   @file storage/perfschema/table_os_global_by_type.cc
25   Table OBJECTS_SUMMARY_GLOBAL_BY_TYPE (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_pthread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_os_global_by_type.h"
34 #include "pfs_global.h"
35 
36 THR_LOCK table_os_global_by_type::m_table_lock;
37 
38 static const TABLE_FIELD_TYPE field_types[]=
39 {
40   {
41     { C_STRING_WITH_LEN("OBJECT_TYPE") },
42     { C_STRING_WITH_LEN("varchar(64)") },
43     { NULL, 0}
44   },
45   {
46     { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
47     { C_STRING_WITH_LEN("varchar(64)") },
48     { NULL, 0}
49   },
50   {
51     { C_STRING_WITH_LEN("OBJECT_NAME") },
52     { C_STRING_WITH_LEN("varchar(64)") },
53     { NULL, 0}
54   },
55   {
56     { C_STRING_WITH_LEN("COUNT_STAR") },
57     { C_STRING_WITH_LEN("bigint(20)") },
58     { NULL, 0}
59   },
60   {
61     { C_STRING_WITH_LEN("SUM_TIMER_WAIT") },
62     { C_STRING_WITH_LEN("bigint(20)") },
63     { NULL, 0}
64   },
65   {
66     { C_STRING_WITH_LEN("MIN_TIMER_WAIT") },
67     { C_STRING_WITH_LEN("bigint(20)") },
68     { NULL, 0}
69   },
70   {
71     { C_STRING_WITH_LEN("AVG_TIMER_WAIT") },
72     { C_STRING_WITH_LEN("bigint(20)") },
73     { NULL, 0}
74   },
75   {
76     { C_STRING_WITH_LEN("MAX_TIMER_WAIT") },
77     { C_STRING_WITH_LEN("bigint(20)") },
78     { NULL, 0}
79   }
80 };
81 
82 TABLE_FIELD_DEF
83 table_os_global_by_type::m_field_def=
84 { 8, field_types };
85 
86 PFS_engine_table_share
87 table_os_global_by_type::m_share=
88 {
89   { C_STRING_WITH_LEN("objects_summary_global_by_type") },
90   &pfs_truncatable_acl,
91   table_os_global_by_type::create,
92   NULL, /* write_row */
93   table_os_global_by_type::delete_all_rows,
94   NULL, /* get_row_count */
95   1000, /* records */
96   sizeof(pos_os_global_by_type),
97   &m_table_lock,
98   &m_field_def,
99   false /* checked */
100 };
101 
102 PFS_engine_table*
create(void)103 table_os_global_by_type::create(void)
104 {
105   return new table_os_global_by_type();
106 }
107 
108 int
delete_all_rows(void)109 table_os_global_by_type::delete_all_rows(void)
110 {
111   reset_table_waits_by_table_handle();
112   reset_table_waits_by_table();
113   return 0;
114 }
115 
table_os_global_by_type()116 table_os_global_by_type::table_os_global_by_type()
117   : PFS_engine_table(&m_share, &m_pos),
118     m_row_exists(false), m_pos(), m_next_pos()
119 {}
120 
reset_position(void)121 void table_os_global_by_type::reset_position(void)
122 {
123   m_pos.reset();
124   m_next_pos.reset();
125 }
126 
rnd_next(void)127 int table_os_global_by_type::rnd_next(void)
128 {
129   PFS_table_share *table_share;
130 
131   for (m_pos.set_at(&m_next_pos);
132        m_pos.has_more_view();
133        m_pos.next_view())
134   {
135     switch (m_pos.m_index_1) {
136     case pos_os_global_by_type::VIEW_TABLE:
137       for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++)
138       {
139         table_share= &table_share_array[m_pos.m_index_2];
140         if (table_share->m_lock.is_populated())
141         {
142           make_row(table_share);
143           m_next_pos.set_after(&m_pos);
144           return 0;
145         }
146       }
147       break;
148     default:
149       break;
150     }
151   }
152 
153   return HA_ERR_END_OF_FILE;
154 }
155 
156 int
rnd_pos(const void * pos)157 table_os_global_by_type::rnd_pos(const void *pos)
158 {
159   PFS_table_share *table_share;
160 
161   set_position(pos);
162 
163   switch (m_pos.m_index_1) {
164   case pos_os_global_by_type::VIEW_TABLE:
165     DBUG_ASSERT(m_pos.m_index_2 < table_share_max);
166     table_share= &table_share_array[m_pos.m_index_2];
167     if (table_share->m_lock.is_populated())
168     {
169       make_row(table_share);
170       return 0;
171     }
172     break;
173   default:
174     break;
175   }
176 
177   return HA_ERR_RECORD_DELETED;
178 }
179 
make_row(PFS_table_share * share)180 void table_os_global_by_type::make_row(PFS_table_share *share)
181 {
182   pfs_lock lock;
183   PFS_single_stat cumulated_stat;
184   uint safe_key_count;
185 
186   m_row_exists= false;
187 
188   share->m_lock.begin_optimistic_lock(&lock);
189 
190   m_row.m_object_type= share->get_object_type();
191   memcpy(m_row.m_schema_name, share->m_schema_name, share->m_schema_name_length);
192   m_row.m_schema_name_length= share->m_schema_name_length;
193   memcpy(m_row.m_object_name, share->m_table_name, share->m_table_name_length);
194   m_row.m_object_name_length= share->m_table_name_length;
195 
196   /* This is a dirty read, some thread can write data while we are reading it */
197   safe_key_count= sanitize_index_count(share->m_key_count);
198 
199   share->m_table_stat.sum(& cumulated_stat, safe_key_count);
200 
201   if (! share->m_lock.end_optimistic_lock(&lock))
202     return;
203 
204   m_row_exists= true;
205 
206   if (share->get_refcount() > 0)
207   {
208     /* For all the table handles still opened ... */
209     PFS_table *table= table_array;
210     PFS_table *table_last= table_array + table_max;
211     for ( ; table < table_last ; table++)
212     {
213       if ((table->m_share == share) && (table->m_lock.is_populated()))
214       {
215         /*
216           If the opened table handle is for this table share,
217           aggregate the table handle statistics.
218         */
219         table->m_table_stat.sum(& cumulated_stat, safe_key_count);
220       }
221     }
222   }
223 
224   time_normalizer *normalizer= time_normalizer::get(wait_timer);
225   m_row.m_stat.set(normalizer, &cumulated_stat);
226 }
227 
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)228 int table_os_global_by_type::read_row_values(TABLE *table,
229                                              unsigned char *buf,
230                                              Field **fields,
231                                              bool read_all)
232 {
233   Field *f;
234 
235   if (unlikely(! m_row_exists))
236     return HA_ERR_RECORD_DELETED;
237 
238   /* Set the null bits */
239   DBUG_ASSERT(table->s->null_bytes == 1);
240   buf[0]= 0;
241 
242   for (; (f= *fields) ; fields++)
243   {
244     if (read_all || bitmap_is_set(table->read_set, f->field_index))
245     {
246       switch(f->field_index)
247       {
248       case 0: /* OBJECT_TYPE */
249         set_field_object_type(f, m_row.m_object_type);
250         break;
251       case 1: /* SCHEMA_NAME */
252         set_field_varchar_utf8(f, m_row.m_schema_name,
253                                m_row.m_schema_name_length);
254         break;
255       case 2: /* OBJECT_NAME */
256         set_field_varchar_utf8(f, m_row.m_object_name,
257                                m_row.m_object_name_length);
258         break;
259       case 3: /* COUNT */
260         set_field_ulonglong(f, m_row.m_stat.m_count);
261         break;
262       case 4: /* SUM */
263         set_field_ulonglong(f, m_row.m_stat.m_sum);
264         break;
265       case 5: /* MIN */
266         set_field_ulonglong(f, m_row.m_stat.m_min);
267         break;
268       case 6: /* AVG */
269         set_field_ulonglong(f, m_row.m_stat.m_avg);
270         break;
271       case 7: /* MAX */
272         set_field_ulonglong(f, m_row.m_stat.m_max);
273         break;
274       default:
275         DBUG_ASSERT(false);
276       }
277     }
278   }
279 
280   return 0;
281 }
282 
283