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: 2020-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.
 | 
						|
 */
 | 
						|
 | 
						|
#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";
 | 
						|
    }
 | 
						|
}
 |