Addition of START_ENCRYPTION_EVENT
Addition of START_ENCRYPTION_EVENT when encrypt_binlog=1 in Binlog Server option. Event is not sent to any slave. MaxBinlogCheck understands the new event added in MariaDB 10.1.7: the number of events = 164 as reported by FormatDescriptionEvent
This commit is contained in:
@ -37,6 +37,7 @@
|
||||
* State CS_UPTODATE removed.
|
||||
* 01/09/2016 Massimiliano Pinto Added support for ANNOTATE_ROWS_EVENT in COM_BINLOG_DUMP
|
||||
* 16/09/2016 Massimiliano Pinto Addition of MARIADB10_START_ENCRYPTION_EVENT 0xa4
|
||||
* 19/09/2016 Massimiliano Pinto Added encrypt_binlog=0|1 option
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -538,6 +539,7 @@ typedef struct router_instance
|
||||
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 */
|
||||
int encrypt_binlog; /*< Encrypt binlog files */
|
||||
struct router_instance *next;
|
||||
} ROUTER_INSTANCE;
|
||||
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
* 22/07/2016 Massimiliano Pinto Added semi_sync replication support
|
||||
* 24/08/2016 Massimiliano Pinto Added slave notification via CS_WAIT_DATA new state
|
||||
* 16/08/2016 Massimiliano Pinto Addition of Start Encription Event description
|
||||
* 19/08/2016 Massimiliano Pinto Addition of encrypt_binlog option
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -294,6 +295,7 @@ createInstance(SERVICE *service, char **options)
|
||||
/* Semi-Sync support */
|
||||
inst->request_semi_sync = false;
|
||||
inst->master_semi_sync = 0;
|
||||
inst->encrypt_binlog = 0;
|
||||
|
||||
/* Generate UUID for the router instance */
|
||||
uuid_generate_time(defuuid);
|
||||
@ -429,6 +431,10 @@ createInstance(SERVICE *service, char **options)
|
||||
{
|
||||
inst->request_semi_sync = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "encrypt_binlog") == 0)
|
||||
{
|
||||
inst->encrypt_binlog = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "lowwater") == 0)
|
||||
{
|
||||
inst->low_water = atoi(value);
|
||||
@ -791,13 +797,20 @@ createInstance(SERVICE *service, char **options)
|
||||
snprintf(task_name, BLRM_TASK_NAME_LEN, "%s stats", service->name);
|
||||
hktask_add(task_name, stats_func, inst, BLR_STATS_FREQ);
|
||||
|
||||
/* Log whether the transaction safety option value is on*/
|
||||
/* Log whether the transaction safety option value is on */
|
||||
if (inst->trx_safe)
|
||||
{
|
||||
MXS_INFO("%s: Service has transaction safety option set to ON",
|
||||
service->name);
|
||||
}
|
||||
|
||||
/* Log whether the binlog encryption option value is on */
|
||||
if (inst->encrypt_binlog)
|
||||
{
|
||||
MXS_INFO("%s: Service has binlog encryption set to ON",
|
||||
service->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether replication can be started
|
||||
*/
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
* 11/07/2016 Massimiliano Pinto Added SSL backend support
|
||||
* 16/09/2016 Massimiliano Pinto Addition of IGNORABLE_EVENT in case of a missing event
|
||||
* detected from master binlog stream
|
||||
* 19/09/2016 Massimiliano Pinto Addition of START_ENCRYPTION_EVENT: new event is written
|
||||
* when encrypt_binlog=1 in Binlog Server option.
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -94,6 +96,9 @@ static int blr_write_special_event(ROUTER_INSTANCE *router,
|
||||
uint32_t hole_size,
|
||||
REP_HEADER *hdr,
|
||||
int type);
|
||||
static uint8_t *blr_create_start_encryption_event(ROUTER_INSTANCE *router,
|
||||
uint32_t event_pos,
|
||||
bool do_checksum);
|
||||
|
||||
/** MaxScale generated events */
|
||||
typedef enum
|
||||
@ -383,10 +388,17 @@ int
|
||||
blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size, uint8_t *buf)
|
||||
{
|
||||
int n;
|
||||
bool write_begin_encryption = false;
|
||||
uint64_t file_offset = router->current_pos;
|
||||
|
||||
/* Track whether FORMAT_DESCRIPTION_EVENT has been received */
|
||||
if (hdr->event_type == FORMAT_DESCRIPTION_EVENT)
|
||||
{
|
||||
write_begin_encryption = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for possible hole looking at curren pos and next pos
|
||||
* Check first for possible hole looking at current pos and next pos
|
||||
* Fill the gap with a self generated ignorable event
|
||||
* Binlog file position is incremented by blr_write_special_event()
|
||||
*/
|
||||
@ -400,7 +412,7 @@ blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size,
|
||||
}
|
||||
}
|
||||
|
||||
/* Write current received event form master */
|
||||
/* Write current received event from master */
|
||||
if ((n = pwrite(router->binlog_fd, buf, size,
|
||||
router->last_written)) != size)
|
||||
{
|
||||
@ -428,6 +440,18 @@ blr_write_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint32_t size,
|
||||
router->last_event_pos = hdr->next_pos - hdr->event_size;
|
||||
spinlock_release(&router->binlog_lock);
|
||||
|
||||
/* Check whether adding the Start Encryption event into current binlog */
|
||||
if (router->encrypt_binlog && write_begin_encryption)
|
||||
{
|
||||
uint64_t event_size = router->master_chksum ? 40 : 36;
|
||||
uint64_t file_offset = router->current_pos;
|
||||
if (!blr_write_special_event(router, file_offset, event_size, hdr, BLRM_START_ENCRYPTION))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_begin_encryption = false;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -1464,23 +1488,26 @@ blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug)
|
||||
event_header_length = ptr[2 + 50 + 4];
|
||||
event_header_ntypes = hdr.event_size - event_header_length - (2 + 50 + 4 + 1);
|
||||
|
||||
if (event_header_ntypes == 168)
|
||||
/* mariadb >= 10.1.7 LOG_EVENT_TYPES*/
|
||||
if (event_header_ntypes == 169)
|
||||
{
|
||||
/* mariadb 10 LOG_EVENT_TYPES*/
|
||||
event_header_ntypes -= 164;
|
||||
}
|
||||
else if (event_header_ntypes == 168)
|
||||
{
|
||||
/* mariadb 10 LOG_EVENT_TYPES*/
|
||||
event_header_ntypes -= 163;
|
||||
}
|
||||
else if (event_header_ntypes == 165)
|
||||
{
|
||||
/* mariadb 5 LOG_EVENT_TYPES*/
|
||||
event_header_ntypes -= 160;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event_header_ntypes == 165)
|
||||
{
|
||||
/* mariadb 5 LOG_EVENT_TYPES*/
|
||||
event_header_ntypes -= 160;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* mysql 5.6 LOG_EVENT_TYPES = 35 */
|
||||
event_header_ntypes -= 35;
|
||||
}
|
||||
/* mysql 5.6 LOG_EVENT_TYPES = 35 */
|
||||
event_header_ntypes -= 35;
|
||||
}
|
||||
|
||||
n_events = hdr.event_size - event_header_length - (2 + 50 + 4 + 1);
|
||||
@ -2082,7 +2109,7 @@ blr_print_binlog_details(ROUTER_INSTANCE *router,
|
||||
/** Create an ignorable event
|
||||
*
|
||||
* @param event_size The size of the new event being created (crc32 4 bytes could be included)
|
||||
* @param hdr Current replication event header, received form master
|
||||
* @param hdr Current replication event header, received from master
|
||||
* @param event_pos The position in binlog file of the new event
|
||||
* @param do_checksum Whether checksum must be calculated and stored
|
||||
* @return Returns the pointer of new event
|
||||
@ -2137,13 +2164,14 @@ blr_create_ignorable_event(uint32_t event_size,
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and write a special event (not received form master) into binlog file
|
||||
* Create and write a special event (not received from master) into binlog file
|
||||
*
|
||||
* @param router The current router instance
|
||||
* @param file_offset Position where event will be written
|
||||
* @param event_size The size of new event (it might hold the 4 bytes crc32)
|
||||
* @param hdr Replication header of the current reived event (from Master)
|
||||
* @param type Type of special event to create and write
|
||||
* @return 1 on success, 0 on error
|
||||
*/
|
||||
static int
|
||||
blr_write_special_event(ROUTER_INSTANCE *router, uint32_t file_offset, uint32_t event_size, REP_HEADER *hdr, int type)
|
||||
@ -2164,7 +2192,7 @@ blr_write_special_event(ROUTER_INSTANCE *router, uint32_t file_offset, uint32_t
|
||||
(unsigned long)event_size,
|
||||
(unsigned long)file_offset);
|
||||
|
||||
/* Create new Ignorable event */
|
||||
/* Create the new Ignorable event */
|
||||
if ((new_event = blr_create_ignorable_event(event_size,
|
||||
hdr,
|
||||
file_offset,
|
||||
@ -2173,6 +2201,24 @@ blr_write_special_event(ROUTER_INSTANCE *router, uint32_t file_offset, uint32_t
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case BLRM_START_ENCRYPTION:
|
||||
new_event_desc = "MARIADB10_START_ENCRYPTION";
|
||||
MXS_INFO("New event %s is being added in binlog '%s' @ %lu: "
|
||||
"%lu bytes will be written at pos %lu",
|
||||
new_event_desc,
|
||||
router->binlog_name,
|
||||
router->current_pos,
|
||||
(unsigned long)event_size,
|
||||
(unsigned long)file_offset);
|
||||
|
||||
/* Create the MARIADB10_START_ENCRYPTION event */
|
||||
if ((new_event = blr_create_start_encryption_event(router,
|
||||
file_offset,
|
||||
router->master_chksum)) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
new_event_desc = "UNKNOWN";
|
||||
MXS_ERROR("Cannot create special binlog event of %s type and size %lu "
|
||||
@ -2224,3 +2270,67 @@ blr_write_special_event(ROUTER_INSTANCE *router, uint32_t file_offset, uint32_t
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Create the START_ENCRYPTION_EVENT
|
||||
*
|
||||
* This is a New Event added in MariaDB 10.1.7
|
||||
* Type is 0xa4 and size 36 (crc32 not included)
|
||||
*
|
||||
* @param hdr Current replication event header, received from master
|
||||
* @param event_pos The position in binlog file of the new event
|
||||
* @param do_checksum Whether checksum must be calculated and stored
|
||||
* @return Returns the pointer of new event
|
||||
*/
|
||||
|
||||
uint8_t *
|
||||
blr_create_start_encryption_event(ROUTER_INSTANCE *router, uint32_t event_pos, bool do_checksum)
|
||||
{
|
||||
uint8_t *new_event;
|
||||
uint8_t event_size = 36;
|
||||
if (do_checksum)
|
||||
{
|
||||
event_size += 4;
|
||||
}
|
||||
|
||||
new_event= MXS_CALLOC(1, event_size);
|
||||
if (new_event == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Populate Event header 19 bytes
|
||||
encode_value(&new_event[0], time(NULL), 32); // now
|
||||
new_event[4] = MARIADB10_START_ENCRYPTION_EVENT; // type is BEGIN_ENCRYPTION_EVENT
|
||||
encode_value(&new_event[5], router->serverid, 32); // serverid of maxscale
|
||||
encode_value(&new_event[9], event_size, 32); // event size
|
||||
encode_value(&new_event[13], event_pos + event_size, 32); // next_pos
|
||||
encode_value(&new_event[17], LOG_EVENT_IGNORABLE_F, 16); // flag is LOG_EVENT_IGNORABLE_F OR 0 ?
|
||||
|
||||
/* Event conten */
|
||||
// set schema
|
||||
new_event[19] = 1;
|
||||
// key version
|
||||
encode_value(&new_event[20], 1, 32);
|
||||
// nonce
|
||||
gw_generate_random_str((char *)&new_event[24], 12);
|
||||
|
||||
/* if checksum is requred add the crc32 */
|
||||
if (do_checksum)
|
||||
{
|
||||
/*
|
||||
* Now add the CRC to the Ignorable binlog event.
|
||||
*
|
||||
* The algorithm is first to compute the checksum of an empty buffer
|
||||
* and then the checksum of the event.
|
||||
*/
|
||||
uint32_t chksum;
|
||||
chksum = crc32(0L, NULL, 0);
|
||||
chksum = crc32(chksum, new_event, event_size - 4);
|
||||
|
||||
// checksum is stored at the end of current event data: 4 less bytes than event size
|
||||
encode_value(new_event + event_size - 4, chksum, 32);
|
||||
}
|
||||
|
||||
return new_event;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user