1156 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1156 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| #ifndef _BLR_H
 | |
| #define _BLR_H
 | |
| /*
 | |
|  * Copyright (c) 2016 MariaDB Corporation Ab
 | |
|  *
 | |
|  * Use of this software is governed by the Business Source License included
 | |
|  * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
 | |
|  *
 | |
|  * Change Date: 2022-01-01
 | |
|  *
 | |
|  * On the date above, in accordance with the Business Source License, use
 | |
|  * of this software will be governed by version 2 or later of the General
 | |
|  * Public License.
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * @file blr.h - The binlog router header file
 | |
|  */
 | |
| 
 | |
| #define MXS_MODULE_NAME "binlogrouter"
 | |
| 
 | |
| #include <maxscale/ccdefs.hh>
 | |
| 
 | |
| #include <openssl/aes.h>
 | |
| #include <pthread.h>
 | |
| #include <stdint.h>
 | |
| #include <zlib.h>
 | |
| 
 | |
| #include <string>
 | |
| #include <thread>
 | |
| #include <vector>
 | |
| 
 | |
| #include <maxscale/buffer.h>
 | |
| #include <maxscale/dcb.h>
 | |
| #include <maxscale/protocol/mysql.h>
 | |
| #include <maxscale/router.h>
 | |
| #include <maxscale/secrets.h>
 | |
| #include <maxscale/service.h>
 | |
| #include <maxscale/sqlite3.h>
 | |
| #include <maxscale/mysql_binlog.h>
 | |
| 
 | |
| #define BINLOG_FNAMELEN   255
 | |
| #define BLR_PROTOCOL      "MySQLBackend"
 | |
| #define BINLOG_MAGIC      {0xfe, 0x62, 0x69, 0x6e}
 | |
| #define BINLOG_MAGIC_SIZE 4
 | |
| #define BINLOG_NAMEFMT    "%s.%06d"
 | |
| #define BINLOG_NAME_ROOT  "mysql-bin"
 | |
| 
 | |
| #define BINLOG_EVENT_HDR_LEN       19
 | |
| #define BINLOG_EVENT_CRC_ALGO_TYPE 1
 | |
| #define BINLOG_EVENT_CRC_SIZE      4
 | |
| /* BINLOG_EVENT_LEN_OFFSET points to event_size in event_header */
 | |
| #define BINLOG_EVENT_LEN_OFFSET    9
 | |
| #define BINLOG_FATAL_ERROR_READING 1236
 | |
| #define BINLOG_DATA_TRUNCATED      2032
 | |
| 
 | |
| /* Binlog Encryption */
 | |
| #define BINLOG_ENC_ALGO_NAME_LEN         13
 | |
| #define BINLOG_FLAG_ENCRYPT              1
 | |
| #define BINLOG_FLAG_DECRYPT              0
 | |
| #define BINLOG_AES_MAX_KEY_LEN           32
 | |
| #define BINLOG_MAX_CRYPTO_SCHEME         2
 | |
| #define BINLOG_SYSTEM_DATA_CRYPTO_SCHEME 1
 | |
| #define BINLOG_MAX_KEYFILE_LINE_LEN      130
 | |
| 
 | |
| /* Event detail routine */
 | |
| #define BLR_REPORT_CHECKSUM_FORMAT "CRC32 0x"
 | |
| #define BLR_REPORT_REP_HEADER      0x02
 | |
| #define BLR_CHECK_ONLY             0x04
 | |
| 
 | |
| /* GTID slite3 query buffer size */
 | |
| #define GTID_SQL_BUFFER_SIZE 1024
 | |
| 
 | |
| /* GTID slite3 database name */
 | |
| #define GTID_MAPS_DB "gtid_maps.db"
 | |
| 
 | |
| /* Number of reties for a missing binlog file */
 | |
| #define MISSING_FILE_READ_RETRIES 20
 | |
| /**
 | |
|  * Add GTID components domain and serverid as name prefix
 | |
|  * in SHOW FULL BINARY LOGS
 | |
|  */
 | |
| #define BINLOG_FILE_EXTRA_INFO GTID_MAX_LEN
 | |
| 
 | |
| /* Default MariaDB GTID Domain Id */
 | |
| #define BLR_DEFAULT_GTID_DOMAIN_ID 0
 | |
| 
 | |
| enum binlog_storage_type
 | |
| {
 | |
|     BLR_BINLOG_STORAGE_FLAT,
 | |
|     BLR_BINLOG_STORAGE_TREE
 | |
| };
 | |
| 
 | |
| /** Conecting slave checks */
 | |
| enum blr_slave_check
 | |
