2012-03-24 14:06:46 -04:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
|
|
|
* Copyright 2012 Fidelity Information Services, Inc *
|
|
|
|
* *
|
|
|
|
* 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 *
|
|
|
|
* the license, please stop and do not read further. *
|
|
|
|
* *
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#include "mdef.h"
|
|
|
|
#include "gdsroot.h"
|
|
|
|
#include "gdsblk.h"
|
|
|
|
#include "gdskill.h"
|
|
|
|
#include "gtm_facility.h"
|
|
|
|
#include "fileinfo.h"
|
|
|
|
#include "gdsbt.h"
|
|
|
|
#include "gdsfhead.h"
|
|
|
|
#include "gdscc.h"
|
|
|
|
#include "filestruct.h"
|
|
|
|
#include "jnl.h"
|
2012-06-14 08:55:06 -04:00
|
|
|
#include <rtnhdr.h>
|
2012-03-24 14:06:46 -04:00
|
|
|
#include "hashtab_int4.h" /* needed for tp.h */
|
|
|
|
#include "buddy_list.h" /* needed for tp.h */
|
|
|
|
#include "tp.h"
|
|
|
|
#include "repl_msg.h" /* for gtmsource.h */
|
|
|
|
#include "gtmsource.h" /* for jnlpool_addrs structure definition */
|
|
|
|
#include "gvcst_protos.h" /* for gvcst_root_search prototype */
|
|
|
|
#include "repl_instance.h"
|
|
|
|
#include "gtmrecv.h"
|
|
|
|
#include "gtmimagename.h"
|
|
|
|
#include "have_crit.h"
|
|
|
|
#include "tp_frame.h"
|
|
|
|
|
|
|
|
GBLREF gtmsource_state_t gtmsource_state;
|
|
|
|
GBLREF jnlpool_addrs jnlpool;
|
|
|
|
GBLREF jnlpool_ctl_ptr_t jnlpool_ctl;
|
|
|
|
GBLREF seq_num gtmsource_save_read_jnl_seqno;
|
|
|
|
GBLREF uint4 process_id;
|
|
|
|
|
|
|
|
void gtmsource_onln_rlbk_clnup()
|
|
|
|
{
|
|
|
|
gtmsource_local_ptr_t gtmsource_local;
|
|
|
|
boolean_t was_crit;
|
|
|
|
sgmnt_addrs *repl_csa;
|
|
|
|
|
|
|
|
gtmsource_local = jnlpool.gtmsource_local;
|
|
|
|
repl_csa = &FILE_INFO(jnlpool.jnlpool_dummy_reg)->s_addrs;
|
|
|
|
was_crit = repl_csa->now_crit;
|
|
|
|
assert(!repl_csa->hold_onto_crit);
|
|
|
|
assert(was_crit || (process_id == gtmsource_local->gtmsource_srv_latch.u.parts.latch_pid)
|
|
|
|
|| (0 != have_crit(CRIT_HAVE_ANY_REG)));
|
|
|
|
/* Reset source server context to indicate a fresh connection that is about to take place */
|
|
|
|
assert(NULL != gtmsource_local);
|
|
|
|
if (NULL != gtmsource_local)
|
|
|
|
{
|
|
|
|
/* If ROLLBACK has not taken the instance past the source server's read_jnl_seqno, then the source server should
|
|
|
|
* just continue from where it currently is and start sending the journal records from that point onwards. But, this
|
|
|
|
* is non-trivial. The reason is because, when the source server detected the online rollback, it could be in the
|
|
|
|
* READ_POOL state. But, since the instance has been rolled back, the journal pool cannot be relied upon in its
|
|
|
|
* entirety. To illustrate this -- consider that the journal pool contains the data from 1-100 and the source server
|
|
|
|
* is currently sending sequence number 30 and is reading from the pool. Assume an online rollback happens that
|
|
|
|
* takes the instance from sequence number 100 to sequence number 80 and leaves the journal pool write_addr and
|
|
|
|
* early_write_addr untouched. Now, lets say GT.M process comes in after this and does a few more updates. All of
|
|
|
|
* these updates will be written in the journal pool right after the "old-rolled-back" sequence number 100. If the
|
|
|
|
* source server continues to read from the pool, it will send the valid data until sequence number 80. After that,
|
|
|
|
* it will start sending the "old-rolled-back" sequence numbers 81-100 which is not right. To avoid this, rollback
|
|
|
|
* should set the write_addr and early_write_addr by searching in the journal pool for sequence number 81. This is
|
|
|
|
* currently not done, but is something that we can think about when it comes to optimization. Until then, force
|
|
|
|
* rollback to reset jnlpool's write_addr, write and early_write_addr to 0 and let source server be forced into
|
|
|
|
* READ_FILE mode.
|
|
|
|
*/
|
|
|
|
gtmsource_local->read_state = READ_FILE;
|
|
|
|
/* Set the state which gets bubbled up the call chain to gtmsource_process at which point we will close and
|
|
|
|
* re-establish the connection with the other end.
|
|
|
|
*/
|
|
|
|
gtmsource_local->gtmsource_state = gtmsource_state = GTMSOURCE_HANDLE_ONLN_RLBK;
|
|
|
|
if (!was_crit)
|
|
|
|
GRAB_LOCK(jnlpool.jnlpool_dummy_reg, ASSERT_NO_ONLINE_ROLLBACK)
|
|
|
|
/* We have to let the read files logic know that until we have sent data "upto" the current journal sequence number
|
|
|
|
* at this point, we cannot rely on the journal pool. Indicate this through the gtmsource_save_read_jnl_seqno global
|
|
|
|
* variable
|
|
|
|
*/
|
|
|
|
gtmsource_save_read_jnl_seqno = jnlpool.jnlpool_ctl->jnl_seqno;
|
|
|
|
gtmsource_local->read = jnlpool.jnlpool_ctl->write;
|
|
|
|
gtmsource_local->read_addr = jnlpool.jnlpool_ctl->write_addr;
|
|
|
|
if (!was_crit)
|
|
|
|
rel_lock(jnlpool.jnlpool_dummy_reg);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|