ob_mysql_packet.h 11.5 KB
Newer Older
O
oceanbase-admin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
/**
 * Copyright (c) 2021 OceanBase
 * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#ifndef _OB_MYSQL_PACKET_H_
#define _OB_MYSQL_PACKET_H_

#include "rpc/ob_packet.h"

namespace oceanbase
{
namespace obmysql
{

#define OBPROXY_NEW_MYSQL_CMD_START 161
#define OBPROXY_MYSQL_CMD_START 240

enum ObMySQLCmd
{
  OB_MYSQL_COM_SLEEP,
  OB_MYSQL_COM_QUIT,
  OB_MYSQL_COM_INIT_DB,
  OB_MYSQL_COM_QUERY,
  OB_MYSQL_COM_FIELD_LIST,

  OB_MYSQL_COM_CREATE_DB,
  OB_MYSQL_COM_DROP_DB,
  OB_MYSQL_COM_REFRESH,
  OB_MYSQL_COM_SHUTDOWN,
  OB_MYSQL_COM_STATISTICS,

  OB_MYSQL_COM_PROCESS_INFO,
  OB_MYSQL_COM_CONNECT,
  OB_MYSQL_COM_PROCESS_KILL,
  OB_MYSQL_COM_DEBUG,
  OB_MYSQL_COM_PING,

  OB_MYSQL_COM_TIME,
  OB_MYSQL_COM_DELAYED_INSERT,
  OB_MYSQL_COM_CHANGE_USER,
  OB_MYSQL_COM_BINLOG_DUMP,

  OB_MYSQL_COM_TABLE_DUMP,
  OB_MYSQL_COM_CONNECT_OUT,
  OB_MYSQL_COM_REGISTER_SLAVE,

  OB_MYSQL_COM_STMT_PREPARE,
  OB_MYSQL_COM_STMT_EXECUTE,
  OB_MYSQL_COM_STMT_SEND_LONG_DATA,
  OB_MYSQL_COM_STMT_CLOSE,

  OB_MYSQL_COM_STMT_RESET,
  OB_MYSQL_COM_SET_OPTION,
  OB_MYSQL_COM_STMT_FETCH,
  OB_MYSQL_COM_DAEMON,

  OB_MYSQL_COM_BINLOG_DUMP_GTID,

  // COM_RESET_CONNECTION,
  OB_MYSQL_COM_STMT_PREPARE_EXECUTE = OBPROXY_NEW_MYSQL_CMD_START,
W
wgs13579 已提交
69 70
  OB_MYSQL_COM_STMT_SEND_PIECE_DATA,
  OB_MYSQL_COM_STMT_GET_PIECE_DATA,
O
oceanbase-admin 已提交
71 72 73
  OB_MYSQL_COM_END,


W
wgs13579 已提交
74

O
oceanbase-admin 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
  // for obproxy
  // OB_MYSQL_COM_DELETE_SESSION is not a standard mysql package type. This is a package used to process delete session
  // When the connection is disconnected, the session needs to be deleted, but at this time it may not be obtained in the callback function disconnect
  // Session lock, at this time, an asynchronous task will be added to the obmysql queue
  OB_MYSQL_COM_DELETE_SESSION = OBPROXY_MYSQL_CMD_START,
  // OB_MYSQL_COM_HANDSHAKE and OB_MYSQL_COM_LOGIN are not standard mysql package types, they are used in ObProxy
  // OB_MYSQL_COM_HANDSHAKE represents client---->on_connect && observer--->hand shake or error
  // OB_MYSQL_COM_LOGIN represents client---->hand shake response && observer---> ok or error
  OB_MYSQL_COM_HANDSHAKE,
  OB_MYSQL_COM_LOGIN,
  OB_MYSQL_COM_MAX_NUM
};

union ObServerStatusFlags
{
  ObServerStatusFlags() : flags_(0) {}
  explicit ObServerStatusFlags(uint16_t flag) : flags_(flag) {}
  uint16_t flags_;
  //ref:http://dev.mysql.com/doc/internals/en/status-flags.html
  struct ServerStatusFlags
  {
    uint16_t OB_SERVER_STATUS_IN_TRANS:             1;  // a transaction is active
    uint16_t OB_SERVER_STATUS_AUTOCOMMIT:           1;  // auto-commit is enabled
    uint16_t OB_SERVER_STATUS_RESERVED:             1;  // reserved, not used now
    uint16_t OB_SERVER_MORE_RESULTS_EXISTS:         1;
    uint16_t OB_SERVER_STATUS_NO_GOOD_INDEX_USED:   1;
    uint16_t OB_SERVER_STATUS_NO_INDEX_USED:        1;
    // used by Binary Protocol Resultset to signal that
    // OB_MYSQL_COM_STMT_FETCH has to be used to fetch the row-data.
    uint16_t OB_SERVER_STATUS_CURSOR_EXISTS:        1;
    uint16_t OB_SERVER_STATUS_LAST_ROW_SENT:        1;
    uint16_t OB_SERVER_STATUS_DB_DROPPED:           1;
    uint16_t OB_SERVER_STATUS_NO_BACKSLASH_ESCAPES: 1;
    uint16_t OB_SERVER_STATUS_METADATA_CHANGED:     1;
    uint16_t OB_SERVER_QUERY_WAS_SLOW:              1;
    uint16_t OB_SERVER_PS_OUT_PARAMS:               1;
    uint16_t OB_SERVER_STATUS_IN_TRANS_READONLY:    1;  // in a read-only transaction
    uint16_t OB_SERVER_SESSION_STATE_CHANGED:       1;  // connection state information has changed
  } status_flags_;
};

union ObMySQLCapabilityFlags
{
  ObMySQLCapabilityFlags() : capability_(0) {}
  explicit ObMySQLCapabilityFlags(uint32_t cap) : capability_(cap) {}
  uint32_t capability_;
  //ref:http://dev.mysql.com/doc/internals/en/capability-flags.html
  struct CapabilityFlags
  {
    uint32_t OB_CLIENT_LONG_PASSWORD:                   1;
    uint32_t OB_CLIENT_FOUND_ROWS:                      1;
    uint32_t OB_CLIENT_LONG_FLAG:                       1;
    uint32_t OB_CLIENT_CONNECT_WITH_DB:                 1;
    uint32_t OB_CLIENT_NO_SCHEMA:                       1;
    uint32_t OB_CLIENT_COMPRESS:                        1;
    uint32_t OB_CLIENT_ODBC:                            1;
    uint32_t OB_CLIENT_LOCAL_FILES:                     1;
    uint32_t OB_CLIENT_IGNORE_SPACE:                    1;
    uint32_t OB_CLIENT_PROTOCOL_41:                     1;
    uint32_t OB_CLIENT_INTERACTIVE:                     1;
    uint32_t OB_CLIENT_SSL:                             1;
    uint32_t OB_CLIENT_IGNORE_SIGPIPE:                  1;
    uint32_t OB_CLIENT_TRANSACTIONS:                    1;
    uint32_t OB_CLIENT_RESERVED:                        1;
    uint32_t OB_CLIENT_SECURE_CONNECTION:               1;
    uint32_t OB_CLIENT_MULTI_STATEMENTS:                1;
    uint32_t OB_CLIENT_MULTI_RESULTS:                   1;
    uint32_t OB_CLIENT_PS_MULTI_RESULTS:                1;
    uint32_t OB_CLIENT_PLUGIN_AUTH:                     1;
    uint32_t OB_CLIENT_CONNECT_ATTRS:                   1;
    uint32_t OB_CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA:  1;
    uint32_t OB_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS:    1;
    uint32_t OB_CLIENT_SESSION_TRACK:                   1;
    uint32_t OB_CLIENT_DEPRECATE_EOF:                   1;
    uint32_t OB_CLIENT_RESERVED_NOT_USE:                2;
    uint32_t OB_CLIENT_SUPPORT_ORACLE_MODE:             1;
    uint32_t OB_CLIENT_RESERVED_NOT_USE_V2:             4;
  } cap_flags_;
};

enum ObClientCapabilityPos
{
  OB_CLIENT_LONG_PASSWORD_POS = 0,
  OB_CLIENT_FOUND_ROWS_POS,
  OB_CLIENT_LONG_FLAG_POS,
  OB_CLIENT_CONNECT_WITH_DB_POS,
  OB_CLIENT_NO_SCHEMA_POS,
  OB_CLIENT_COMPRESS_POS,
  OB_CLIENT_ODBC_POS,
  OB_CLIENT_LOCAL_FILES_POS,
  OB_CLIENT_IGNORE_SPACE_POS,
  OB_CLIENT_PROTOCOL_41_POS,
  OB_CLIENT_INTERACTIVE_POS,
  OB_CLIENT_SSL_POS,
  OB_CLIENT_IGNORE_SIGPIPE_POS,
  OB_CLIENT_TRANSACTION_POS,
  OB_CLIENT_RESERVED_POS,
  OB_CLIENT_SECURE_CONNECTION_POS,
  OB_CLIENT_MULTI_STATEMENTS_POS,
  OB_CLIENT_MULTI_RESULTS_POS,
  OB_CLIENT_PS_MULTI_RESULTS_POS,
  OB_CLIENT_PLUGIN_AUTH_POS,
  OB_CLIENT_CONNECT_ATTRS_POS,
  OB_CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA_POS,
  OB_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS_POS,
  OB_CLIENT_SESSION_TRACK_POS,
  OB_CLIENT_DEPRECATE_EOF_POS,
};

enum ObServerStatusFlagsPos
{
  OB_SERVER_STATUS_IN_TRANS_POS = 0,
  OB_SERVER_STATUS_AUTOCOMMIT_POS,
  OB_SERVER_STATUS_RESERVED_POS,
  OB_SERVER_MORE_RESULTS_EXISTS_POS,
  OB_SERVER_STATUS_NO_GOOD_INDEX_USED_POS,
  OB_SERVER_STATUS_NO_INDEX_USED_POS,
  OB_SERVER_STATUS_CURSOR_EXISTS_POS,
  OB_SERVER_STATUS_LAST_ROW_SENT_POS,
  OB_SERVER_STATUS_DB_DROPPED_POS,
  OB_SERVER_STATUS_NO_BACKSLASH_ESCAPES_POS,
  OB_SERVER_STATUS_METADATA_CHANGED_POS,
  OB_SERVER_QUERY_WAS_SLOW_POS,
  OB_SERVER_PS_OUT_PARAMS_POS,
  OB_SERVER_STATUS_IN_TRANS_READONLY_POS,
  OB_SERVER_SESSION_STATE_CHANGED_POS,
};

char const *get_mysql_cmd_str(ObMySQLCmd mysql_cmd);

//http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user
enum ObInformationFunctions
{
  BENCHMARK_FUNC = 0,     // Repeatedly execute an expression
  CHARSET_FUNC,           // Return the character set of the argument
  COERCIBILITY_FUNC,      // Return the collation coercibility value of the string argument
  COLLATION_FUNC,         // Return the collation of the string argument
  CONNECTION_ID_FUNC,     // Return the connection ID (thread ID) for the connection
  CURRENT_USER_FUNC,      // The authenticated user name and host name
  DATABASE_FUNC,          // Return the default (current) database name
  FOUND_ROWS_FUNC,        // For a SELECT with a LIMIT clause, the number of rows
                          // that would be returned were there no LIMIT clause
  LAST_INSERT_ID_FUNC,    // Value of the AUTOINCREMENT column for the last INSERT
  ROW_COUNT_FUNC,         // The number of rows updated
  SCHEAM_FUNC,            // Synonym for DATABASE()
  SESSION_USER_FUNC,      // Synonym for USER()
  SYSTEM_USER_FUNC,       // Synonym for USER()
  USER_FUNC,              // The user name and host name provided by the client
  VERSION_FUNC,           // Return a string that indicates the MySQL server version
  MAX_INFO_FUNC           // end
};

char const *get_info_func_name(const ObInformationFunctions func);

template<class K, class V>
class ObCommonKV
{
public:
  ObCommonKV() : key_(), value_() {}
  void reset()
  {
    key_.reset();
    value_.reset();
  }
  K key_;
  V value_;
  TO_STRING_KV(K_(key), K_(value));
};

typedef ObCommonKV<common::ObString, common::ObString> ObStringKV;

static const int64_t MAX_STORE_LENGTH = 9;

class ObMySQLPacketHeader
{
public:
  ObMySQLPacketHeader()
      : len_(0), seq_(0)
  { }

  TO_STRING_KV("length", len_, "sequence", seq_);

public:
  uint32_t len_;         // MySQL packet length not include packet header
  uint8_t  seq_;         // MySQL packet sequence
};

class ObMySQLPacket
    : public rpc::ObPacket
{
public:
  ObMySQLPacket()
      : hdr_(), cdata_(NULL)
  {}
  virtual ~ObMySQLPacket() {}

  static int encode_packet(char *buf, int64_t &len, int64_t &pos, const ObMySQLPacket &pkt);
  inline void set_seq(uint8_t seq);
  inline uint8_t get_seq(void) const;
  inline void set_content(const char *content, uint32_t len);

  virtual int64_t get_serialize_size() const;
  int encode(char *buffer, int64_t length, int64_t &pos) const;
  virtual int decode() { return common::OB_NOT_SUPPORTED; }

  VIRTUAL_TO_STRING_KV("header", hdr_);

protected:
  virtual int serialize(char*, const int64_t, int64_t&) const
  {
    return common::OB_NOT_SUPPORTED;
  }

public:
  static const int64_t HANDSHAKE_RESPONSE_RESERVED_SIZE = 23;
    // 4: capability flags
    // 4: max-packet size
    // 1: character set
    static const int64_t HANDSHAKE_RESPONSE_MIN_SIZE = 9 + HANDSHAKE_RESPONSE_RESERVED_SIZE;
    // 4: capability flags
    static const int64_t JDBC_SSL_MIN_SIZE = 4;
    // 2: capability flags
    static const int64_t MIN_CAPABILITY_SIZE = 2;

protected:
  ObMySQLPacketHeader hdr_;
  const char *cdata_;
};

class ObMySQLRawPacket
    : public ObMySQLPacket
{
public:
  ObMySQLRawPacket() : ObMySQLPacket(), cmd_(OB_MYSQL_COM_MAX_NUM) {}
  explicit ObMySQLRawPacket(obmysql::ObMySQLCmd cmd) : ObMySQLPacket(), cmd_(cmd) {}

  inline void set_cmd(ObMySQLCmd cmd);
  inline ObMySQLCmd get_cmd() const;

  inline const char *get_cdata() const;
  inline uint32_t get_clen() const;
  int encode_packet_meta(char *buf, int64_t &len, int64_t &pos) const;

  virtual int64_t get_serialize_size() const;
  TO_STRING_KV("header", hdr_);
protected:
  virtual int serialize(char*, const int64_t, int64_t&) const;

private:
  void set_len(uint32_t len);
private:
  ObMySQLCmd cmd_;
};

void ObMySQLPacket::set_seq(uint8_t seq)
{
  hdr_.seq_ = seq;
}

uint8_t ObMySQLPacket::get_seq(void) const
{
  return hdr_.seq_;
}

void ObMySQLPacket::set_content(const char *content, uint32_t len)
{
  cdata_ = content;
  hdr_.len_ = len;
}

void ObMySQLRawPacket::set_cmd(ObMySQLCmd cmd)
{
  cmd_ = cmd;
}

ObMySQLCmd ObMySQLRawPacket::get_cmd() const
{
  return cmd_;
}

inline const char *ObMySQLRawPacket::get_cdata() const
{
  return cdata_;
}

inline uint32_t ObMySQLRawPacket::get_clen() const
{
  return hdr_.len_;
}

} // end of namespace obmysql
} // end of namespace oceanbase

#endif /* _OB_MYSQL_PACKET_H_ */