214 lines
5.6 KiB
C
214 lines
5.6 KiB
C
/*
|
|
* 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: 2019-07-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.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <binlog_common.h>
|
|
#include <blr_constants.h>
|
|
#include <maxscale/log_manager.h>
|
|
|
|
/**
|
|
* @file binlog_common.c - Common binary log code shared between multiple modules
|
|
*
|
|
* This file contains functions that are common to multiple modules that all
|
|
* handle MySQL/MariaDB binlog files.
|
|
*
|
|
* @verbatim
|
|
* Revision History
|
|
*
|
|
* Date Who Description
|
|
* 7/3/16 Markus Makela Initial implementation
|
|
*
|
|
* @endverbatim
|
|
*/
|
|
|
|
/**
|
|
* Get the next binlog file name.
|
|
*
|
|
* @param router The router instance
|
|
* @return 0 on error, >0 as sequence number
|
|
*/
|
|
int blr_file_get_next_binlogname(const char *binlog_name)
|
|
{
|
|
char *sptr;
|
|
int filenum;
|
|
|
|
if ((sptr = strrchr(binlog_name, '.')) == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
filenum = atoi(sptr + 1);
|
|
if (filenum)
|
|
{
|
|
filenum++;
|
|
}
|
|
|
|
return filenum;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the next binlog file exists and is readable
|
|
* @param binlogdir Directory where the binlogs are
|
|
* @param binlog Current binlog name
|
|
* @return True if next binlog file exists and is readable
|
|
*/
|
|
bool binlog_next_file_exists(const char* binlogdir, const char* binlog)
|
|
{
|
|
bool rval = false;
|
|
int filenum = blr_file_get_next_binlogname(binlog);
|
|
|
|
if (filenum)
|
|
{
|
|
char *sptr = strrchr(binlog, '.');
|
|
|
|
if (sptr)
|
|
{
|
|
char buf[BLRM_BINLOG_NAME_STR_LEN + 1];
|
|
char filename[PATH_MAX + 1];
|
|
char next_file[BLRM_BINLOG_NAME_STR_LEN + 1];
|
|
int offset = sptr - binlog;
|
|
memcpy(buf, binlog, offset);
|
|
buf[offset] = '\0';
|
|
sprintf(next_file, BINLOG_NAMEFMT, buf, filenum);
|
|
snprintf(filename, PATH_MAX, "%s/%s", binlogdir, next_file);
|
|
filename[PATH_MAX] = '\0';
|
|
|
|
/* Next file in sequence doesn't exist */
|
|
if (access(filename, R_OK) == -1)
|
|
{
|
|
MXS_DEBUG("File '%s' does not yet exist.", filename);
|
|
}
|
|
else
|
|
{
|
|
rval = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return rval;
|
|
}
|
|
|
|
/**
|
|
* Extract a numeric field from a packet of the specified number of bits
|
|
*
|
|
* @param src The raw packet source
|
|
* @param birs The number of bits to extract (multiple of 8)
|
|
*/
|
|
uint32_t extract_field(uint8_t *src, int bits)
|
|
{
|
|
uint32_t rval = 0, shift = 0;
|
|
|
|
while (bits > 0)
|
|
{
|
|
rval |= (*src++) << shift;
|
|
shift += 8;
|
|
bits -= 8;
|
|
}
|
|
return rval;
|
|
}
|
|
|
|
/**
|
|
* Convert binlog event type to string
|
|
* @param type Event type
|
|
* @return Event type in string format
|
|
*/
|
|
const char* binlog_event_name(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case START_EVENT_V3:
|
|
return "START_EVENT_V3";
|
|
case QUERY_EVENT:
|
|
return "QUERY_EVENT";
|
|
case STOP_EVENT:
|
|
return "STOP_EVENT";
|
|
case ROTATE_EVENT:
|
|
return "ROTATE_EVENT";
|
|
case INTVAR_EVENT:
|
|
return "INTVAR_EVENT";
|
|
case LOAD_EVENT:
|
|
return "LOAD_EVENT";
|
|
case SLAVE_EVENT:
|
|
return "SLAVE_EVENT";
|
|
case CREATE_FILE_EVENT:
|
|
return "CREATE_FILE_EVENT";
|
|
case APPEND_BLOCK_EVENT:
|
|
return "APPEND_BLOCK_EVENT";
|
|
case EXEC_LOAD_EVENT:
|
|
return "EXEC_LOAD_EVENT";
|
|
case DELETE_FILE_EVENT:
|
|
return "DELETE_FILE_EVENT";
|
|
case NEW_LOAD_EVENT:
|
|
return "NEW_LOAD_EVENT";
|
|
case RAND_EVENT:
|
|
return "RAND_EVENT";
|
|
case USER_VAR_EVENT:
|
|
return "USER_VAR_EVENT";
|
|
case FORMAT_DESCRIPTION_EVENT:
|
|
return "FORMAT_DESCRIPTION_EVENT";
|
|
case XID_EVENT:
|
|
return "XID_EVENT";
|
|
case BEGIN_LOAD_QUERY_EVENT:
|
|
return "BEGIN_LOAD_QUERY_EVENT";
|
|
case EXECUTE_LOAD_QUERY_EVENT:
|
|
return "EXECUTE_LOAD_QUERY_EVENT";
|
|
case TABLE_MAP_EVENT:
|
|
return "TABLE_MAP_EVENT";
|
|
case WRITE_ROWS_EVENTv0:
|
|
return "WRITE_ROWS_EVENTv0";
|
|
case UPDATE_ROWS_EVENTv0:
|
|
return "UPDATE_ROWS_EVENTv0";
|
|
case DELETE_ROWS_EVENTv0:
|
|
return "DELETE_ROWS_EVENTv0";
|
|
case WRITE_ROWS_EVENTv1:
|
|
return "WRITE_ROWS_EVENTv1";
|
|
case UPDATE_ROWS_EVENTv1:
|
|
return "UPDATE_ROWS_EVENTv1";
|
|
case DELETE_ROWS_EVENTv1:
|
|
return "DELETE_ROWS_EVENTv1";
|
|
case INCIDENT_EVENT:
|
|
return "INCIDENT_EVENT";
|
|
case HEARTBEAT_EVENT:
|
|
return "HEARTBEAT_EVENT";
|
|
case IGNORABLE_EVENT:
|
|
return "IGNORABLE_EVENT";
|
|
case ROWS_QUERY_EVENT:
|
|
return "ROWS_QUERY_EVENT";
|
|
case WRITE_ROWS_EVENTv2:
|
|
return "WRITE_ROWS_EVENTv2";
|
|
case UPDATE_ROWS_EVENTv2:
|
|
return "UPDATE_ROWS_EVENTv2";
|
|
case DELETE_ROWS_EVENTv2:
|
|
return "DELETE_ROWS_EVENTv2";
|
|
case GTID_EVENT:
|
|
return "GTID_EVENT";
|
|
case ANONYMOUS_GTID_EVENT:
|
|
return "ANONYMOUS_GTID_EVENT";
|
|
case PREVIOUS_GTIDS_EVENT:
|
|
return "PREVIOUS_GTIDS_EVENT";
|
|
case MARIADB_ANNOTATE_ROWS_EVENT:
|
|
return "MARIADB_ANNOTATE_ROWS_EVENT";
|
|
case MARIADB10_BINLOG_CHECKPOINT_EVENT:
|
|
return "MARIADB10_BINLOG_CHECKPOINT_EVENT";
|
|
case MARIADB10_GTID_EVENT:
|
|
return "MARIADB10_GTID_EVENT";
|
|
case MARIADB10_GTID_GTID_LIST_EVENT:
|
|
return "MARIADB10_GTID_GTID_LIST_EVENT";
|
|
default:
|
|
return "UNKNOWN_EVENT";
|
|
}
|
|
}
|