MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
table_host_cache.cc
Go to the documentation of this file.
1 /* Copyright (c) 2011, 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 as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
21 #include "my_global.h"
22 #include "my_pthread.h"
23 #include "table_host_cache.h"
24 #include "hostname.h"
25 
26 THR_LOCK table_host_cache::m_table_lock;
27 
28 static const TABLE_FIELD_TYPE field_types[]=
29 {
30  {
31  { C_STRING_WITH_LEN("IP") },
32  { C_STRING_WITH_LEN("varchar(64)") },
33  { NULL, 0}
34  },
35  {
36  { C_STRING_WITH_LEN("HOST") },
37  { C_STRING_WITH_LEN("varchar(255)") },
38  { NULL, 0}
39  },
40  {
41  { C_STRING_WITH_LEN("HOST_VALIDATED") },
42  { C_STRING_WITH_LEN("enum(\'YES\',\'NO\')") },
43  { NULL, 0}
44  },
45  {
46  { C_STRING_WITH_LEN("SUM_CONNECT_ERRORS") },
47  { C_STRING_WITH_LEN("bigint(20)") },
48  { NULL, 0}
49  },
50  {
51  { C_STRING_WITH_LEN("COUNT_HOST_BLOCKED_ERRORS") },
52  { C_STRING_WITH_LEN("bigint(20)") },
53  { NULL, 0}
54  },
55  {
56  { C_STRING_WITH_LEN("COUNT_NAMEINFO_TRANSIENT_ERRORS") },
57  { C_STRING_WITH_LEN("bigint(20)") },
58  { NULL, 0}
59  },
60  {
61  { C_STRING_WITH_LEN("COUNT_NAMEINFO_PERMANENT_ERRORS") },
62  { C_STRING_WITH_LEN("bigint(20)") },
63  { NULL, 0}
64  },
65  {
66  { C_STRING_WITH_LEN("COUNT_FORMAT_ERRORS") },
67  { C_STRING_WITH_LEN("bigint(20)") },
68  { NULL, 0}
69  },
70  {
71  { C_STRING_WITH_LEN("COUNT_ADDRINFO_TRANSIENT_ERRORS") },
72  { C_STRING_WITH_LEN("bigint(20)") },
73  { NULL, 0}
74  },
75  {
76  { C_STRING_WITH_LEN("COUNT_ADDRINFO_PERMANENT_ERRORS") },
77  { C_STRING_WITH_LEN("bigint(20)") },
78  { NULL, 0}
79  },
80  {
81  { C_STRING_WITH_LEN("COUNT_FCRDNS_ERRORS") },
82  { C_STRING_WITH_LEN("bigint(20)") },
83  { NULL, 0}
84  },
85  {
86  { C_STRING_WITH_LEN("COUNT_HOST_ACL_ERRORS") },
87  { C_STRING_WITH_LEN("bigint(20)") },
88  { NULL, 0}
89  },
90  {
91  { C_STRING_WITH_LEN("COUNT_NO_AUTH_PLUGIN_ERRORS") },
92  { C_STRING_WITH_LEN("bigint(20)") },
93  { NULL, 0}
94  },
95  {
96  { C_STRING_WITH_LEN("COUNT_AUTH_PLUGIN_ERRORS") },
97  { C_STRING_WITH_LEN("bigint(20)") },
98  { NULL, 0}
99  },
100  {
101  { C_STRING_WITH_LEN("COUNT_HANDSHAKE_ERRORS") },
102  { C_STRING_WITH_LEN("bigint(20)") },
103  { NULL, 0}
104  },
105  {
106  { C_STRING_WITH_LEN("COUNT_PROXY_USER_ERRORS") },
107  { C_STRING_WITH_LEN("bigint(20)") },
108  { NULL, 0}
109  },
110  {
111  { C_STRING_WITH_LEN("COUNT_PROXY_USER_ACL_ERRORS") },
112  { C_STRING_WITH_LEN("bigint(20)") },
113  { NULL, 0}
114  },
115  {
116  { C_STRING_WITH_LEN("COUNT_AUTHENTICATION_ERRORS") },
117  { C_STRING_WITH_LEN("bigint(20)") },
118  { NULL, 0}
119  },
120  {
121  { C_STRING_WITH_LEN("COUNT_SSL_ERRORS") },
122  { C_STRING_WITH_LEN("bigint(20)") },
123  { NULL, 0}
124  },
125  {
126  { C_STRING_WITH_LEN("COUNT_MAX_USER_CONNECTIONS_ERRORS") },
127  { C_STRING_WITH_LEN("bigint(20)") },
128  { NULL, 0}
129  },
130  {
131  { C_STRING_WITH_LEN("COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS") },
132  { C_STRING_WITH_LEN("bigint(20)") },
133  { NULL, 0}
134  },
135  {
136  { C_STRING_WITH_LEN("COUNT_DEFAULT_DATABASE_ERRORS") },
137  { C_STRING_WITH_LEN("bigint(20)") },
138  { NULL, 0}
139  },
140  {
141  { C_STRING_WITH_LEN("COUNT_INIT_CONNECT_ERRORS") },
142  { C_STRING_WITH_LEN("bigint(20)") },
143  { NULL, 0}
144  },
145  {
146  { C_STRING_WITH_LEN("COUNT_LOCAL_ERRORS") },
147  { C_STRING_WITH_LEN("bigint(20)") },
148  { NULL, 0}
149  },
150  {
151  { C_STRING_WITH_LEN("COUNT_UNKNOWN_ERRORS") },
152  { C_STRING_WITH_LEN("bigint(20)") },
153  { NULL, 0}
154  },
155  {
156  { C_STRING_WITH_LEN("FIRST_SEEN") },
157  { C_STRING_WITH_LEN("timestamp") },
158  { NULL, 0}
159  },
160  {
161  { C_STRING_WITH_LEN("LAST_SEEN") },
162  { C_STRING_WITH_LEN("timestamp") },
163  { NULL, 0}
164  },
165  {
166  { C_STRING_WITH_LEN("FIRST_ERROR_SEEN") },
167  { C_STRING_WITH_LEN("timestamp") },
168  { NULL, 0}
169  },
170  {
171  { C_STRING_WITH_LEN("LAST_ERROR_SEEN") },
172  { C_STRING_WITH_LEN("timestamp") },
173  { NULL, 0}
174  }
175 };
176 
178 table_host_cache::m_field_def=
179 { 29, field_types };
180 
183 {
184  { C_STRING_WITH_LEN("host_cache") },
186  &table_host_cache::create,
187  NULL, /* write_row */
188  table_host_cache::delete_all_rows,
189  NULL, /* get_row_count */
190  1000, /* records */
191  sizeof(PFS_simple_index), /* ref length */
192  &m_table_lock,
193  &m_field_def,
194  false /* checked */
195 };
196 
197 PFS_engine_table* table_host_cache::create(void)
198 {
200  if (t != NULL)
201  {
202  THD *thd= current_thd;
203  DBUG_ASSERT(thd != NULL);
204  t->materialize(thd);
205  }
206  return t;
207 }
208 
209 int
210 table_host_cache::delete_all_rows(void)
211 {
212  /*
213  TRUNCATE TABLE performance_schema.host_cache
214  is an alternate syntax for
215  FLUSH HOSTS
216  */
217  hostname_cache_refresh();
218  return 0;
219 }
220 
221 table_host_cache::table_host_cache()
222  : PFS_engine_table(&m_share, &m_pos),
223  m_all_rows(NULL), m_row_count(0),
224  m_row(NULL), m_pos(0), m_next_pos(0)
225 {}
226 
227 void table_host_cache::materialize(THD *thd)
228 {
229  Host_entry *current;
230  Host_entry *first;
231  uint size;
232  uint index;
233  row_host_cache *rows;
234  row_host_cache *row;
235 
236  DBUG_ASSERT(m_all_rows == NULL);
237  DBUG_ASSERT(m_row_count == 0);
238 
239  hostname_cache_lock();
240 
241  size= hostname_cache_size();
242  if (size == 0)
243  {
244  /* Normal case, the cache is empty. */
245  goto end;
246  }
247 
248  rows= (row_host_cache*) thd->alloc(size * sizeof(row_host_cache));
249  if (rows == NULL)
250  {
251  /* Out of memory, this thread will error out. */
252  goto end;
253  }
254 
255  index= 0;
256  row= rows;
257 
258  first= hostname_cache_first();
259  current= first;
260 
261  while ((current != NULL) && (index < size))
262  {
263  make_row(current, row);
264  index++;
265  row++;
266  current= current->next();
267  }
268 
269  m_all_rows= rows;
270  m_row_count= index;
271 
272 end:
273  hostname_cache_unlock();
274 }
275 
276 void table_host_cache::make_row(Host_entry *entry, row_host_cache *row)
277 {
278  row->m_ip_length= strlen(entry->ip_key);
279  strcpy(row->m_ip, entry->ip_key);
280  row->m_hostname_length= entry->m_hostname_length;
281  if (row->m_hostname_length > 0)
282  strncpy(row->m_hostname, entry->m_hostname, row->m_hostname_length);
283  row->m_host_validated= entry->m_host_validated;
299  row->m_count_ssl_errors= entry->m_errors.m_ssl;
305 
306  /*
307  Reserved for future use, to help with backward compatibility.
308  When new errors are added in entry->m_errors.m_xxx,
309  report them in this column (GA releases),
310  until the table HOST_CACHE structure can be extended (next development version).
311  */
312  row->m_count_unknown_errors= 0;
313 
314  row->m_first_seen= entry->m_first_seen;
315  row->m_last_seen= entry->m_last_seen;
316  row->m_first_error_seen= entry->m_first_error_seen;
317  row->m_last_error_seen= entry->m_last_error_seen;
318 }
319 
321 {
322  m_pos.m_index= 0;
323  m_next_pos.m_index= 0;
324 }
325 
327 {
328  int result;
329 
330  m_pos.set_at(&m_next_pos);
331 
332  if (m_pos.m_index < m_row_count)
333  {
334  m_row= &m_all_rows[m_pos.m_index];
335  m_next_pos.set_after(&m_pos);
336  result= 0;
337  }
338  else
339  {
340  m_row= NULL;
341  result= HA_ERR_END_OF_FILE;
342  }
343 
344  return result;
345 }
346 
347 int table_host_cache::rnd_pos(const void *pos)
348 {
349  set_position(pos);
350  DBUG_ASSERT(m_pos.m_index < m_row_count);
351  m_row= &m_all_rows[m_pos.m_index];
352  return 0;
353 }
354 
356  unsigned char *buf,
357  Field **fields,
358  bool read_all)
359 {
360  Field *f;
361 
362  DBUG_ASSERT(m_row);
363 
364  /* Set the null bits */
365  DBUG_ASSERT(table->s->null_bytes == 1);
366  buf[0]= 0;
367 
368  for (; (f= *fields) ; fields++)
369  {
370  if (read_all || bitmap_is_set(table->read_set, f->field_index))
371  {
372  switch(f->field_index)
373  {
374  case 0: /* IP */
375  set_field_varchar_utf8(f, m_row->m_ip, m_row->m_ip_length);
376  break;
377  case 1: /* HOST */
378  if (m_row->m_hostname_length > 0)
379  set_field_varchar_utf8(f, m_row->m_hostname, m_row->m_hostname_length);
380  else
381  f->set_null();
382  break;
383  case 2: /* HOST_VALIDATED */
384  set_field_enum(f, m_row->m_host_validated ? ENUM_YES : ENUM_NO);
385  break;
386  case 3: /* SUM_CONNECT_ERRORS */
388  break;
389  case 4: /* COUNT_HOST_BLOCKED_ERRORS. */
391  break;
392  case 5: /* COUNT_NAMEINFO_TRANSIENT_ERRORS */
394  break;
395  case 6: /* COUNT_NAMEINFO_PERSISTENT_ERRORS */
397  break;
398  case 7: /* COUNT_FORMAT_ERRORS */
400  break;
401  case 8: /* COUNT_ADDRINFO_TRANSIENT_ERRORS */
403  break;
404  case 9: /* COUNT_ADDRINFO_PERSISTENT_ERRORS */
406  break;
407  case 10: /* COUNT_FCRDNS_ERRORS */
409  break;
410  case 11: /* COUNT_HOST_ACL_ERRORS */
412  break;
413  case 12: /* COUNT_NO_AUTH_PLUGIN_ERRORS */
415  break;
416  case 13: /* COUNT_AUTH_PLUGIN_ERRORS */
418  break;
419  case 14: /* COUNT_HANDSHAKE_ERRORS */
421  break;
422  case 15: /* COUNT_PROXY_USER_ERRORS */
424  break;
425  case 16: /* COUNT_PROXY_USER_ACL_ERRORS */
427  break;
428  case 17: /* COUNT_AUTHENTICATION_ERRORS */
430  break;
431  case 18: /* COUNT_SSL_ERRORS */
433  break;
434  case 19: /* COUNT_MAX_USER_CONNECTION_ERRORS */
436  break;
437  case 20: /* COUNT_MAX_USER_CONNECTION_PER_HOUR_ERRORS */
439  break;
440  case 21: /* COUNT_DEFAULT_DATABASE_ERRORS */
442  break;
443  case 22: /* COUNT_INIT_CONNECT_ERRORS */
445  break;
446  case 23: /* COUNT_LOCAL_ERRORS */
448  break;
449  case 24: /* COUNT_UNKNOWN_ERRORS */
451  break;
452  case 25: /* FIRST_SEEN */
454  break;
455  case 26: /* LAST_SEEN */
456  set_field_timestamp(f, m_row->m_last_seen);
457  break;
458  case 27: /* FIRST_ERROR_SEEN */
459  if (m_row->m_first_error_seen != 0)
461  else
462  f->set_null();
463  break;
464  case 28: /* LAST_ERROR_SEEN */
465  if (m_row->m_last_error_seen != 0)
467  else
468  f->set_null();
469  break;
470  default:
471  DBUG_ASSERT(false);
472  }
473  }
474  }
475 
476  return 0;
477 }
478