MXS-1266: Standalone events in transaction (no COMMIT event) are now handled
Standalone events in transaction (no COMMIT event) are now handled: the GTID is saved to gtid_maps storage. Transaction detection assumes there is only one query_event after GTID event with MARIADB_FL_STANDALONE flag set.
This commit is contained in:
@ -543,7 +543,8 @@ typedef enum
|
|||||||
BLRM_NO_TRANSACTION, /*< No transaction */
|
BLRM_NO_TRANSACTION, /*< No transaction */
|
||||||
BLRM_TRANSACTION_START, /*< A transaction is open*/
|
BLRM_TRANSACTION_START, /*< A transaction is open*/
|
||||||
BLRM_COMMIT_SEEN, /*< Received COMMIT event in the current trx */
|
BLRM_COMMIT_SEEN, /*< Received COMMIT event in the current trx */
|
||||||
BLRM_XID_EVENT_SEEN /*< Received XID event of current transaction */
|
BLRM_XID_EVENT_SEEN, /*< Received XID event of current transaction */
|
||||||
|
BLRM_STANDALONE_SEEN /*< Received a standalone event, ie: a DDL */
|
||||||
} master_transaction_t;
|
} master_transaction_t;
|
||||||
|
|
||||||
/** MariaDB GTID elements */
|
/** MariaDB GTID elements */
|
||||||
@ -562,6 +563,8 @@ typedef struct pending_transaction
|
|||||||
uint64_t start_pos; /** The BEGIN pos */
|
uint64_t start_pos; /** The BEGIN pos */
|
||||||
uint64_t end_pos; /** The next_pos in COMMIT event*/
|
uint64_t end_pos; /** The next_pos in COMMIT event*/
|
||||||
MARIADB_GTID_ELEMS gtid_elms; /* MariaDB 10.x GTID components */
|
MARIADB_GTID_ELEMS gtid_elms; /* MariaDB 10.x GTID components */
|
||||||
|
bool standalone; /** Standalone event, such as DDL
|
||||||
|
* no terminating COMMIT */
|
||||||
} PENDING_TRANSACTION;
|
} PENDING_TRANSACTION;
|
||||||
|
|
||||||
/** MariaDB GTID info */
|
/** MariaDB GTID info */
|
||||||
|
|||||||
@ -2051,8 +2051,13 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
domainid = extract_field(ptr + 8, 32);
|
domainid = extract_field(ptr + 8, 32);
|
||||||
flags = *(ptr + 8 + 4);
|
flags = *(ptr + 8 + 4);
|
||||||
|
|
||||||
if ((flags & (MARIADB_FL_DDL | MARIADB_FL_STANDALONE)) == 0)
|
/**
|
||||||
{
|
* Detect whether it's a standalone transaction:
|
||||||
|
* there is no terminating COMMIT event.
|
||||||
|
* i.e: a DDL or FLUSH TABLES etc
|
||||||
|
*/
|
||||||
|
router->pending_transaction.standalone = flags & MARIADB_FL_STANDALONE;
|
||||||
|
|
||||||
if (pending_transaction > BLRM_NO_TRANSACTION)
|
if (pending_transaction > BLRM_NO_TRANSACTION)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Transaction cannot be @ pos %llu: "
|
MXS_ERROR("Transaction cannot be @ pos %llu: "
|
||||||
@ -2102,7 +2107,6 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for GTID_LIST_EVENT
|
* Check for GTID_LIST_EVENT
|
||||||
@ -2179,6 +2183,7 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
*
|
*
|
||||||
* Check for BEGIN ( ONLY for mysql 5.6, mariadb 5.5 )
|
* Check for BEGIN ( ONLY for mysql 5.6, mariadb 5.5 )
|
||||||
* Check for COMMIT (not transactional engines)
|
* Check for COMMIT (not transactional engines)
|
||||||
|
* Check for pending standalone transaction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hdr.event_type == QUERY_EVENT)
|
if (hdr.event_type == QUERY_EVENT)
|
||||||
@ -2238,11 +2243,33 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
|
|
||||||
if (!(debug & BLR_CHECK_ONLY))
|
if (!(debug & BLR_CHECK_ONLY))
|
||||||
{
|
{
|
||||||
MXS_DEBUG(" Transaction @ pos %llu, closing @ %llu",
|
MXS_DEBUG(" Transaction @ pos %llu,"
|
||||||
last_known_commit, pos);
|
" closing @ %llu",
|
||||||
|
last_known_commit,
|
||||||
|
pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If it's a standalone transaction event we're done:
|
||||||
|
* This query event, only one, terminates the
|
||||||
|
* transaction.
|
||||||
|
*/
|
||||||
|
if (pending_transaction > BLRM_NO_TRANSACTION &&
|
||||||
|
router->pending_transaction.standalone)
|
||||||
|
{
|
||||||
|
pending_transaction = BLRM_STANDALONE_SEEN;
|
||||||
|
|
||||||
|
if (!(debug & BLR_CHECK_ONLY))
|
||||||
|
{
|
||||||
|
MXS_DEBUG(" Standalone Transaction @ pos %llu,"
|
||||||
|
" closing @ %llu",
|
||||||
|
last_known_commit,
|
||||||
|
pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MXS_FREE(statement_sql);
|
MXS_FREE(statement_sql);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2263,8 +2290,10 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
|
|
||||||
if (!(debug & BLR_CHECK_ONLY))
|
if (!(debug & BLR_CHECK_ONLY))
|
||||||
{
|
{
|
||||||
MXS_DEBUG(" Transaction XID @ pos %llu, closing @ %llu",
|
MXS_DEBUG(" Transaction XID @ pos %llu,"
|
||||||
last_known_commit, pos);
|
" closing @ %llu",
|
||||||
|
last_known_commit,
|
||||||
|
pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2273,11 +2302,15 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
{
|
{
|
||||||
if (!(debug & BLR_CHECK_ONLY))
|
if (!(debug & BLR_CHECK_ONLY))
|
||||||
{
|
{
|
||||||
MXS_DEBUG("< Transaction @ pos %llu, is now closed @ %llu. %lu events seen",
|
MXS_DEBUG("< Transaction @ pos %llu, is now closed @ %llu."
|
||||||
last_known_commit, pos, transaction_events);
|
" %lu events seen",
|
||||||
|
last_known_commit,
|
||||||
|
pos,
|
||||||
|
transaction_events);
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_transaction = BLRM_NO_TRANSACTION;
|
pending_transaction = BLRM_NO_TRANSACTION;
|
||||||
|
router->pending_transaction.standalone = false;
|
||||||
|
|
||||||
router->pending_transaction.end_pos = hdr.next_pos;
|
router->pending_transaction.end_pos = hdr.next_pos;
|
||||||
|
|
||||||
@ -3485,7 +3518,6 @@ static int gtid_select_cb(void *data, int cols, char** values, char** names)
|
|||||||
* @param result The (allocated) ouput data to fill
|
* @param result The (allocated) ouput data to fill
|
||||||
* @return True if with found GTID or false
|
* @return True if with found GTID or false
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool blr_fetch_mariadb_gtid(ROUTER_SLAVE *slave,
|
bool blr_fetch_mariadb_gtid(ROUTER_SLAVE *slave,
|
||||||
const char *gtid,
|
const char *gtid,
|
||||||
MARIADB_GTID_INFO *result)
|
MARIADB_GTID_INFO *result)
|
||||||
|
|||||||
@ -1041,6 +1041,7 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
|
|||||||
|
|
||||||
if (router->trx_safe)
|
if (router->trx_safe)
|
||||||
{
|
{
|
||||||
|
// MariaDB 10 GTID event check
|
||||||
if (router->mariadb10_compat &&
|
if (router->mariadb10_compat &&
|
||||||
hdr.event_type == MARIADB10_GTID_EVENT)
|
hdr.event_type == MARIADB10_GTID_EVENT)
|
||||||
{
|
{
|
||||||
@ -1057,10 +1058,15 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
|
|||||||
domainid = extract_field(ptr + MYSQL_HEADER_LEN + 1 + BINLOG_EVENT_HDR_LEN + 8, 32);
|
domainid = extract_field(ptr + MYSQL_HEADER_LEN + 1 + BINLOG_EVENT_HDR_LEN + 8, 32);
|
||||||
flags = *(ptr + MYSQL_HEADER_LEN + 1 + BINLOG_EVENT_HDR_LEN + 8 + 4);
|
flags = *(ptr + MYSQL_HEADER_LEN + 1 + BINLOG_EVENT_HDR_LEN + 8 + 4);
|
||||||
|
|
||||||
if ((flags & (MARIADB_FL_DDL | MARIADB_FL_STANDALONE)) == 0)
|
|
||||||
{
|
|
||||||
spinlock_acquire(&router->binlog_lock);
|
spinlock_acquire(&router->binlog_lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect whether it's a standalone transaction:
|
||||||
|
* there is no terminating COMMIT event.
|
||||||
|
* i.e: a DDL or FLUSH TABLES etc
|
||||||
|
*/
|
||||||
|
router->pending_transaction.standalone = flags & MARIADB_FL_STANDALONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Now mark the new open transaction
|
* Now mark the new open transaction
|
||||||
*/
|
*/
|
||||||
@ -1106,8 +1112,8 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
|
|||||||
|
|
||||||
spinlock_release(&router->binlog_lock);
|
spinlock_release(&router->binlog_lock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// Query Event check
|
||||||
if (hdr.event_type == QUERY_EVENT)
|
if (hdr.event_type == QUERY_EVENT)
|
||||||
{
|
{
|
||||||
char *statement_sql;
|
char *statement_sql;
|
||||||
@ -1148,6 +1154,17 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
|
|||||||
{
|
{
|
||||||
router->pending_transaction.state = BLRM_COMMIT_SEEN;
|
router->pending_transaction.state = BLRM_COMMIT_SEEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If it's a standalone transaction event we're done:
|
||||||
|
* this query event, only one, terminates the transaction.
|
||||||
|
*/
|
||||||
|
if (router->pending_transaction.state > BLRM_NO_TRANSACTION &&
|
||||||
|
router->pending_transaction.standalone)
|
||||||
|
{
|
||||||
|
router->pending_transaction.state = BLRM_STANDALONE_SEEN;
|
||||||
|
}
|
||||||
|
|
||||||
spinlock_release(&router->binlog_lock);
|
spinlock_release(&router->binlog_lock);
|
||||||
|
|
||||||
MXS_FREE(statement_sql);
|
MXS_FREE(statement_sql);
|
||||||
@ -1326,7 +1343,10 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
|
|||||||
spinlock_acquire(&router->binlog_lock);
|
spinlock_acquire(&router->binlog_lock);
|
||||||
|
|
||||||
router->binlog_position = router->current_pos;
|
router->binlog_position = router->current_pos;
|
||||||
|
|
||||||
|
/* Set no pending transaction and no standalone */
|
||||||
router->pending_transaction.state = BLRM_NO_TRANSACTION;
|
router->pending_transaction.state = BLRM_NO_TRANSACTION;
|
||||||
|
router->pending_transaction.standalone = false;
|
||||||
|
|
||||||
spinlock_release(&router->binlog_lock);
|
spinlock_release(&router->binlog_lock);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6826,7 +6826,8 @@ static bool blr_handle_set_stmt(ROUTER_INSTANCE *router,
|
|||||||
MXS_ERROR("%s: Incomplete set command.", router->service->name);
|
MXS_ERROR("%s: Incomplete set command.", router->service->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((strcasecmp(word, "autocommit") == 0) || (strcasecmp(word, "@@session.autocommit") == 0))
|
else if ((strcasecmp(word, "autocommit") == 0) ||
|
||||||
|
(strcasecmp(word, "@@session.autocommit") == 0))
|
||||||
{
|
{
|
||||||
blr_slave_send_ok(router, slave);
|
blr_slave_send_ok(router, slave);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user