You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
8.5 KiB

  1. /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software Foundation,
  11. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
  12. #ifndef PFS_INSTR_H
  13. #define PFS_INSTR_H
  14. /**
  15. @file storage/perfschema/pfs_instr.h
  16. Performance schema instruments (declarations).
  17. */
  18. #include "pfs_lock.h"
  19. #include "pfs_instr_class.h"
  20. #include "pfs_events_waits.h"
  21. #include "pfs_server.h"
  22. #include "lf.h"
  23. /**
  24. @addtogroup Performance_schema_buffers
  25. @{
  26. */
  27. struct PFS_thread;
  28. struct PFS_instr
  29. {
  30. /** Internal lock. */
  31. pfs_lock m_lock;
  32. /** Instrument wait statistics chain. */
  33. PFS_single_stat_chain m_wait_stat;
  34. };
  35. /** Instrumented mutex implementation. @see PSI_mutex. */
  36. struct PFS_mutex : public PFS_instr
  37. {
  38. /** Mutex identity, typically a pthread_mutex_t. */
  39. const void *m_identity;
  40. /** Mutex class. */
  41. PFS_mutex_class *m_class;
  42. /**
  43. Mutex lock usage statistics chain.
  44. This statistic is not exposed in user visible tables yet.
  45. */
  46. PFS_single_stat_chain m_lock_stat;
  47. /** Current owner. */
  48. PFS_thread *m_owner;
  49. /**
  50. Timestamp of the last lock.
  51. This statistic is not exposed in user visible tables yet.
  52. */
  53. ulonglong m_last_locked;
  54. };
  55. /** Instrumented rwlock implementation. @see PSI_rwlock. */
  56. struct PFS_rwlock : public PFS_instr
  57. {
  58. /** RWLock identity, typically a pthread_rwlock_t. */
  59. const void *m_identity;
  60. /** RWLock class. */
  61. PFS_rwlock_class *m_class;
  62. /**
  63. RWLock read lock usage statistics chain.
  64. This statistic is not exposed in user visible tables yet.
  65. */
  66. PFS_single_stat_chain m_read_lock_stat;
  67. /**
  68. RWLock write lock usage statistics chain.
  69. This statistic is not exposed in user visible tables yet.
  70. */
  71. PFS_single_stat_chain m_write_lock_stat;
  72. /** Current writer thread. */
  73. PFS_thread *m_writer;
  74. /** Current count of readers. */
  75. uint m_readers;
  76. /**
  77. Timestamp of the last write.
  78. This statistic is not exposed in user visible tables yet.
  79. */
  80. ulonglong m_last_written;
  81. /**
  82. Timestamp of the last read.
  83. This statistic is not exposed in user visible tables yet.
  84. */
  85. ulonglong m_last_read;
  86. };
  87. /** Instrumented cond implementation. @see PSI_cond. */
  88. struct PFS_cond : public PFS_instr
  89. {
  90. /** Condition identity, typically a pthread_cond_t. */
  91. const void *m_identity;
  92. /** Condition class. */
  93. PFS_cond_class *m_class;
  94. /** Condition instance usage statistics. */
  95. PFS_cond_stat m_cond_stat;
  96. };
  97. /** Instrumented File and FILE implementation. @see PSI_file. */
  98. struct PFS_file : public PFS_instr
  99. {
  100. /** File name. */
  101. char m_filename[FN_REFLEN];
  102. /** File name length in bytes. */
  103. uint m_filename_length;
  104. /** File class. */
  105. PFS_file_class *m_class;
  106. /** File usage statistics. */
  107. PFS_file_stat m_file_stat;
  108. };
  109. /** Instrumented table implementation. @see PSI_table. */
  110. struct PFS_table : public PFS_instr
  111. {
  112. /** Table share. */
  113. PFS_table_share *m_share;
  114. /** Table identity, typically a handler. */
  115. const void *m_identity;
  116. };
  117. /**
  118. @def LOCKER_STACK_SIZE
  119. Maximum number of nested waits.
  120. */
  121. #define LOCKER_STACK_SIZE 3
  122. /**
  123. @def PFS_MAX_ALLOC_RETRY
  124. Maximum number of times the code attempts to allocate an item
  125. from internal buffers, before giving up.
  126. */
  127. #define PFS_MAX_ALLOC_RETRY 1000
  128. #define PFS_MAX_SCAN_PASS 2
  129. /**
  130. Helper to scan circular buffers.
  131. Given a buffer of size [0, max_size - 1],
  132. and a random starting point in the buffer,
  133. this helper returns up to two [first, last -1] intervals that:
  134. - fit into the [0, max_size - 1] range,
  135. - have a maximum combined length of at most PFS_MAX_ALLOC_RETRY.
  136. */
  137. struct PFS_scan
  138. {
  139. public:
  140. void init(uint random, uint max_size);
  141. bool has_pass() const
  142. { return (m_pass < m_pass_max); }
  143. void next_pass()
  144. { m_pass++; }
  145. uint first() const
  146. { return m_first[m_pass]; }
  147. uint last() const
  148. { return m_last[m_pass]; }
  149. private:
  150. uint m_pass;
  151. uint m_pass_max;
  152. uint m_first[PFS_MAX_SCAN_PASS];
  153. uint m_last[PFS_MAX_SCAN_PASS];
  154. };
  155. /** Instrumented thread implementation. @see PSI_thread. */
  156. struct PFS_thread
  157. {
  158. /** Internal lock. */
  159. pfs_lock m_lock;
  160. /** Pins for filename_hash. */
  161. LF_PINS *m_filename_hash_pins;
  162. /** Pins for table_share_hash. */
  163. LF_PINS *m_table_share_hash_pins;
  164. /** Event ID counter */
  165. ulonglong m_event_id;
  166. /** Thread instrumentation flag. */
  167. bool m_enabled;
  168. /** Internal thread identifier, unique. */
  169. ulong m_thread_internal_id;
  170. /** External (SHOW PROCESSLIST) thread identifier, not unique. */
  171. ulong m_thread_id;
  172. /** Thread class. */
  173. PFS_thread_class *m_class;
  174. /** Size of @c m_wait_locker_stack. */
  175. uint m_wait_locker_count;
  176. /**
  177. Stack of wait lockers.
  178. This member holds the data for the table
  179. PERFORMANCE_SCHEMA.EVENTS_WAITS_CURRENT.
  180. For most locks, only 1 wait locker is used at a given time.
  181. For composite locks, several records are needed:
  182. - 1 for a 'logical' wait (for example on the GLOBAL READ LOCK state)
  183. - 1 for a 'physical' wait (for example on COND_refresh)
  184. */
  185. PFS_wait_locker m_wait_locker_stack[LOCKER_STACK_SIZE];
  186. /** True if the circular buffer @c m_waits_history is full. */
  187. bool m_waits_history_full;
  188. /** Current index in the circular buffer @c m_waits_history. */
  189. uint m_waits_history_index;
  190. /**
  191. Waits history circular buffer.
  192. This member holds the data for the table
  193. PERFORMANCE_SCHEMA.EVENTS_WAITS_HISTORY.
  194. */
  195. PFS_events_waits *m_waits_history;
  196. /**
  197. Per thread waits aggregated statistics.
  198. This member holds the data for the table
  199. PERFORMANCE_SCHEMA.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.
  200. */
  201. PFS_single_stat_chain *m_instr_class_wait_stats;
  202. };
  203. PFS_thread *sanitize_thread(PFS_thread *unsafe);
  204. const char *sanitize_file_name(const char *unsafe);
  205. PFS_single_stat_chain*
  206. find_per_thread_mutex_class_wait_stat(PFS_thread *thread,
  207. PFS_mutex_class *klass);
  208. PFS_single_stat_chain*
  209. find_per_thread_rwlock_class_wait_stat(PFS_thread *thread,
  210. PFS_rwlock_class *klass);
  211. PFS_single_stat_chain*
  212. find_per_thread_cond_class_wait_stat(PFS_thread *thread,
  213. PFS_cond_class *klass);
  214. PFS_single_stat_chain*
  215. find_per_thread_file_class_wait_stat(PFS_thread *thread,
  216. PFS_file_class *klass);
  217. int init_instruments(const PFS_global_param *param);
  218. void cleanup_instruments();
  219. int init_file_hash();
  220. void cleanup_file_hash();
  221. PFS_mutex* create_mutex(PFS_mutex_class *mutex_class, const void *identity);
  222. void destroy_mutex(PFS_mutex *pfs);
  223. PFS_rwlock* create_rwlock(PFS_rwlock_class *klass, const void *identity);
  224. void destroy_rwlock(PFS_rwlock *pfs);
  225. PFS_cond* create_cond(PFS_cond_class *klass, const void *identity);
  226. void destroy_cond(PFS_cond *pfs);
  227. PFS_thread* create_thread(PFS_thread_class *klass, const void *identity,
  228. ulong thread_id);
  229. void destroy_thread(PFS_thread *pfs);
  230. PFS_file* find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
  231. const char *filename, uint len);
  232. void release_file(PFS_file *pfs);
  233. void destroy_file(PFS_thread *thread, PFS_file *pfs);
  234. PFS_table* create_table(PFS_table_share *share, const void *identity);
  235. void destroy_table(PFS_table *pfs);
  236. /* For iterators and show status. */
  237. extern ulong mutex_max;
  238. extern ulong mutex_lost;
  239. extern ulong rwlock_max;
  240. extern ulong rwlock_lost;
  241. extern ulong cond_max;
  242. extern ulong cond_lost;
  243. extern ulong thread_max;
  244. extern ulong thread_lost;
  245. extern ulong file_max;
  246. extern ulong file_lost;
  247. extern long file_handle_max;
  248. extern ulong file_handle_lost;
  249. extern ulong table_max;
  250. extern ulong table_lost;
  251. extern ulong events_waits_history_per_thread;
  252. extern ulong instr_class_per_thread;
  253. extern ulong locker_lost;
  254. /* Exposing the data directly, for iterators. */
  255. extern PFS_mutex *mutex_array;
  256. extern PFS_rwlock *rwlock_array;
  257. extern PFS_cond *cond_array;
  258. extern PFS_thread *thread_array;
  259. extern PFS_file *file_array;
  260. extern PFS_file **file_handle_array;
  261. extern PFS_table *table_array;
  262. void reset_events_waits_by_instance();
  263. void reset_per_thread_wait_stat();
  264. void reset_file_instance_io();
  265. /** @} */
  266. #endif