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:
MassimilianoPinto
2016-09-19 17:43:47 +02:00
parent 695fed4912
commit 883c581d25
3 changed files with 142 additions and 17 deletions

View File

@ -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;

View File

@ -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
*/

View File

@ -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;
}