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