pfs_events_waits.cc 9.07 KB
Newer Older
Oleksandr Byelkin's avatar
Oleksandr Byelkin committed
1
/* Copyright (c) 2008, 2022, Oracle and/or its affiliates.
2 3

  This program is free software; you can redistribute it and/or modify
Sergei Golubchik's avatar
Sergei Golubchik committed
4 5 6 7 8 9 10 11 12
  it under the terms of the GNU General Public License, version 2.0,
  as published by the Free Software Foundation.

  This program is also distributed with certain software (including
  but not limited to OpenSSL) that is licensed under separate terms,
  as designated in a particular file or component or in included license
  documentation.  The authors of MySQL hereby grant you an additional
  permission to link the program and your derivative works with the
  separately licensed software that they have included with MySQL.
13 14 15 16

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Sergei Golubchik's avatar
Sergei Golubchik committed
17
  GNU General Public License, version 2.0, for more details.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation,
  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */

/**
  @file storage/perfschema/pfs_events_waits.cc
  Events waits data structures (implementation).
*/

#include "my_global.h"
#include "my_sys.h"
#include "pfs_global.h"
#include "pfs_instr_class.h"
#include "pfs_instr.h"
#include "pfs_user.h"
#include "pfs_host.h"
#include "pfs_account.h"
#include "pfs_events_waits.h"
#include "pfs_atomic.h"
Sergei Golubchik's avatar
Sergei Golubchik committed
38 39
#include "pfs_buffer_container.h"
#include "pfs_builtin_memory.h"
40 41
#include "m_string.h"

Sergei Golubchik's avatar
Sergei Golubchik committed
42
PFS_ALIGNED ulong events_waits_history_long_size= 0;
43
/** Consumer flag for table EVENTS_WAITS_CURRENT. */
Sergei Golubchik's avatar
Sergei Golubchik committed
44
PFS_ALIGNED bool flag_events_waits_current= false;
45
/** Consumer flag for table EVENTS_WAITS_HISTORY. */
Sergei Golubchik's avatar
Sergei Golubchik committed
46
PFS_ALIGNED bool flag_events_waits_history= false;
47
/** Consumer flag for table EVENTS_WAITS_HISTORY_LONG. */
Sergei Golubchik's avatar
Sergei Golubchik committed
48
PFS_ALIGNED bool flag_events_waits_history_long= false;
49
/** Consumer flag for the global instrumentation. */
Sergei Golubchik's avatar
Sergei Golubchik committed
50
PFS_ALIGNED bool flag_global_instrumentation= false;
51
/** Consumer flag for the per thread instrumentation. */
Sergei Golubchik's avatar
Sergei Golubchik committed
52
PFS_ALIGNED bool flag_thread_instrumentation= false;
53 54

/** True if EVENTS_WAITS_HISTORY_LONG circular buffer is full. */
Sergei Golubchik's avatar
Sergei Golubchik committed
55
PFS_ALIGNED bool events_waits_history_long_full= false;
56
/** Index in EVENTS_WAITS_HISTORY_LONG circular buffer. */
Sergei Golubchik's avatar
Sergei Golubchik committed
57
PFS_ALIGNED PFS_cacheline_uint32 events_waits_history_long_index;
58
/** EVENTS_WAITS_HISTORY_LONG circular buffer. */
Sergei Golubchik's avatar
Sergei Golubchik committed
59
PFS_ALIGNED PFS_events_waits *events_waits_history_long_array= NULL;
60 61 62 63 64 65 66 67 68

/**
  Initialize table EVENTS_WAITS_HISTORY_LONG.
  @param events_waits_history_long_sizing       table sizing
*/
int init_events_waits_history_long(uint events_waits_history_long_sizing)
{
  events_waits_history_long_size= events_waits_history_long_sizing;
  events_waits_history_long_full= false;
Sergei Golubchik's avatar
Sergei Golubchik committed
69
  PFS_atomic::store_u32(&events_waits_history_long_index.m_u32, 0);
70 71 72 73 74

  if (events_waits_history_long_size == 0)
    return 0;

  events_waits_history_long_array=
Sergei Golubchik's avatar
Sergei Golubchik committed
75 76 77 78
    PFS_MALLOC_ARRAY(& builtin_memory_waits_history_long,
                     events_waits_history_long_size,
                     sizeof(PFS_events_waits), PFS_events_waits,
                     MYF(MY_ZEROFILL));
79 80 81 82 83 84 85

  return (events_waits_history_long_array ? 0 : 1);
}