| {
 | |
|     BLR_SLAVE_CONNECTING,           /*< The slave starts the registration */
 | |
|     BLR_SLAVE_IS_MARIADB10,         /*< The slave is a MariaDB10 one */
 | |
|     BLR_SLAVE_HAS_MARIADB10_GTID,   /*< The MariaDB10 Slave has GTID request */
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Supported Encryption algorithms
 | |
|  *
 | |
|  * Note: AES_ECB is only internally used
 | |
|  * Available algorithms for binlog files
 | |
|  * Encryption/Decryption are AES_CBC and AES_CTR
 | |
|  */
 | |
| enum blr_aes_mode
 | |
| {
 | |
|     BLR_AES_CBC,
 | |
|     BLR_AES_CTR,
 | |
|     BLR_AES_ECB
 | |
| };
 | |
| 
 | |
| /* Default encryption alogorithm is AES_CBC */
 | |
| #define BINLOG_DEFAULT_ENC_ALGO BLR_AES_CBC
 | |
| 
 | |
| /**
 | |
|  * Binlog event types
 | |
|  */
 | |
| #define START_EVENT_V3           0x01
 | |
| #define QUERY_EVENT              0x02
 | |
| #define STOP_EVENT               0x03
 | |
| #define ROTATE_EVENT             0x04
 | |
| #define INTVAR_EVENT             0x05
 | |
| #define LOAD_EVENT               0x06
 | |
| #define SLAVE_EVENT              0x07
 | |
| #define CREATE_FILE_EVENT        0x08
 | |
| #define APPEND_BLOCK_EVENT       0x09
 | |
| #define EXEC_LOAD_EVENT          0x0A
 | |
| #define DELETE_FILE_EVENT        0x0B
 | |
| #define NEW_LOAD_EVENT           0x0C
 | |
| #define RAND_EVENT               0x0D
 | |
| #define USER_VAR_EVENT           0x0E
 | |
| #define FORMAT_DESCRIPTION_EVENT 0x0F
 | |
| #define XID_EVENT                0x10
 | |
| #define BEGIN_LOAD_QUERY_EVENT   0x11
 | |
| #define EXECUTE_LOAD_QUERY_EVENT 0x12
 | |
| #define TABLE_MAP_EVENT          0x13
 | |
| #define WRITE_ROWS_EVENTv0       0x14
 | |
| #define UPDATE_ROWS_EVENTv0      0x15
 | |
| #define DELETE_ROWS_EVENTv0      0x16
 | |
| #define WRITE_ROWS_EVENTv1       0x17
 | |
| #define UPDATE_ROWS_EVENTv1      0x18
 | |
| #define DELETE_ROWS_EVENTv1      0x19
 | |
| #define INCIDENT_EVENT           0x1A
 | |
| #define HEARTBEAT_EVENT          0x1B
 | |
| #define IGNORABLE_EVENT          0x1C
 | |
| #define ROWS_QUERY_EVENT         0x1D
 | |
| #define WRITE_ROWS_EVENTv2       0x1E
 | |
| #define UPDATE_ROWS_EVENTv2      0x1F
 | |
| #define DELETE_ROWS_EVENTv2      0x20
 | |
| #define GTID_EVENT               0x21
 | |
| #define ANONYMOUS_GTID_EVENT     0x22
 | |
| #define PREVIOUS_GTIDS_EVENT     0x23
 | |
| 
 | |
| #define MAX_EVENT_TYPE 0x23
 | |
| 
 | |
| /* New MariaDB event numbers start from 0xa0 */
 | |
| #define MARIADB_NEW_EVENTS_BEGIN    0xa0
 | |
| #define MARIADB_ANNOTATE_ROWS_EVENT 0xa0
 | |
| /* New MariaDB 10 event numbers start from here */
 | |
| #define MARIADB10_BINLOG_CHECKPOINT_EVENT 0xa1
 | |
| #define MARIADB10_GTID_EVENT              0xa2
 | |
| #define MARIADB10_GTID_GTID_LIST_EVENT    0xa3
 | |
| #define MARIADB10_START_ENCRYPTION_EVENT  0xa4
 | |
| 
 | |
| #define MAX_EVENT_TYPE_MARIADB10 0xa4
 | |
| 
 | |
| /* Maximum event type so far */
 | |
| #define MAX_EVENT_TYPE_END MAX_EVENT_TYPE_MARIADB10
 | |
| 
 | |
| /**
 | |
|  * Binlog event flags
 | |
|  */
 | |
| #define LOG_EVENT_BINLOG_IN_USE_F            0x0001
 | |
| #define LOG_EVENT_FORCED_ROTATE_F            0x0002
 | |
| #define LOG_EVENT_THREAD_SPECIFIC_F          0x0004
 | |
| #define LOG_EVENT_SUPPRESS_USE_F             0x0008
 | |
| #define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x0010
 | |
| #define LOG_EVENT_ARTIFICIAL_F               0x0020
 | |
| #define LOG_EVENT_RELAY_LOG_F                0x0040
 | |
| #define LOG_EVENT_IGNORABLE_F                0x0080
 | |
| #define LOG_EVENT_NO_FILTER_F                0x0100
 | |
| #define LOG_EVENT_MTS_ISOLATE_F              0x0200
 | |
| 
 | |
| /**
 | |
|  * Binlog COM_BINLOG_DUMP flags
 | |
|  */
 | |
| #define BLR_REQUEST_ANNOTATE_ROWS_EVENT 2
 | |
| 
 | |
| /** MaxScale generated events */
 | |
| typedef enum
 | |
| {
 | |
|     BLRM_IGNORABLE,         /*< Ignorable event */
 | |
|     BLRM_START_ENCRYPTION   /*< Start Encryption event */
 | |
| } generated_event_t;
 | |
| 
 | |
| /**
 | |
|  * How often to call the binlog status function (seconds)
 | |
|  */
 | |
| #define BLR_STATS_FREQ     60
 | |
| #define BLR_NSTATS_MINUTES 30
 | |
| 
 | |
| /**
 | |
|  * High and Low water marks for the slave dcb.
 | |
|  * These values can be overriden
 | |
|  * by the router options highwater and lowwater.
 | |
|  */
 | |
| #define DEF_LOW_WATER  "1000"
 | |
| #define DEF_HIGH_WATER "10000"
 | |
| 
 | |
| /**
 | |
|  * Default burst sizes for slave catchup
 | |
|  */
 | |
| #define DEF_SHORT_BURST "15"
 | |
| #define DEF_LONG_BURST  "500"
 | |
| #define DEF_BURST_SIZE  "1024000"           /* 1 Mb */
 | |
| 
 | |
| /**
 | |
|  * master reconnect backoff constants
 | |
|  * BLR_MASTER_BACKOFF_TIME      The increments of the back off time (seconds)
 | |
|  * BLR_MASTER_CONNECT_RETRY     The connect retry interval
 | |
|  * BLR_BLR_MASTER_RETRY_COUNT   Maximum value of retries
 | |
|  */
 | |
| #define BLR_MASTER_BACKOFF_TIME 10
 | |
| 
 | |
| #define BLR_MASTER_CONNECT_RETRY_VALUE 60
 | |
| #define BLR_MASTER_CONNECT_RETRY       "60"
 | |
| #define BLR_MASTER_RETRY_COUNT         "1000"
 | |
| 
 | |
| /* Default value for @@max_connections SQL var */
 | |
| #define BLR_DEFAULT_MAX_CONNS 151
 | |
| 
 | |
| /* max size for error message returned to client */
 | |
| #define BINLOG_ERROR_MSG_LEN 700
 | |
| 
 | |
| /* network latency extra wait tme for heartbeat check */
 | |
| #define BLR_NET_LATENCY_WAIT_TIME 1
 | |
| 
 | |
| /* default heartbeat interval in seconds */
 | |
| #define BLR_HEARTBEAT_DEFAULT_INTERVAL_VALUE 300
 | |
| #define BLR_HEARTBEAT_DEFAULT_INTERVAL       "300"
 | |
| 
 | |
| /* Max heartbeat interval in seconds */
 | |
| #define BLR_HEARTBEAT_MAX_INTERVAL 4294967
 | |
| 
 | |
| /* strings and numbers in SQL replies */
 | |
| #define BLR_TYPE_STRING 0xf
 | |
| #define BLR_TYPE_INT    0x03
 | |
| 
 | |
| /* string len for COM_STATISTICS output */
 | |
| #define BLRM_COM_STATISTICS_SIZE 1000
 | |
| 
 | |
| /* string len for strerror_r message */
 | |
| #define BLRM_STRERROR_R_MSG_SIZE 128
 | |
| 
 | |
| /* string len for task message name */
 | |
| #define BLRM_TASK_NAME_LEN 80
 | |
| 
 | |
| /* string len for temp binlog filename  */
 | |
| #define BLRM_BINLOG_NAME_STR_LEN 80
 | |
| 
 | |
| /* string len for temp binlog filename  */
 | |
| #define BLRM_SET_HEARTBEAT_QUERY_LEN 80
 | |
| 
 | |
| /* string len for master registration query  */
 | |
| #define BLRM_MASTER_REGITRATION_QUERY_LEN 255
 | |
| 
 | |
| /* Read Binlog position states */
 | |
| #define SLAVE_POS_READ_OK     0x00
 | |
| #define SLAVE_POS_READ_ERR    0xff
 | |
| #define SLAVE_POS_READ_UNSAFE 0xfe
 | |
| #define SLAVE_POS_BAD_FD      0xfd
 | |
| #define SLAVE_POS_BEYOND_EOF  0xfc
 | |
| 
 | |
| /* MariadDB 10 GTID event flags */
 | |
| #define MARIADB_FL_DDL        32
 | |
| #define MARIADB_FL_STANDALONE 1
 | |
| 
 | |
| /* Maxwell-related SQL queries */
 | |
| #define MYSQL_CONNECTOR_SERVER_VARS_QUERY \
 | |
|     "SELECT " \
 | |
|     "@@session.auto_increment_increment AS auto_increment_increment, " \
 | |
|     "@@character_set_client AS character_set_client, "                 \
 | |
|     "@@character_set_connection AS character_set_connection, "         \
 | |
|     "@@character_set_results AS character_set_results, "               \
 | |
|     "@@character_set_server AS character_set_server, "                 \
 | |
|     "@@init_connect AS init_connect, "                                 \
 | |
|     "@@interactive_timeout AS interactive_timeout, "                   \
 | |
|     "@@license AS license, "                                           \
 | |
|     "@@lower_case_table_names AS lower_case_table_names, "             \
 | |
|     "@@max_allowed_packet AS max_allowed_packet, "                     \
 | |
|     "@@net_buffer_length AS net_buffer_length, "                       \
 | |
|     "@@net_write_timeout AS net_write_timeout, "                       \
 | |
|     "@@query_cache_size AS query_cache_size, "                         \
 | |
|     "@@query_cache_type AS query_cache_type, "                         \
 | |
|     "@@sql_mode AS sql_mode, "                                         \
 | |
|     "@@system_time_zone AS system_time_zone, "                         \
 | |
|     "@@time_zone AS time_zone, "                                       \
 | |
|     "@@tx_isolation AS tx_isolation, "                                 \
 | |
|     "@@wait_timeout AS wait_timeout"
 | |
| 
 | |
| #define MYSQL_CONNECTOR_SQL_MODE_QUERY \
 | |
|     "SET sql_mode=" \
 | |
|     "'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'"
 | |
| 
 | |
| /* Saved credential file name's tail */
 | |
| static const char BLR_DBUSERS_DIR[] = "cache/users";
 | |
| static const char BLR_DBUSERS_FILE[] = "dbusers";
 | |
| 
 | |
| /**
 | |
|  * Some useful macros for examining the MySQL Response packets
 | |
|  */
 | |
| #define MYSQL_RESPONSE_OK(buf)  (*((uint8_t*)GWBUF_DATA(buf) + 4) == 0x00)
 | |
| #define MYSQL_RESPONSE_EOF(buf) (*((uint8_t*)GWBUF_DATA(buf) + 4) == 0xfe)
 | |
| #define MYSQL_RESPONSE_ERR(buf) (*((uint8_t*)GWBUF_DATA(buf) + 4) == 0xff)
 | |
| #define MYSQL_ERROR_CODE(buf)   ((uint8_t*)GWBUF_DATA(buf) + 5)
 | |
| #define MYSQL_ERROR_MSG(buf)    ((uint8_t*)GWBUF_DATA(buf) + 7)
 | |
| #define MYSQL_COMMAND(buf)      (*((uint8_t*)GWBUF_DATA(buf) + 4))
 | |
| 
 | |
| /** Possible states of an event sent by the master */
 | |
| enum blr_event_state
 | |
| {
 | |
|     BLR_EVENT_STARTED,  /*< The first packet of an event has been received */
 | |
|     BLR_EVENT_ONGOING,  /*< Other packets of a multi-packet event are being processed */
 | |
|     BLR_EVENT_DONE,     /*< The complete event was received */
 | |
| };
 | |
| 
 | |
| /** MariaDB GTID elements */
 | |
| typedef struct mariadb_gtid_elems
 | |
| {
 | |
|     uint32_t domain_id;     /*< The replication domain */
 | |
|     uint32_t server_id;     /*< The serverid */
 | |
|     uint64_t seq_no;        /*< The sequence number */
 | |
| } MARIADB_GTID_ELEMS;
 | |
| 
 | |
| /** MariaDB GTID info */
 | |
| typedef struct mariadb_gtid_info
 | |
| {
 | |
|     char               gtid[GTID_MAX_LEN + 1];          /** MariaDB 10.x GTID, string value */
 | |
|     char               binlog_name[BINLOG_FNAMELEN + 1];/** The binlog file */
 | |
|     uint64_t           start;                           /** The BEGIN pos: i.e the GTID event */
 | |
|     uint64_t           end;                             /** The next_pos in COMMIT event */
 | |
|     MARIADB_GTID_ELEMS gtid_elms;                       /** MariaDB 10.x GTID components */
 | |
| } MARIADB_GTID_INFO;
 | |
| 
 | |
| /* Master Server configuration struct */
 | |
| class MasterServerConfig
 | |
| {
 | |
| public:
 | |
|     std::string    host;
 | |
|     unsigned short port;
 | |
|     std::string    logfile;
 | |
|     uint64_t       pos;
 | |
|     uint64_t       safe_pos;
 | |
|     std::string    user;
 | |
|     std::string    password;
 | |
|     std::string    filestem;
 | |
|     /* SSL options */
 | |
|     std::string ssl_key;
 | |
|     std::string ssl_cert;
 | |
|     std::string ssl_ca;
 | |
|     int         ssl_enabled;
 | |
|     std::string ssl_version;
 | |
|     /* Connect options */
 | |
|     int heartbeat;
 | |
| };
 | |
| 
 | |
| /* Config struct for CHANGE MASTER TO */
 | |
| class ChangeMasterConfig
 | |
| {
 | |
| public:
 | |
|     ChangeMasterConfig()
 | |
|         : ChangeMasterConfig("")
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     ChangeMasterConfig(const char* name)
 | |
|         : connection_name(name)
 | |
|         , port(-1)
 | |
|         , ssl_enabled(false)
 | |
|         , heartbeat_period(BLR_HEARTBEAT_DEFAULT_INTERVAL_VALUE)
 | |
|         , connect_retry(BLR_MASTER_CONNECT_RETRY_VALUE)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     std::string connection_name;
 | |
|     std::string host;
 | |
|     int         port;
 | |
|     std::string binlog_file;
 | |
|     std::string binlog_pos;
 | |
|     std::string user;
 | |
|     std::string password;
 | |
|     /* SSL options */
 | |
|     std::string ssl_key;
 | |
|     std::string ssl_cert;
 | |
|     std::string ssl_ca;
 | |
|     bool        ssl_enabled;
 | |
|     std::string ssl_version;
 | |
|     /* MariaDB 10 GTID */
 | |
|     std::string use_mariadb10_gtid;
 | |
|     /* Connection options */
 | |
|     int heartbeat_period;
 | |
|     int connect_retry;
 | |
| };
 | |
| 
 | |
| struct ROUTER_INSTANCE;
 | |
| 
 | |
| /* Config struct for CHANGE MASTER TO options */
 | |
| class ChangeMasterOptions
 | |
| {
 | |
| public:
 | |
|     ChangeMasterOptions()
 | |
|         : heartbeat_period(BLR_HEARTBEAT_DEFAULT_INTERVAL)
 | |
|         , connect_retry(BLR_MASTER_CONNECT_RETRY)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     ChangeMasterOptions(const std::string& s)
 | |
|         : connection_name(s)
 | |
|         , heartbeat_period(BLR_HEARTBEAT_DEFAULT_INTERVAL)
 | |
|         , connect_retry(BLR_MASTER_CONNECT_RETRY)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     void set_defaults(const ChangeMasterConfig& config)
 | |
|     {
 | |
|         host = config.host;
 | |
|         port = std::to_string(config.port);
 | |
|         binlog_file = config.binlog_file;
 | |
|         user = config.user;
 | |
|         password = config.password;
 | |
|         ssl_key = config.ssl_key;
 | |
|         ssl_cert = config.ssl_cert;
 | |
|         ssl_ca = config.ssl_ca;
 | |
|         ssl_enabled = config.ssl_enabled ? "1" : "0";
 | |
|         use_mariadb10_gtid = config.use_mariadb10_gtid;
 | |
|         heartbeat_period = std::to_string(config.heartbeat_period);
 | |
|         connect_retry = std::to_string(config.connect_retry);
 | |
|     }
 | |
| 
 | |
|     std::string connection_name;
 | |
|     std::string host;
 | |
|     std::string port;
 | |
|     std::string binlog_file;
 | |
|     std::string binlog_pos;
 | |
|     std::string user;
 | |
|     std::string password;
 | |
|     /* SSL options */
 | |
|     std::string ssl_key;
 | |
|     std::string ssl_cert;
 | |
|     std::string ssl_ca;
 | |
|     std::string ssl_enabled;
 | |
|     std::string ssl_version;
 | |
|     /* MariaDB 10 GTID */
 | |
|     std::string use_mariadb10_gtid;
 | |
|     /* Connection options */
 | |
|     std::string heartbeat_period;
 | |
|     std::string connect_retry;
 | |
| 
 | |
|     bool validate(ROUTER_INSTANCE* router,
 | |
|                   char* error,
 | |
|                   ChangeMasterConfig* config);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Packet header for replication messages
 | |
|  */
 | |
| typedef struct rep_header
 | |
| {
 | |
|     int      payload_len;   /*< Payload length (24 bits) */
 | |
|     uint8_t  seqno;         /*< Response sequence number */
 | |
|     uint8_t  ok;            /*< OK Byte from packet */
 | |
|     uint32_t timestamp;     /*< Timestamp - start of binlog record */
 | |
|     uint8_t  event_type;    /*< Binlog event type */
 | |
|     uint32_t serverid;      /*< Server id of master */
 | |
|     uint32_t event_size;    /*< Size of header, post-header and body */
 | |
|     uint32_t next_pos;      /*< Position of next event */
 | |
|     uint16_t flags;         /*< Event flags */
 | |
| } REP_HEADER;
 | |
| 
 | |
| /**
 | |
|  * The binlog record structure. This contains the actual packet read from the binlog
 | |
|  * file.
 | |
|  */
 | |
| typedef struct
 | |
| {
 | |
|     unsigned long position;         /*< binlog record position for this cache entry */
 | |
|     GWBUF*        pkt;              /*< The packet received from the master */
 | |
|     REP_HEADER    hdr;              /*< The packet header */
 | |
| } BLCACHE_RECORD;
 | |
| 
 | |
| /**
 | |
|  * The binlog cache. A cache exists for each file that hold cached bin log records.
 | |
|  * Caches will be used for all files being read by more than 1 slave.
 | |
|  */
 | |
| typedef struct
 | |
| {
 | |
|     BLCACHE_RECORD**        records;/*< The actual binlog records */
 | |
|     int                     current;/*< The next record that will be inserted */
 | |
|     int                     cnt;    /*< The number of records in the cache */
 | |
|     mutable pthread_mutex_t lock;   /*< The spinlock for the cache */
 | |
| } BLCACHE;
 | |
| 
 | |
| typedef struct blfile
 | |
| {
 | |
|     char binlog_name[BINLOG_FNAMELEN + 1];
 | |
|     /*< Name of the binlog file */
 | |
|     int                     fd;         /*< Actual file descriptor */
 | |
|     int                     refcnt;     /*< Reference count for file */
 | |
|     BLCACHE*                cache;      /*< Record cache for this file */
 | |
|     mutable pthread_mutex_t lock;       /*< The file lock */
 | |
|     MARIADB_GTID_ELEMS      gtid_elms;  /*< Elements for file prefix */
 | |
|     struct blfile*          next;       /*< Next file in list */
 | |
| } BLFILE;
 | |
| 
 | |
| /**
 | |
|  * Slave statistics
 | |
|  */
 | |
| typedef struct
 | |
| {
 | |
|     int           n_events;         /*< Number of events sent */
 | |
|     unsigned long n_bytes;          /*< Number of bytes sent */
 | |
|     int           n_bursts;         /*< Number of bursts sent */
 | |
|     int           n_requests;       /*< Number of requests received */
 | |
|     int           n_flows;          /*< Number of flow control restarts */
 | |
|     int           n_queries;        /*< Number of SQL queries */
 | |
|     int           n_upd;
 | |
|     int           n_cb;
 | |
|     int           n_cbna;
 | |
|     int           n_dcb;
 | |
|     int           n_above;
 | |
|     int           n_failed_read;
 | |
|     int           n_overrun;
 | |
|     int           n_caughtup;
 | |
|     int           n_actions[3];
 | |
|     uint64_t      lastsample;
 | |
|     int           minno;
 | |
|     int           minavgs[BLR_NSTATS_MINUTES];
 | |
| } SLAVE_STATS;
 | |
| 
 | |
| typedef enum blr_thread_role
 | |
| {
 | |
|     BLR_THREAD_ROLE_MASTER_LARGE_NOTRX,
 | |
|     BLR_THREAD_ROLE_MASTER_NOTRX,
 | |
|     BLR_THREAD_ROLE_MASTER_TRX,
 | |
|     BLR_THREAD_ROLE_SLAVE
 | |
| } blr_thread_role_t;
 | |
| 
 | |
| #define ROLETOSTR(r) \
 | |
|     r == BLR_THREAD_ROLE_MASTER_LARGE_NOTRX ? "master (large event, no trx)"   \
 | |
|                                             : r == BLR_THREAD_ROLE_MASTER_NOTRX ? "master (no trx)"   \
 | |
|                                                                                 : r \
 | |
|     == BLR_THREAD_ROLE_MASTER_TRX ? "master (trx)" : "slave"
 | |
| 
 | |
| /**
 | |
|  * Binlog encryption context of slave binlog file
 | |
|  */
 | |
| 
 | |
| typedef struct slave_encryption_ctx
 | |
| {
 | |
|     uint8_t  binlog_crypto_scheme;  /**< Encryption scheme */
 | |
|     uint32_t binlog_key_version;    /**< Encryption key version */
 | |
|     uint8_t  nonce[AES_BLOCK_SIZE]; /**< nonce (random bytes) of current binlog.
 | |
|                                     *   These bytes + the binlog event current pos
 | |
|                                     *   form the encrryption IV for the event */
 | |
|     char*    log_file;              /**< The log file the client has requested */
 | |
|     uint32_t first_enc_event_pos;   /**< The position of first encrypted event
 | |
|                                      *   It's the first event afte Start_encryption_event
 | |
|                                      *   which is after FDE */
 | |
| } SLAVE_ENCRYPTION_CTX;
 | |
| 
 | |
| /**
 | |
|  * The client session structure used within this router. This represents
 | |
|  * the slaves that are replicating binlogs from MaxScale.
 | |
|  */
 | |
| typedef struct router_slave
 | |
| {
 | |
|     DCB*     dcb;               /*< The slave server DCB */
 | |
|     int      state;             /*< The state of this slave */
 | |
|     uint32_t binlog_pos;        /*< Binlog position for this slave */
 | |
|     char     binlog_name[BINLOG_FNAMELEN + 1];
 | |
|     /*< Current binlog file for this slave */
 | |
|     char* uuid;             /*< Slave UUID */
 | |
| #ifdef BLFILE_IN_SLAVE
 | |
|     BLFILE* file;           /*< Currently open binlog file */
 | |
| #endif
 | |
|     int      serverid;              /*< Server-id of the slave */
 | |
|     char*    hostname;              /*< Hostname of the slave, if known */
 | |
|     char*    user;                  /*< Username if given */
 | |
|     char*    passwd;                /*< Password if given */
 | |
|     short    port;                  /*< MySQL port */
 | |
|     int      nocrc;                 /*< Disable CRC */
 | |
|     int      overrun;
 | |
|     uint32_t rank;              /*< Replication rank */
 | |
|     uint8_t  seqno;             /*< Replication dump sequence no */
 | |
|     uint32_t lastEventTimestamp;
 | |
|     /*< Last event timestamp sent */
 | |
|     mutable pthread_mutex_t catch_lock;         /*< Event catchup lock */
 | |
|     unsigned int            cstate;             /*< Catch up state */
 | |
|     bool                    mariadb10_compat;   /*< MariaDB 10.0 compatibility */
 | |
|     mutable pthread_mutex_t rses_lock;          /*< Protects rses_deleted */
 | |
|     pthread_t               pthread;
 | |
|     ROUTER_INSTANCE*        router; /*< Pointer to the owning router */
 | |
|     struct router_slave*    next;
 | |
|     SLAVE_STATS             stats;          /*< Slave statistics */
 | |
|     time_t                  connect_time;   /*< Connect time of slave */
 | |
|     char*                   warning_msg;    /*< Warning message */
 | |
|     int                     heartbeat;      /*< Heartbeat in seconds */
 | |
|     uint8_t                 lastEventReceived;
 | |
|     /*< Last event received */
 | |
|     time_t lastReply;       /*< Last event sent */
 | |
|     /*< lsi: Last Sent Information */
 | |
|     blr_thread_role_t lsi_sender_role;
 | |
|     /*< Master or slave code sent */
 | |
|     std::thread::id lsi_sender_tid;
 | |
|     /*< Who sent */
 | |
|     char lsi_binlog_name[BINLOG_FNAMELEN + 1];
 | |
|     /*< Which binlog file */
 | |
|     uint32_t lsi_binlog_pos;
 | |
|     /*< What position */
 | |
|     SLAVE_ENCRYPTION_CTX* encryption_ctx;
 | |
|     /*< Encryption context */
 | |
|     bool gtid_strict_mode;
 | |
|     /*< MariaDB 10 Slave sets gtid_strict_mode */
 | |
|     char*             mariadb_gtid;     /*< MariaDB 10 Slave connects with GTID */
 | |
|     sqlite3*          gtid_maps;        /*< GTID storage client handle, read only*/
 | |
|     MARIADB_GTID_INFO f_info;           /*< GTID info for file name prefix */
 | |
|     bool              annotate_rows;    /*< MariaDB 10 Slave requests ANNOTATE_ROWS */
 | |
| } ROUTER_SLAVE;
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * The statistics for this router instance
 | |
|  */
 | |
| typedef struct
 | |
| {
 | |
|     int      n_slaves;          /*< Number slave sessions created     */
 | |
|     int      n_reads;           /*< Number of record reads */
 | |
|     uint64_t n_binlogs;         /*< Number of binlog records from master */
 | |
|     uint64_t n_binlogs_ses;     /*< Number of binlog records from master */
 | |
|     uint64_t n_binlog_errors;   /*< Number of binlog records from master */
 | |
|     uint64_t n_rotates;         /*< Number of binlog rotate events */
 | |
|     uint64_t n_cachehits;       /*< Number of hits on the binlog cache */
 | |
|     uint64_t n_cachemisses;     /*< Number of misses on the binlog cache */
 | |
|     int      n_registered;      /*< Number of registered slaves */
 | |
|     int      n_masterstarts;    /*< Number of times connection restarted */
 | |
|     int      n_delayedreconnects;
 | |
|     int      n_residuals;           /*< Number of times residual data was buffered */
 | |
|     int      n_heartbeats;          /*< Number of heartbeat messages */
 | |
|     time_t   lastReply;
 | |
|     uint64_t n_fakeevents;                  /*< Fake events not written to disk */
 | |
|     uint64_t n_artificial;                  /*< Artificial events not written to disk */
 | |
|     int      n_badcrc;                      /*< No. of bad CRC's from master */
 | |
|     uint64_t events[MAX_EVENT_TYPE_END + 1];/*< Per event counters */
 | |
|     uint64_t lastsample;
 | |
|     int      minno;
 | |
|     int      minavgs[BLR_NSTATS_MINUTES];
 | |
| } ROUTER_STATS;
 | |
| 
 | |
| /**
 | |
|  * Saved responses from the master that will be forwarded to slaves
 | |
|  */
 | |
| typedef struct
 | |
| {
 | |
|     GWBUF* server_id;           /*< Master server id */
 | |
|     GWBUF* heartbeat;           /*< Heartbeat period */
 | |
|     GWBUF* chksum1;             /*< Binlog checksum 1st response */
 | |
|     GWBUF* chksum2;             /*< Binlog checksum 2nd response */
 | |
|     GWBUF* gtid_mode;           /*< GTID Mode response */
 | |
|     GWBUF* uuid;                /*< Master UUID */
 | |
|     GWBUF* setslaveuuid;        /*< Set Slave UUID */
 | |
|     GWBUF* setnames;            /*< Set NAMES latin1 */
 | |
|     GWBUF* utf8;                /*< Set NAMES utf8 */
 | |
|     GWBUF* select1;             /*< select 1 */
 | |
|     GWBUF* selectver;           /*< select version() */
 | |
|     GWBUF* selectvercom;        /*< select @@version_comment */
 | |
|     GWBUF* selecthostname;      /*< select @@hostname */
 | |
|     GWBUF* map;                 /*< select @@max_allowed_packet */
 | |
|     GWBUF* mariadb10;           /*< set @mariadb_slave_capability */
 | |
|     GWBUF* server_vars;         /*< MySQL Connector master server variables */
 | |
|     GWBUF* binlog_vars;         /*< SELECT @@global.log_bin,
 | |
|                                  *  @@global.binlog_format,
 | |
|                                  *  @@global.binlog_row_image;
 | |
|                                  */
 | |
|     GWBUF* lower_case_tables;   /*< select @@lower_case_table_names */
 | |
| } MASTER_RESPONSES;
 | |
| 
 | |
| /**
 | |
|  * The binlog encryption setup
 | |
|  */
 | |
| typedef struct binlog_encryption_setup
 | |
| {
 | |
|     bool          enabled;
 | |
|     int           encryption_algorithm;
 | |
|     char*         key_management_filename;
 | |
|     uint8_t       key_value[BINLOG_AES_MAX_KEY_LEN];
 | |
|     unsigned long key_len;
 | |
|     uint8_t       key_id;
 | |
| } BINLOG_ENCRYPTION_SETUP;
 | |
| 
 | |
| /** Transaction States */
 | |
| typedef enum
 | |
| {
 | |
|     BLRM_NO_TRANSACTION,        /*< No transaction */
 | |
|     BLRM_TRANSACTION_START,     /*< A transaction is open*/
 | |
|     BLRM_COMMIT_SEEN,           /*< Received COMMIT event in the current trx */
 | |
|     BLRM_XID_EVENT_SEEN,        /*< Received XID event of current transaction */
 | |
|     BLRM_STANDALONE_SEEN        /*< Received a standalone event, ie: a DDL */
 | |
| } master_transaction_t;
 | |
| 
 | |
| /** Transaction Details */
 | |
| typedef struct pending_transaction
 | |
| {
 | |
|     char                 gtid[GTID_MAX_LEN + 1];/*< MariaDB 10.x GTID */
 | |
|     master_transaction_t state;                 /*< Transaction state */
 | |
|     uint64_t             start_pos;             /*< The BEGIN pos */
 | |
|     uint64_t             end_pos;               /*< The next_pos in COMMIT event */
 | |
|     MARIADB_GTID_ELEMS   gtid_elms;             /*< MariaDB 10.x GTID components */
 | |
|     bool                 standalone;            /*< Standalone event, such as DDL
 | |
|                                                  *  no terminating COMMIT
 | |
|                                                  */
 | |
| } PENDING_TRANSACTION;
 | |
| 
 | |
| /**
 | |
|  * Binlog encryption context of binlog file
 | |
|  */
 | |
| 
 | |
| typedef struct binlog_encryption_ctx
 | |
| {
 | |
|     uint8_t  binlog_crypto_scheme;  /**< Encryption scheme */
 | |
|     uint32_t binlog_key_version;    /**< Encryption key version */
 | |
|     uint8_t  nonce[AES_BLOCK_SIZE]; /**< nonce (random bytes) of current binlog.
 | |
|                                     *   These bytes + the binlog event current pos
 | |
|                                     *   form the encrryption IV for the event */
 | |
|     char* binlog_file;              /**< Current binlog file being encrypted */
 | |
| } BINLOG_ENCRYPTION_CTX;
 | |
| 
 | |
| /**
 | |
|  * The per instance data for the router.
 | |
|  */
 | |
| struct ROUTER_INSTANCE : public MXS_ROUTER
 | |
| {
 | |
|     SERVICE*                service;        /*< Pointer to the service using this router */
 | |
|     ROUTER_SLAVE*           slaves;         /*< Link list of all the slave connections  */
 | |
|     mutable pthread_mutex_t lock;           /*< Spinlock for the instance data */
 | |
|     char*                   uuid;           /*< UUID for the router to use w/master */
 | |
|     int                     orig_masterid;  /*< Server ID of the master, internally used */
 | |
|     int                     masterid;       /*< Set ID of the master, sent to slaves */
 | |
|     int                     serverid;       /*< ID for the router to use w/master */
 | |
|     int                     initbinlog;     /*< Initial binlog file number */
 | |
|     char*                   user;           /*< User name to use with master */
 | |
|     char*                   password;       /*< Password to use with master */
 | |
|     char*                   fileroot;       /*< Root of binlog filename */
 | |
|     bool                    master_chksum;  /*< Does the master provide checksums */
 | |
|     bool                    mariadb10_compat;
 | |
|     /*< MariaDB 10.0 compatibility */
 | |
|     bool         maxwell_compat;/*< Zendesk's Maxwell compatibility */
 | |
|     char*        master_uuid;   /*< Set UUID of the master, sent to slaves */
 | |
|     DCB*         master;        /*< DCB for master connection */
 | |
|     DCB*         client;        /*< DCB for dummy client */
 | |
|     MXS_SESSION* session;       /*< Fake session for master connection */
 | |
|     unsigned int master_state;  /*< State of the master FSM */
 | |
|     uint8_t      lastEventReceived;
 | |
|     /*< Last event received */
 | |
|     uint32_t lastEventTimestamp;
 | |
|     /*< Timestamp from last event */
 | |
|     MASTER_RESPONSES        saved_master;   /*< Saved master responses */
 | |
|     char*                   binlogdir;      /*< The directory with the binlog files */
 | |
|     mutable pthread_mutex_t binlog_lock;    /*< Lock to control update of the binlog position */
 | |
|     int                     trx_safe;       /*< Detect and handle partial transactions */
 | |
|     PENDING_TRANSACTION     pending_transaction;
 | |
|     /*< Pending transaction */
 | |
|     enum blr_event_state master_event_state;
 | |
|     /*< Packet read state */
 | |
|     REP_HEADER stored_header;
 | |
|     /*< Replication header of the event the master is sending */
 | |
|     GWBUF*   stored_event;      /*< Buffer where partial events are stored */
 | |
|     uint64_t last_safe_pos;     /* last committed transaction */
 | |
|     char     binlog_name[BINLOG_FNAMELEN + 1];
 | |
|     /*< Name of the current binlog file */
 | |
|     uint64_t binlog_position;   /*< last committed transaction position */
 | |
|     uint64_t current_pos;       /*< Current binlog position */
 | |
|     int      binlog_fd;         /*< File descriptor of the binlog
 | |
|                                  *  file being written
 | |
|                                  */
 | |
|     uint64_t last_written;      /*< Position of the last write operation */
 | |
|     uint64_t last_event_pos;    /*< Position of last event written */
 | |
|     uint64_t current_safe_event;
 | |
|     /*< Position of the latest safe event being sent to slaves */
 | |
|     char                    prevbinlog[BINLOG_FNAMELEN + 1];
 | |
|     int                     rotating;   /*< Rotation in progress flag */
 | |
|     BLFILE*                 files;      /*< Files used by the slaves */
 | |
|     mutable pthread_mutex_t fileslock;  /*< Lock for the files queue above */
 | |
|     unsigned int            short_burst;/*< Short burst for slave catchup */
 | |
|     unsigned int            long_burst; /*< Long burst for slave catchup */
 | |
|     unsigned long           burst_size; /*< Maximum size of burst to send */
 | |
|     unsigned long           heartbeat;  /*< Configured heartbeat value */
 | |
|     ROUTER_STATS            stats;      /*< Statistics for this router */
 | |
|     int                     active_logs;
 | |
|     int                     reconnect_pending;
 | |
|     int                     retry_interval; /*< Connect retry interval */
 | |
|     int                     retry_count;    /*< Connect retry counter */
 | |
|     int                     retry_limit;    /*< Retry limit */
 | |
|     time_t                  connect_time;
 | |
|     int                     handling_threads;
 | |
|     unsigned long           m_errno;                /*< master response mysql errno */
 | |
|     char*                   m_errmsg;               /*< master response mysql error message */
 | |
|     char*                   set_master_version;     /*< Send custom Version to slaves */
 | |
|     char*                   set_master_hostname;    /*< Send custom Hostname to slaves */
 | |
|     bool                    set_master_uuid;        /*< Send custom Master UUID to slaves */
 | |
|     bool                    set_master_server_id;   /*< Send custom Master server_id to slaves */
 | |
|     int                     send_slave_heartbeat;   /*< Enable sending heartbeat to slaves */
 | |
|     bool                    ssl_enabled;            /*< Use SSL connection to master */
 | |
|     int                     ssl_cert_verification_depth;
 | |
|     /*< The maximum length of the certificate
 | |
|      * authority chain that will be accepted.
 | |
|      */
 | |
|     char*                   ssl_key;            /*< config Certificate Key for Master SSL connection */
 | |
|     char*                   ssl_ca;             /*< config CA Certificate for Master SSL connection */
 | |
|     char*                   ssl_cert;           /*< config Certificate for Master SSL connection */
 | |
|     char*                   ssl_version;        /*< config TLS Version for Master SSL connection */
 | |
|     bool                    request_semi_sync;  /*< Request Semi-Sync replication to master */
 | |
|     int                     master_semi_sync;   /*< Semi-Sync replication status of master server */
 | |
|     BINLOG_ENCRYPTION_SETUP encryption;         /*< Binlog encryption setup */
 | |
|     BINLOG_ENCRYPTION_CTX*  encryption_ctx;     /*< Encryption context */
 | |
|     char                    last_mariadb_gtid[GTID_MAX_LEN + 1];
 | |
|     /*< Last seen MariaDB 10 GTID */
 | |
|     bool mariadb10_gtid;                                    /*< Save received MariaDB GTIDs into repo.
 | |
|                                                              * This allows MariaDB 10 slave servers
 | |
|                                                              * connecting with GTID
 | |
|                                                              */
 | |
|     bool mariadb10_master_gtid;                             /*< Enables MariaDB 10 GTID registration
 | |
|                                                              * to MariaDB 10.0/10.1 Master
 | |
|                                                              */
 | |
|     uint32_t                        mariadb10_gtid_domain;  /*< MariaDB 10 GTID Domain ID */
 | |
|     sqlite3*                        gtid_maps;              /*< MariaDB 10 GTID storage */
 | |
|     enum binlog_storage_type        storage_type;           /*< Enables hierachical binlog file storage */
 | |
|     char*                           set_slave_hostname;     /*< Send custom Hostname to Master */
 | |
|     ROUTER_INSTANCE*                next;
 | |
|     std::vector<ChangeMasterConfig> configs;        /*< Available configs. */
 | |
|     int                             config_index;   /*< The index of the config currently being used. */
 | |
| };
 | |
| 
 | |
| /** Master Semi-Sync capability */
 | |
| typedef enum
 | |
| {
 | |
|     MASTER_SEMISYNC_NOT_AVAILABLE,  /*< Semi-Sync replication not available */
 | |
|     MASTER_SEMISYNC_DISABLED,       /*< Semi-Sync is disabled */
 | |
|     MASTER_SEMISYNC_ENABLED         /*< Semi-Sync is enabled */
 | |
| } master_semisync_capability_t;
 | |
| 
 | |
| /**
 | |
|  * Holds information about:
 | |
|  * truncating a corrupted file
 | |
|  * or replace an event at specified pos
 | |
|  * or replace a transaction that start
 | |
|  * at specified pos
 | |
|  */
 | |
| 
 | |
| typedef struct binlog_pos_fix
 | |
| {
 | |
|     bool     fix;       /**< Truncate file to last safe pos */
 | |
|     uint64_t pos;       /**< Position of the event to be replaced
 | |
|                          *   by an Ignorable Event
 | |
|                          */
 | |
|     bool replace_trx;   /**< Replace all events belonging to
 | |
|                          *   a transaction starting at pos
 | |
|                          */
 | |
| } BINLOG_FILE_FIX;
 | |
| 
 | |
| /**
 | |
|  * Defines and offsets for binlog encryption
 | |
|  *
 | |
|  * BLRM_FDE_EVENT_TYPES_OFFSET is the offset
 | |
|  * in FDE event content that points to
 | |
|  * the number of events the master server supports.
 | |
|  */
 | |
| #define BLR_FDE_EVENT_BINLOG_VERSION       2
 | |
| #define BLR_FDE_EVENT_SERVER_VERSION       50
 | |
| #define BLR_FDE_EVENT_BINLOG_TIME          4
 | |
| #define BLR_FDE_EVENT_BINLOG_EVENT_HDR_LEN 1
 | |
| #define BLRM_FDE_EVENT_TYPES_OFFSET \
 | |
|     (BLR_FDE_EVENT_BINLOG_VERSION   \
 | |
|      + BLR_FDE_EVENT_SERVER_VERSION   \
 | |
|      + BLR_FDE_EVENT_BINLOG_TIME   \
 | |
|      + BLR_FDE_EVENT_BINLOG_EVENT_HDR_LEN)
 | |
| #define BLRM_CRYPTO_SCHEME_LENGTH 1
 | |
| #define BLRM_KEY_VERSION_LENGTH   4
 | |
| #define BLRM_IV_LENGTH            AES_BLOCK_SIZE
 | |
| #define BLRM_IV_OFFS_LENGTH       4
 | |
| #define BLRM_NONCE_LENGTH         (BLRM_IV_LENGTH - BLRM_IV_OFFS_LENGTH)
 | |
| 
 | |
| /**
 | |
|  * State machine for the master to MaxScale replication
 | |
|  */
 | |
| #define BLRM_UNCONFIGURED           0x0000
 | |
| #define BLRM_UNCONNECTED            0x0001
 | |
| #define BLRM_CONNECTING             0x0002
 | |
| #define BLRM_AUTHENTICATED          0x0003
 | |
| #define BLRM_TIMESTAMP              0x0004
 | |
| #define BLRM_SERVERID               0x0005
 | |
| #define BLRM_HBPERIOD               0x0006
 | |
| #define BLRM_CHKSUM1                0x0007
 | |
| #define BLRM_CHKSUM2                0x0008
 | |
| #define BLRM_MARIADB10              0x0009
 | |
| #define BLRM_MARIADB10_GTID_DOMAIN  0x000A
 | |
| #define BLRM_MARIADB10_REQUEST_GTID 0x000B
 | |
| #define BLRM_MARIADB10_GTID_STRICT  0x000C
 | |
| #define BLRM_MARIADB10_GTID_NO_DUP  0x000D
 | |
| #define BLRM_GTIDMODE               0x000E
 | |
| #define BLRM_MUUID                  0x000F
 | |
| #define BLRM_SUUID                  0x0010
 | |
| #define BLRM_LATIN1                 0x0011
 | |
| #define BLRM_UTF8                   0x0012
 | |
| #define BLRM_RESULTS_CHARSET        0x0013
 | |
| #define BLRM_SQL_MODE               0x0014
 | |
| #define BLRM_SELECT1                0x0015
 | |
| #define BLRM_SELECTVER              0x0016
 | |
| #define BLRM_SELECTVERCOM           0x0017
 | |
| #define BLRM_SELECTHOSTNAME         0x0018
 | |
| #define BLRM_MAP                    0x0019
 | |
| #define BLRM_SERVER_VARS            0x001A
 | |
| #define BLRM_BINLOG_VARS            0x001B
 | |
| #define BLRM_LOWER_CASE_TABLES      0x001C
 | |
| #define BLRM_REGISTER_READY         0x001D
 | |
| #define BLRM_REGISTER               0x001E
 | |
| #define BLRM_CHECK_SEMISYNC         0x001F
 | |
| #define BLRM_REQUEST_SEMISYNC       0x0020
 | |
| #define BLRM_REQUEST_BINLOGDUMP     0x0021
 | |
| #define BLRM_BINLOGDUMP             0x0022
 | |
| #define BLRM_SLAVE_STOPPED          0x0023
 | |
| 
 | |
| #define BLRM_MAXSTATE 0x0023
 | |
| 
 | |
| static const char* blrm_states[] =
 | |
| {
 | |
|     "Unconfigured",
 | |
|     "Unconnected",
 | |
|     "Connecting",
 | |
|     "Authenticated",
 | |
|     "Timestamp retrieval",
 | |
|     "Server ID retrieval",
 | |
|     "HeartBeat Period setup",
 | |
|     "binlog checksum config",
 | |
|     "binlog checksum rerieval",
 | |
|     "Set MariaDB10 slave capability",
 | |
|     "MariaDB10 GTID Domain retrieval",
 | |
|     "Set MariaDB10 GTID Request",
 | |
|     "Set MariaDB10 GTID strict mode",
 | |
|     "Set MariaDB10 GTID ignore duplicates",
 | |
|     "GTID Mode retrieval",
 | |
|     "Master UUID retrieval",
 | |
|     "Set Slave UUID",
 | |
|     "Set Names latin1",
 | |
|     "Set Names utf8",
 | |
|     "Set results charset null",
 | |
|     "Set sql_mode",
 | |
|     "select 1",
 | |
|     "select version()",
 | |
|     "select @@version_comment",
 | |
|     "select @@hostname",
 | |
|     "select @@max_allowed_packet",
 | |
|     "Query server variables",
 | |
|     "Query binlog variables",
 | |
|     "Query @@lower_case_table_names",
 | |
|     "Ready to Register",
 | |
|     "Register slave",
 | |
|     "Semi-Sync Support retrivial",
 | |
|     "Request Semi-Sync Replication",
 | |
|     "Request Binlog Dump",
 | |
|     "Binlog Dump",
 | |
|     "Slave stopped"
 | |
| };
 | |
| 
 | |
| #define BLRS_CREATED      0x0000
 | |
| #define BLRS_UNREGISTERED 0x0001
 | |
| #define BLRS_REGISTERED   0x0002
 | |
| #define BLRS_DUMPING      0x0003
 | |
| #define BLRS_ERRORED      0x0004
 | |
| 
 | |
| #define BLRS_MAXSTATE 0x0004
 | |
| 
 | |
| static const char* blrs_states[] =
 | |
| {
 | |
|     "Created",
 | |
|     "Unregistered",
 | |
|     "Registered",
 | |
|     "Sending binlogs",
 | |
|     "Errored"
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Slave catch-up status
 | |
|  */
 | |
| #define CS_UNDEFINED 0x0000
 | |
| #define CS_EXPECTCB  0x0004
 | |
| #define CS_WAIT_DATA 0x0020
 | |
| #define CS_BUSY      0x0040
 | |
| 
 | |
| /**
 | |
|  * MySQL protocol OpCodes needed for replication
 | |
|  */
 | |
| #define COM_QUIT           0x01
 | |
| #define COM_QUERY          0x03
 | |
| #define COM_STATISTICS     0x09
 | |
| #define COM_PING           0x0e
 | |
| #define COM_REGISTER_SLAVE 0x15
 | |
| #define COM_BINLOG_DUMP    0x12
 | |
| 
 | |
| /**
 | |
|  * Macros to extract common fields
 | |
|  */
 | |
| #define INLINE_EXTRACT 1                /* Set to 0 for debug purposes */
 | |
| 
 | |
| #if INLINE_EXTRACT
 | |
| #define EXTRACT16(x) (*(uint8_t*)(x) | (*((uint8_t*)(x) + 1) << 8))
 | |
| #define EXTRACT24(x) \
 | |
|     (*(uint8_t*)(x)                \
 | |
|      | (*((uint8_t*)(x) + 1) << 8)   \
 | |
|      | (*((uint8_t*)(x) + 2) << 16))
 | |
| #define EXTRACT32(x) \
 | |
|     (*(uint8_t*)(x)                        \
 | |
|      | (*((uint8_t*)(x) + 1) << 8)           \
 | |
|      | (*((uint8_t*)(x) + 2) << 16)          \
 | |
|      | (*((uint8_t*)(x) + 3) << 24))
 | |
| #else
 | |
| #define EXTRACT16(x) extract_field((x), 16)
 | |
| #define EXTRACT24(x) extract_field((x), 24)
 | |
| #define EXTRACT32(x) extract_field((x), 32)
 | |
| #endif
 | |
| 
 | |
| #define MASTER_BYTES_BEFORE_EVENT           5
 | |
| #define MASTER_BYTES_BEFORE_EVENT_SEMI_SYNC MASTER_BYTES_BEFORE_EVENT + 2
 | |
| /* Semi-Sync indicator in network packet (byte 6) */
 | |
| #define BLR_MASTER_SEMI_SYNC_INDICATOR 0xef
 | |
| /* Semi-Sync flag ACK_REQ in network packet (byte 7) */
 | |
| #define BLR_MASTER_SEMI_SYNC_ACK_REQ 0x01
 | |
| 
 | |
| /*
 | |
|  * Externals within the router
 | |
|  */
 | |
| extern void blr_log_disabled_heartbeat(const ROUTER_INSTANCE* inst);
 | |
| extern void blr_master_response(ROUTER_INSTANCE*, GWBUF*);
 | |
| extern void blr_master_reconnect(ROUTER_INSTANCE*);
 | |
| extern int  blr_master_connected(ROUTER_INSTANCE*);
 | |
| extern void blr_master_set_config(ROUTER_INSTANCE*, const ChangeMasterConfig& config);
 | |
| 
 | |
| extern int blr_slave_request(ROUTER_INSTANCE*,
 | |
|                              ROUTER_SLAVE*,
 | |
|                              GWBUF*);
 | |
| extern void blr_slave_rotate(ROUTER_INSTANCE*,
 | |
|                              ROUTER_SLAVE*,
 | |
|                              uint8_t*);
 | |
| extern int blr_slave_catchup(ROUTER_INSTANCE* router,
 | |
|                              ROUTER_SLAVE* slave,
 | |
|                              bool large);
 | |
| extern void blr_init_cache(ROUTER_INSTANCE*);
 | |
| 
 | |
| extern int blr_file_init(ROUTER_INSTANCE*);
 | |
| extern int blr_write_binlog_record(ROUTER_INSTANCE*,
 | |
|                                    REP_HEADER*,
 | |
|                                    uint32_t pos,
 | |
|                                    uint8_t*);
 | |
| extern int blr_file_rotate(ROUTER_INSTANCE*,
 | |
|                            char*,
 | |
|                            uint64_t);
 | |
| extern int     blr_file_read_master_config(ROUTER_INSTANCE* router);
 | |
| extern int     blr_file_write_master_config(ROUTER_INSTANCE* router, char* error);
 | |
| extern void    blr_file_flush(ROUTER_INSTANCE*);
 | |
| extern BLFILE* blr_open_binlog(ROUTER_INSTANCE*,
 | |
|                                const char*,
 | |
|                                const MARIADB_GTID_INFO*);
 | |
| extern GWBUF* blr_read_binlog(ROUTER_INSTANCE*,
 | |
|                               BLFILE*,
 | |
|                               unsigned long,
 | |
|                               REP_HEADER*,
 | |
|                               char*,
 | |
|                               const SLAVE_ENCRYPTION_CTX*);
 | |
| extern void          blr_close_binlog(ROUTER_INSTANCE*, BLFILE*);
 | |
| extern unsigned long blr_file_size(BLFILE*);
 | |
| extern int           blr_statistics(ROUTER_INSTANCE*, ROUTER_SLAVE*, GWBUF*);
 | |
| extern int           blr_ping(ROUTER_INSTANCE*, ROUTER_SLAVE*, GWBUF*);
 | |
| extern int           blr_send_custom_error(DCB*,
 | |
|                                            int,
 | |
|                                            int,
 | |
|                                            const char*,
 | |
|                                            const char*,
 | |
|                                            unsigned int);
 | |
| extern int blr_file_next_exists(ROUTER_INSTANCE*,
 | |
|                                 ROUTER_SLAVE*,
 | |
|                                 char* next_file);
 | |
| uint32_t    extract_field(uint8_t* src, int bits);
 | |
| void        blr_cache_read_master_data(ROUTER_INSTANCE* router);
 | |
| int         blr_read_events_all_events(ROUTER_INSTANCE*, BINLOG_FILE_FIX*, int);
 | |
| int         blr_save_dbusers(const ROUTER_INSTANCE* router);
 | |
| const char* blr_get_event_description(ROUTER_INSTANCE* router, uint8_t event);
 | |
| void        blr_file_append(ROUTER_INSTANCE* router, char* file);
 | |
| void        blr_cache_response(ROUTER_INSTANCE* router, char* response, GWBUF* buf);
 | |
| const char* blr_last_event_description(ROUTER_INSTANCE* router);
 | |
| void        blr_free_ssl_data(ROUTER_INSTANCE* inst);
 | |
| 
 | |
| extern bool blr_send_event(blr_thread_role_t role,
 | |
|                            const char* binlog_name,
 | |
|                            uint32_t binlog_pos,
 | |
|                            ROUTER_SLAVE* slave,
 | |
|                            REP_HEADER*   hdr,
 | |
|                            uint8_t* buf);
 | |
| 
 | |
| extern const char* blr_get_encryption_algorithm(int);
 | |
| extern int         blr_check_encryption_algorithm(const char*);
 | |
| extern const char* blr_encryption_algorithm_list(void);
 | |
| extern bool        blr_get_encryption_key(ROUTER_INSTANCE*);
 | |
| extern void        blr_set_checksum(ROUTER_INSTANCE* instance, GWBUF* buf);
 | |
| extern const char* blr_skip_leading_sql_comments(const char*);
 | |
| extern bool        blr_fetch_mariadb_gtid(ROUTER_SLAVE*,
 | |
|                                           const char*,
 | |
|                                           MARIADB_GTID_INFO*);
 | |
| extern bool blr_start_master_in_main(ROUTER_INSTANCE* data, int32_t delay = 0);
 | |
| extern bool blr_binlog_file_exists(ROUTER_INSTANCE* router,
 | |
|                                    const MARIADB_GTID_INFO* info_file);
 | |
| 
 | |
| // Functions used by blr_handle_one_event
 | |
| int  blr_rotate_event(ROUTER_INSTANCE* router, uint8_t* ptr, REP_HEADER* hdr);
 | |
| int  blr_send_semisync_ack(ROUTER_INSTANCE* router, uint64_t pos);
 | |
| bool blr_handle_fake_rotate(ROUTER_INSTANCE* router, REP_HEADER* hdr, uint8_t* ptr);
 | |
| void blr_handle_fake_gtid_list(ROUTER_INSTANCE* router, REP_HEADER* hdr, uint8_t* ptr);
 | |
| void blr_master_close(ROUTER_INSTANCE*);
 | |
| void blr_notify_all_slaves(ROUTER_INSTANCE* router);
 | |
| bool blr_save_mariadb_gtid(ROUTER_INSTANCE* inst);
 | |
| 
 | |
| /**
 | |
|  * Handler for binlog events
 | |
|  *
 | |
|  * This function is called for each event replicated from the master.
 | |
|  *
 | |
|  * @param instance Router instance
 | |
|  * @param hdr      Event header
 | |
|  * @param ptr      Event data
 | |
|  * @param len      Buffer length
 | |
|  * @param semisync 1 if semisync is enabled (TODO: change this)
 | |
|  *
 | |
|  * @return True if event was successfully processed, false if an error occurred
 | |
|  *         and the processing should be stopped.
 | |
|  */
 | |
| bool blr_handle_one_event(MXS_ROUTER* instance,
 | |
|                           REP_HEADER& hdr,
 | |
|                           uint8_t* ptr,
 | |
|                           uint32_t len,
 | |
|                           int semi_sync_send_ack);
 | |
| 
 | |
| #endif
 | 
