1/* Copyright (c) 2008, 2014, 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
16#ifndef HA_PERFSCHEMA_H
17#define HA_PERFSCHEMA_H
18
19#include "handler.h" /* class handler */
20#include "table.h"
21#include "sql_class.h"
22
23/**
24 @file storage/perfschema/ha_perfschema.h
25 Performance schema storage engine (declarations).
26
27 @defgroup Performance_schema_engine Performance Schema Engine
28 @ingroup Performance_schema_implementation
29 @{
30*/
31struct PFS_engine_table_share;
32class PFS_engine_table;
33/** Name of the performance schema engine. */
34extern const char *pfs_engine_name;
35
36/** A handler for a PERFORMANCE_SCHEMA table. */
37class ha_perfschema : public handler
38{
39public:
40 /**
41 Create a new performance schema table handle on a table.
42 @param hton storage engine handler singleton
43 @param share table share
44 */
45 ha_perfschema(handlerton *hton, TABLE_SHARE *share);
46
47 ~ha_perfschema();
48
49 const char *index_type(uint) { return ""; }
50
51 /** Capabilities of the performance schema tables. */
52 ulonglong table_flags(void) const
53 {
54 /*
55 About HA_FAST_KEY_READ:
56
57 The storage engine ::rnd_pos() method is fast to locate records by key,
58 so HA_FAST_KEY_READ is technically true, but the record content can be
59 overwritten between ::rnd_next() and ::rnd_pos(), because all the P_S
60 data is volatile.
61 The HA_FAST_KEY_READ flag is not advertised, to force the optimizer
62 to cache records instead, to provide more consistent records.
63 For example, consider the following statement:
64 - select * from P_S.EVENTS_WAITS_HISTORY_LONG where THREAD_ID=<n>
65 order by ...
66 With HA_FAST_KEY_READ, it can return records where "THREAD_ID=<n>"
67 is false, because the where clause was evaluated to true after
68 ::rnd_pos(), then the content changed, then the record was fetched by
69 key using ::rnd_pos().
70 Without HA_FAST_KEY_READ, the optimizer reads all columns and never
71 calls ::rnd_pos(), so it is guaranteed to return only thread <n>
72 records.
73 */
74 return HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_NO_AUTO_INCREMENT |
75 HA_PRIMARY_KEY_REQUIRED_FOR_DELETE;
76 }
77
78 /**
79 Operations supported by indexes.
80 None, there are no indexes.
81 */
82 ulong index_flags(uint , uint , bool ) const
83 { return 0; }
84
85 uint max_supported_record_length(void) const
86 { return HA_MAX_REC_LENGTH; }
87
88 uint max_supported_keys(void) const
89 { return 0; }
90
91 uint max_supported_key_parts(void) const
92 { return 0; }
93
94 uint max_supported_key_length(void) const
95 { return 0; }
96
97 ha_rows estimate_rows_upper_bound(void)
98 { return HA_POS_ERROR; }
99
100 double scan_time(void)
101 { return 1.0; }
102
103 /**
104 Open a performance schema table.
105 @param name the table to open
106 @param mode unused
107 @param test_if_locked unused
108 @return 0 on success
109 */
110 int open(const char *name, int mode, uint test_if_locked);
111
112 /**
113 Close a table handle.
114 @sa open.
115 */
116 int close(void);
117
118 /**
119 Write a row.
120 @param buf the row to write
121 @return 0 on success
122 */
123 int write_row(uchar *buf);
124
125 void use_hidden_primary_key();
126
127 /**
128 Update a row.
129 @param old_data the row old values
130 @param new_data the row new values
131 @return 0 on success
132 */
133 int update_row(const uchar *old_data, const uchar *new_data);
134
135 /**
136 Delete a row.
137 @param buf the row to delete
138 @return 0 on success
139 */
140 int delete_row(const uchar *buf);
141
142 int rnd_init(bool scan);
143
144 /**
145 Scan end.
146 @sa rnd_init.
147 */
148 int rnd_end(void);
149
150 /**
151 Iterator, fetch the next row.
152 @param[out] buf the row fetched.
153 @return 0 on success
154 */
155 int rnd_next(uchar *buf);
156
157 /**
158 Iterator, fetch the row at a given position.
159 @param[out] buf the row fetched.
160 @param pos the row position
161 @return 0 on success
162 */
163 int rnd_pos(uchar *buf, uchar *pos);
164
165 /**
166 Read the row current position.
167 @param record the current row
168 */
169 void position(const uchar *record);
170
171 int info(uint);
172
173 int delete_all_rows(void);
174
175 int truncate();
176
177 int delete_table(const char *from);
178
179 int rename_table(const char * from, const char * to);
180
181 int create(const char *name, TABLE *form,
182 HA_CREATE_INFO *create_info);
183
184 THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
185 enum thr_lock_type lock_type);
186
187 virtual uint8 table_cache_type(void)
188 { return HA_CACHE_TBL_NOCACHE; }
189
190 virtual my_bool register_query_cache_table
191 (THD *, const char *, uint , qc_engine_callback *engine_callback,
192 ulonglong *)
193 {
194 *engine_callback= 0;
195 return FALSE;
196 }
197
198 virtual void print_error(int error, myf errflags);
199
200private:
201 /**
202 Check if the caller is a replication thread or the caller is called
203 by a client thread executing base64 encoded BINLOG'... statement.
204
205 In theory, performance schema tables are not supposed to be replicated.
206 This is true and enforced starting with MySQL 5.6.10.
207 In practice, in previous versions such as MySQL 5.5 (GA) or earlier 5.6
208 (non GA) DML on performance schema tables could end up written in the binlog,
209 both in STATEMENT and ROW format.
210 While these records are not supposed to be there, they are found when:
211 - performing replication from a 5.5 master to a 5.6 slave during
212 upgrades
213 - performing replication from 5.5 (performance_schema enabled)
214 to a 5.6 slave
215 - performing point in time recovery in 5.6 with old archived logs.
216
217 This API detects when the code calling the performance schema storage
218 engine is a slave thread or whether the code calling isthe client thread
219 executing a BINLOG'.. statement.
220
221 This API acts as a late filter for the above mentioned cases.
222
223 For ROW format, @see Rows_log_event::do_apply_event()
224
225 */
226 bool is_executed_by_slave() const
227 {
228 DBUG_ASSERT(table != NULL);
229 DBUG_ASSERT(table->in_use != NULL);
230 return table->in_use->slave_thread;
231
232 }
233
234 /** MySQL lock */
235 THR_LOCK_DATA m_thr_lock;
236 /** Performance schema table share for this table handler. */
237 const PFS_engine_table_share *m_table_share;
238 /** Performance schema table cursor. */
239 PFS_engine_table *m_table;
240};
241
242/** @} */
243#endif
244
245