/** Cleanup table EVENTS_WAITS_HISTORY_LONG. */
void cleanup_events_waits_history_long(void)
{
Sergei Golubchik's avatar
Sergei Golubchik committed
86 87 88
  PFS_FREE_ARRAY(& builtin_memory_waits_history_long,
                 events_waits_history_long_size, sizeof(PFS_events_waits),
                 events_waits_history_long_array);
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  events_waits_history_long_array= NULL;
}

static inline void copy_events_waits(PFS_events_waits *dest,
                                     const PFS_events_waits *source)
{
  memcpy(dest, source, sizeof(PFS_events_waits));
}

/**
  Insert a wait record in table EVENTS_WAITS_HISTORY.
  @param thread             thread that executed the wait
  @param wait               record to insert
*/
void insert_events_waits_history(PFS_thread *thread, PFS_events_waits *wait)
{
  if (unlikely(events_waits_history_per_thread == 0))
    return;

  uint index= thread->m_waits_history_index;

  /*
    A concurrent thread executing TRUNCATE TABLE EVENTS_WAITS_CURRENT
    could alter the data that this thread is inserting,
    causing a potential race condition.
    We are not testing for this and insert a possibly empty record,
    to make this thread (the writer) faster.
    This is ok, the readers of m_waits_history will filter this out.
  */
  copy_events_waits(&thread->m_waits_history[index], wait);

  index++;
  if (index >= events_waits_history_per_thread)
  {
    index= 0;
    thread->m_waits_history_full= true;
  }
  thread->m_waits_history_index= index;
}

/**
  Insert a wait record in table EVENTS_WAITS_HISTORY_LONG.
  @param wait               record to insert
*/
void insert_events_waits_history_long(PFS_events_waits *wait)
{
  if (unlikely(events_waits_history_long_size == 0))
    return;

Sergei Golubchik's avatar
Sergei Golubchik committed
138
  uint index= PFS_atomic::add_u32(&events_waits_history_long_index.m_u32, 1);
139 140 141 142 143 144 145 146 147

  index= index % events_waits_history_long_size;
  if (index == 0)
    events_waits_history_long_full= true;

  /* See related comment in insert_events_waits_history. */
  copy_events_waits(&events_waits_history_long_array[index], wait);
}

Sergei Golubchik's avatar
Sergei Golubchik committed
148 149 150 151 152 153 154 155 156 157
static void fct_reset_events_waits_current(PFS_thread *pfs_thread)
{
  PFS_events_waits *pfs_wait= pfs_thread->m_events_waits_stack;
  PFS_events_waits *pfs_wait_last= pfs_wait + WAIT_STACK_SIZE;

  for ( ; pfs_wait < pfs_wait_last; pfs_wait++)
    pfs_wait->m_wait_class= NO_WAIT_CLASS;
}


158 159 160
/** Reset table EVENTS_WAITS_CURRENT data. */
void reset_events_waits_current(void)
{
Sergei Golubchik's avatar
Sergei Golubchik committed
161 162
  global_thread_container.apply_all(fct_reset_events_waits_current);
}
163

Sergei Golubchik's avatar
Sergei Golubchik committed
164 165 166 167
static void fct_reset_events_waits_history(PFS_thread *pfs_thread)
{
  PFS_events_waits *wait= pfs_thread->m_waits_history;
  PFS_events_waits *wait_last= wait + events_waits_history_per_thread;
168

Sergei Golubchik's avatar
Sergei Golubchik committed
169 170 171 172
  pfs_thread->m_waits_history_index= 0;
  pfs_thread->m_waits_history_full= false;
  for ( ; wait < wait_last; wait++)
    wait->m_wait_class= NO_WAIT_CLASS;
173 174 175 176 177
}

/** Reset table EVENTS_WAITS_HISTORY data. */
void reset_events_waits_history(void)
{
Sergei Golubchik's avatar
Sergei Golubchik committed
178
  global_thread_container.apply_all(fct_reset_events_waits_history);
179 180 181 182 183
}

/** Reset table EVENTS_WAITS_HISTORY_LONG data. */
void reset_events_waits_history_long(void)
{
Sergei Golubchik's avatar
Sergei Golubchik committed
184
  PFS_atomic::store_u32(&events_waits_history_long_index.m_u32, 0);
185 186 187 188 189 190 191 192
  events_waits_history_long_full= false;

  PFS_events_waits *wait= events_waits_history_long_array;
  PFS_events_waits *wait_last= wait + events_waits_history_long_size;
  for ( ; wait < wait_last; wait++)
    wait->m_wait_class= NO_WAIT_CLASS;
}

