Skip to content

Commit

Permalink
[YottaDB#341] epoch_interval setting in the journal file needs to be …
Browse files Browse the repository at this point in the history
…honored in all cases

Code fixes for GTM-8708 in GT.M V6.3-002 wanted to prevent the update helper writer process from
unnecessarily making calls to grab_crit_immediate() in case the instance had no updates.
It did this by setting the next epoch time (jbp->next_epoch_time) to a huge value (MAXUINT4)
the moment a wcs_flu() call was done to write a regular epoch (JRE gvstat) where it noticed an
idle epoch (JRI gvstat) had already been written (because of inactivity since the last update).
This caused the jbp->next_epoch_time vs jgbl.gbl_jrec_time check in updhelper_writer() to
automatically skip invoking the grab_crit_immediate() during periods of idleness.

But this introduced the YottaDB#341 regression. It is now possible for a regular epoch to not be written
in a timely fashion. This is because once jbp->next_epoch_time gets set to MAXUINT4 as part of
an update, if the next update on the same journal file happens say N seconds later (where N could
be as high as 5 seconds, the hardcoded inactivity time before an idle epoch kicks in), the call
to t_end/tp_tend for the next update finds jbp->next_epoch_time set to MAXUINT4 and resets it to
the current time (which is the time of the next update, not the time of the prior update) plus
the epoch_interval. This means the next_epoch_time is set to a value that is incorrect by at most
N seconds. That is, it is possible for two updates to be separated by as much as N + epoch_interval
seconds without having an intervening EPOCH in the journal file. This violates the definition of
the epoch_interval setting.

The fix for this is to undo all the changes done as part of GTM-8708. So jbp->next_epoch_time is
never set to MAXUINT4. Instead, updhelper_writer.c is enhanced to check if an EPOCH is the most
recent record in the journal buffer (jbp->post_epoch_freeaddr == jbp->rsrv_freeaddr) and if so
we skip checking jbp->next_epoch_time (and invoking grab_crit_immediate()) altogether since we know
there is nothing left to be flushed in the journal file. This achieves the objective of GTM-8708.
And for YottaDB#341, jbp->next_epoch_time is updated in wcs_flu() at the time when we notice an epoch is
the most recent journal record in the journal file. This ensures we honor the epoch_interval setting.
  • Loading branch information
nars1 committed Aug 14, 2018
1 parent 932c17c commit e0252b4
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 8 deletions.
2 changes: 0 additions & 2 deletions sr_port/t_end.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,8 +1300,6 @@ trans_num t_end(srch_hist *hist1, srch_hist *hist2, trans_num ctn)
}
assert(!jbp->last_eof_written);
assert(jgbl.gbl_jrec_time >= jbp->prev_jrec_time);
if (MAXUINT4 == jbp->next_epoch_time)
jbp->next_epoch_time = (uint4)(jgbl.gbl_jrec_time + jbp->epoch_interval);
if (((jbp->next_epoch_time <= jgbl.gbl_jrec_time) UNCONDITIONAL_EPOCH_ONLY(|| TRUE))
&& !FROZEN_CHILLED(csa))
{ /* Flush the cache. Since we are in crit, defer syncing epoch */
Expand Down
2 changes: 0 additions & 2 deletions sr_port/tp_tend.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,6 @@ boolean_t tp_tend()
}
assert(csd == csa->hdr); /* If MM, csd shouldn't have been reset */
}
if (MAXUINT4 == jbp->next_epoch_time)
jbp->next_epoch_time = (uint4)(jgbl.gbl_jrec_time + jbp->epoch_interval);
if (((jbp->next_epoch_time <= jgbl.gbl_jrec_time) UNCONDITIONAL_EPOCH_ONLY(|| TRUE))
&& !FROZEN_CHILLED(csa))
{ /* Flush the cache. Since we are in crit, defer syncing the epoch */
Expand Down
14 changes: 12 additions & 2 deletions sr_port/updhelper_writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
* Copyright (c) 2005-2018 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* Copyright (c) 2018 YottaDB LLC. and/or its subsidiaries. *
* All rights reserved. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
Expand Down Expand Up @@ -145,8 +148,15 @@ int updhelper_writer(void)
ENSURE_JNL_OPEN(csa, reg);
SET_GBL_JREC_TIME;
assert(jgbl.gbl_jrec_time);
if (((jbp->next_epoch_time - UPDHELPER_EARLY_EPOCH) <= jgbl.gbl_jrec_time)
&& !FROZEN_CHILLED(csa))
/* If EPOCH is the most recent record written in the journal buffer, do not
* attempt any more checks of time/crit or write epochs. Hence the "post_epoch_freeaddr"
* use below. If EPOCH is not the most recent record in the journal buffer,
* then check (out of crit) if it is close to an epoch and if so get crit and
* check again if epoch is due and if so write one (using "wcs_flu").
*/
if ((jbp->post_epoch_freeaddr != jbp->rsrv_freeaddr)
&& ((jbp->next_epoch_time - UPDHELPER_EARLY_EPOCH) <= jgbl.gbl_jrec_time)
&& !FROZEN_CHILLED(csa))
{
DO_JNL_FSYNC_OUT_OF_CRIT_IF_NEEDED(reg, csa, jpc, jbp);
if (grab_crit_immediate(reg, OK_FOR_WCS_RECOVER_TRUE))
Expand Down
5 changes: 3 additions & 2 deletions sr_unix/wcs_flu.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,14 @@ boolean_t wcs_flu(uint4 options)
*/
fileheader_sync(reg);
assert(NULL != jpc);
assert(jgbl.gbl_jrec_time);
if (!jgbl.mur_extract && !epoch_already_current)
{
if (0 == jpc->pini_addr)
jnl_write_pini(csa);
JNL_WRITE_EPOCH_REC(csa, cnl, clean_dbsync);
} else if (epoch_already_current)
jb->next_epoch_time = MAXUINT4;
jb->next_epoch_time = jgbl.gbl_jrec_time + jb->epoch_interval;
}
fsync_dskaddr = jb->fsync_dskaddr; /* take a local copy as it could change concurrently */
if (fsync_dskaddr != jb->rsrv_freeaddr)
Expand Down Expand Up @@ -741,7 +742,7 @@ boolean_t wcs_flu(uint4 options)
jnl_write_pini(csa);
JNL_WRITE_EPOCH_REC(csa, cnl, clean_dbsync);
} else if (epoch_already_current)
jb->next_epoch_time = MAXUINT4;
jb->next_epoch_time = jgbl.gbl_jrec_time + jb->epoch_interval;
}
cnl->last_wcsflu_tn = csa->ti->curr_tn; /* record when last successful wcs_flu occurred */
REL_CRIT_BEFORE_RETURN(cnl, reg);
Expand Down

0 comments on commit e0252b4

Please sign in to comment.