Skip to content

Commit c84e77c

Browse files
dtcpatriciodahlerlend
authored andcommitted
Bug#36313793 Use EpochContext object instead of variables [2/3]
Part of Bug36313793 ndb-log-apply-status fails to work with no replicated changes in BI. Instead of using separate variables to track the handling of events within the epoch, use an object that aggregates all these. Then, using this epoch context, a function is added to assess if the epoch is empty in light of the variables' value that reflect what happened in the epoch. Also gives the possibility to have it extended. Change-Id: I85e8b25cc3890786f97ed0f615287b3ab7e63765
1 parent ad281b3 commit c84e77c

File tree

2 files changed

+58
-42
lines changed

2 files changed

+58
-42
lines changed

storage/ndb/plugin/ha_ndbcluster_binlog.cc

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6198,16 +6198,14 @@ class injector_transaction : public injector::transaction {
61986198
/**
61996199
@brief Handle one data event received from NDB
62006200
6201-
@param pOp The NdbEventOperation that received data
6202-
@param trans The injector transaction
6203-
@param[out] trans_row_count Counter for rows in event
6204-
@param[out] replicated_row_count Counter for replicated rows in event
6201+
@param pOp The NdbEventOperation that received data
6202+
@param trans The injector transaction
6203+
@param[out] epoch_ctx Epoch context for accumulated counters
62056204
@return 0 for success, other values (normally -1) for error
62066205
*/
62076206
int Ndb_binlog_thread::handle_data_event(const NdbEventOperation *pOp,
62086207
injector_transaction &trans,
6209-
unsigned &trans_row_count,
6210-
unsigned &replicated_row_count) {
6208+
EpochContext &epoch_ctx) {
62116209
bool reflected_op = false;
62126210
bool refresh_op = false;
62136211
bool read_op = false;
@@ -6329,7 +6327,7 @@ int Ndb_binlog_thread::handle_data_event(const NdbEventOperation *pOp,
63296327
else {
63306328
assert(!reflected_op && !refresh_op);
63316329
/* Track that we received a replicated row event */
6332-
if (likely(count_this_event)) replicated_row_count++;
6330+
if (likely(count_this_event)) epoch_ctx.replicated_row_count++;
63336331

63346332
if (!log_this_slave_update) {
63356333
/*
@@ -6419,7 +6417,7 @@ int Ndb_binlog_thread::handle_data_event(const NdbEventOperation *pOp,
64196417
case NDBEVENT::TE_INSERT:
64206418
if (likely(count_this_event)) {
64216419
row.n_inserts++;
6422-
trans_row_count++;
6420+
epoch_ctx.trans_row_count++;
64236421
}
64246422
DBUG_PRINT("info", ("INSERT INTO %s.%s", table->s->db.str,
64256423
table->s->table_name.str));
@@ -6449,7 +6447,7 @@ int Ndb_binlog_thread::handle_data_event(const NdbEventOperation *pOp,
64496447
case NDBEVENT::TE_DELETE:
64506448
if (likely(count_this_event)) {
64516449
row.n_deletes++;
6452-
trans_row_count++;
6450+
epoch_ctx.trans_row_count++;
64536451
}
64546452
DBUG_PRINT("info", ("DELETE FROM %s.%s", table->s->db.str,
64556453
table->s->table_name.str));
@@ -6494,7 +6492,7 @@ int Ndb_binlog_thread::handle_data_event(const NdbEventOperation *pOp,
64946492
case NDBEVENT::TE_UPDATE:
64956493
if (likely(count_this_event)) {
64966494
row.n_updates++;
6497-
trans_row_count++;
6495+
epoch_ctx.trans_row_count++;
64986496
}
64996497
DBUG_PRINT("info",
65006498
("UPDATE %s.%s", table->s->db.str, table->s->table_name.str));
@@ -6703,7 +6701,7 @@ bool Ndb_binlog_thread::handle_events_for_epoch(THD *thd, injector *inj,
67036701
(uint)(ndb_latest_handled_binlog_epoch >> 32),
67046702
(uint)(ndb_latest_handled_binlog_epoch)));
67056703

6706-
commit_trans(trans, thd, current_epoch, 0, 0);
6704+
commit_trans(trans, thd, current_epoch, EpochContext{});
67076705
}
67086706

67096707
i_pOp = i_ndb->nextEvent2();
@@ -6743,15 +6741,13 @@ bool Ndb_binlog_thread::handle_events_for_epoch(THD *thd, injector *inj,
67436741
return false; // Error, failed to inject ndb_apply_status
67446742
}
67456743

6746-
unsigned trans_row_count = 0;
6747-
unsigned replicated_row_count = 0;
6744+
EpochContext epoch_ctx;
67486745
do {
67496746
assert(check_event_list_consistency(i_ndb, i_pOp));
67506747

67516748
const NdbDictionary::Event::TableEvent event_type = i_pOp->getEventType();
67526749
if (event_type < NDBEVENT::TE_FIRST_NON_DATA_EVENT) {
6753-
if (handle_data_event(i_pOp, trans, trans_row_count,
6754-
replicated_row_count) != 0) {
6750+
if (handle_data_event(i_pOp, trans, epoch_ctx) != 0) {
67556751
log_error("Failed to handle data event");
67566752
return false; // Error, failed to handle data event
67576753
}
@@ -6772,8 +6768,7 @@ bool Ndb_binlog_thread::handle_events_for_epoch(THD *thd, injector *inj,
67726768
or is == NULL
67736769
*/
67746770

6775-
commit_trans(trans, thd, current_epoch, trans_row_count,
6776-
replicated_row_count);
6771+
commit_trans(trans, thd, current_epoch, epoch_ctx);
67776772

67786773
return true; // OK
67796774
}
@@ -7066,30 +7061,32 @@ static Uint64 find_epoch_to_handle(const NdbEventOperation *s_pOp,
70667061
return ndb_latest_received_binlog_epoch;
70677062
}
70687063

7064+
bool Ndb_binlog_thread::EpochContext::is_empty_epoch() const {
7065+
DBUG_TRACE;
7066+
DBUG_PRINT("enter", ("trans_row_count: %d", trans_row_count));
7067+
DBUG_PRINT("enter", ("replicated_row_count: %d", replicated_row_count));
7068+
if (trans_row_count) {
7069+
DBUG_PRINT("exit", ("binlog has recorded rows -> not empty"));
7070+
return false;
7071+
}
7072+
if (opt_ndb_log_apply_status && replicated_row_count) {
7073+
DBUG_PRINT("info", ("logging updates to ndb_apply_status"));
7074+
DBUG_PRINT("exit", ("received rows applied by a replica "
7075+
"-> not empty"));
7076+
return false;
7077+
}
7078+
DBUG_PRINT("exit", ("empty epoch"));
7079+
return true;
7080+
}
7081+
70697082
void Ndb_binlog_thread::commit_trans(injector_transaction &trans, THD *thd,
70707083
Uint64 current_epoch,
7071-
unsigned trans_row_count,
7072-
unsigned replicated_row_count) {
7073-
if (!opt_ndb_log_empty_epochs) {
7074-
/*
7075-
If
7076-
- We did not add any 'real' rows to the Binlog
7077-
AND
7078-
- We did not apply any slave row updates, only
7079-
ndb_apply_status updates
7080-
THEN
7081-
Don't write the Binlog transaction which just
7082-
contains ndb_apply_status updates.
7083-
(For circular rep with log_apply_status, ndb_apply_status
7084-
updates will propagate while some related, real update
7085-
is propagating)
7086-
*/
7087-
if ((trans_row_count == 0) &&
7088-
(!(opt_ndb_log_apply_status && replicated_row_count))) {
7089-
/* nothing to commit, rollback instead */
7090-
(void)trans.rollback(); // Rollback never fails (by design)
7091-
return;
7092-
}
7084+
EpochContext epoch_ctx) {
7085+
DBUG_TRACE;
7086+
if (!opt_ndb_log_empty_epochs && epoch_ctx.is_empty_epoch()) {
7087+
/* nothing to commit, rollback instead */
7088+
(void)trans.rollback(); // Rollback never fails (by design)
7089+
return;
70937090
}
70947091

70957092
thd->set_proc_info("Committing events to binlog");

storage/ndb/plugin/ndb_binlog_thread.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,26 @@ class Ndb_binlog_thread : public Ndb_component {
326326

327327
Ndb_binlog_index_rows m_binlog_index_rows;
328328

329+
// Epoch context handler
330+
struct EpochContext {
331+
// Counter for rows in event
332+
unsigned int trans_row_count = 0;
333+
// Counter for replicated rows in event
334+
unsigned int replicated_row_count = 0;
335+
336+
/**
337+
@brief Check if epoch is considered empty in regards to the
338+
number of rows recorded in the epoch transaction. An epoch is
339+
considered empty if 1) it did not record any 'real' rows in the
340+
binlog (from user tables) AND 2) if logging ndb_apply_status
341+
updates, it received updates applied by another replica (that
342+
were not on ndb_apply_status).
343+
344+
@retval true for empty epoch
345+
*/
346+
bool is_empty_epoch() const;
347+
};
348+
329349
// Functions for handling received events
330350
int handle_data_get_blobs(const TABLE *table,
331351
const NdbValue *const value_array,
@@ -335,8 +355,7 @@ class Ndb_binlog_thread : public Ndb_component {
335355
void handle_non_data_event(THD *thd, NdbEventOperation *pOp,
336356
NdbDictionary::Event::TableEvent type);
337357
int handle_data_event(const NdbEventOperation *pOp,
338-
injector_transaction &trans, unsigned &trans_row_count,
339-
unsigned &replicated_row_count);
358+
injector_transaction &trans, EpochContext &epoch_ctx);
340359
bool handle_events_for_epoch(THD *thd, injector *inj, Ndb *i_ndb,
341360
NdbEventOperation *&i_pOp,
342361
const Uint64 current_epoch);
@@ -349,7 +368,7 @@ class Ndb_binlog_thread : public Ndb_component {
349368
Uint64 gap_epoch) const;
350369
void inject_table_map(injector_transaction &trans, Ndb *ndb) const;
351370
void commit_trans(injector_transaction &trans, THD *thd, Uint64 current_epoch,
352-
unsigned trans_row_count, unsigned replicated_row_count);
371+
EpochContext epoch_ctx);
353372

354373
// Cache for NDB metadata
355374
class Metadata_cache {

0 commit comments

Comments
 (0)