Sergei Golubchik's avatar
Sergei Golubchik committed
193 194 195 196 197 198 199 200
static void fct_reset_events_waits_by_thread(PFS_thread *thread)
{
  PFS_account *account= sanitize_account(thread->m_account);
  PFS_user *user= sanitize_user(thread->m_user);
  PFS_host *host= sanitize_host(thread->m_host);
  aggregate_thread_waits(thread, account, user, host);
}

201 202 203
/** Reset table EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME data. */
void reset_events_waits_by_thread()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
204 205
  global_thread_container.apply(fct_reset_events_waits_by_thread);
}
206

Sergei Golubchik's avatar
Sergei Golubchik committed
207 208 209 210 211
static void fct_reset_events_waits_by_account(PFS_account *pfs)
{
  PFS_user *user= sanitize_user(pfs->m_user);
  PFS_host *host= sanitize_host(pfs->m_host);
  pfs->aggregate_waits(user, host);
212 213 214 215 216
}

/** Reset table EVENTS_WAITS_SUMMARY_BY_ACCOUNT_BY_EVENT_NAME data. */
void reset_events_waits_by_account()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
217 218
  global_account_container.apply(fct_reset_events_waits_by_account);
}
219

Sergei Golubchik's avatar
Sergei Golubchik committed
220 221 222
static void fct_reset_events_waits_by_user(PFS_user *pfs)
{
  pfs->aggregate_waits();
223 224 225 226 227
}

/** Reset table EVENTS_WAITS_SUMMARY_BY_USER_BY_EVENT_NAME data. */
void reset_events_waits_by_user()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
228 229
  global_user_container.apply(fct_reset_events_waits_by_user);
}
230

Sergei Golubchik's avatar
Sergei Golubchik committed
231 232 233
static void fct_reset_events_waits_by_host(PFS_host *pfs)
{
  pfs->aggregate_waits();
234 235 236 237 238
}

/** Reset table EVENTS_WAITS_SUMMARY_BY_HOST_BY_EVENT_NAME data. */
void reset_events_waits_by_host()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
239 240
  global_host_container.apply(fct_reset_events_waits_by_host);
}
241

Sergei Golubchik's avatar
Sergei Golubchik committed
242 243 244
static void fct_reset_table_waits_by_table(PFS_table_share *pfs)
{
  pfs->aggregate();
245 246 247 248
}

void reset_table_waits_by_table()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
249 250
  global_table_share_container.apply(fct_reset_table_waits_by_table);
}
251

Sergei Golubchik's avatar
Sergei Golubchik committed
252 253 254
static void fct_reset_table_io_waits_by_table(PFS_table_share *pfs)
{
  pfs->aggregate_io();
255 256 257 258
}

void reset_table_io_waits_by_table()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
259 260
  global_table_share_container.apply(fct_reset_table_io_waits_by_table);
}
261

Sergei Golubchik's avatar
Sergei Golubchik committed
262 263 264
static void fct_reset_table_lock_waits_by_table(PFS_table_share *pfs)
{
  pfs->aggregate_lock();
265 266 267 268
}

void reset_table_lock_waits_by_table()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
269 270
  global_table_share_container.apply(fct_reset_table_lock_waits_by_table);
}
271

Sergei Golubchik's avatar
Sergei Golubchik committed
272 273 274
void fct_reset_table_waits_by_table_handle(PFS_table *pfs)
{
  pfs->sanitized_aggregate();
275 276 277 278
}

void reset_table_waits_by_table_handle()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
279 280
  global_table_container.apply(fct_reset_table_waits_by_table_handle);
}
281

Sergei Golubchik's avatar
Sergei Golubchik committed
282 283 284
void fct_reset_table_io_waits_by_table_handle(PFS_table *pfs)
{
  pfs->sanitized_aggregate_io();
285 286 287 288
}

void reset_table_io_waits_by_table_handle()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
289 290
  global_table_container.apply(fct_reset_table_io_waits_by_table_handle);
}
291

Sergei Golubchik's avatar
Sergei Golubchik committed
292 293 294
void fct_reset_table_lock_waits_by_table_handle(PFS_table *pfs)
{
  pfs->sanitized_aggregate_lock();
295 296 297 298
}

void reset_table_lock_waits_by_table_handle()
{
Sergei Golubchik's avatar
Sergei Golubchik committed
299
  global_table_container.apply(fct_reset_table_lock_waits_by_table_handle);
300 301
}