| 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 | */ |
| 31 | struct PFS_engine_table_share; |
| 32 | class PFS_engine_table; |
| 33 | /** Name of the performance schema engine. */ |
| 34 | extern const char *pfs_engine_name; |
| 35 | |
| 36 | /** A handler for a PERFORMANCE_SCHEMA table. */ |
| 37 | class ha_perfschema : public handler |
| 38 | { |
| 39 | public: |
| 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 | |
| 200 | private: |
| 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 | |