fis-gtm/sr_port/db_auto_upgrade.c

156 lines
7.1 KiB
C

/****************************************************************
* *
* Copyright 2001, 2013 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 "gtm_string.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "gdsblk.h"
#include "gdscc.h"
#include "gdsblkops.h"
#include "filestruct.h"
#include "io.h"
#include "jnl.h"
#include "mutex.h"
#include "wcs_phase2_commit_wait.h"
#include "gvcst_protos.h" /* for gvcst_init_sysops prototype */
GBLREF boolean_t dse_running;
error_def(ERR_DBBADUPGRDSTATE);
void db_auto_upgrade(gd_region *reg)
{
/* detect unitialized file header fields for this version of GT.M and do a mini auto-upgrade, initializing such fields
* to default values in the new GT.M version
*/
sgmnt_addrs *csa;
sgmnt_data_ptr_t csd;
assert(NULL != reg);
if (NULL == reg)
return;
csa = &FILE_INFO(reg)->s_addrs;
csd = csa->hdr;
assert(NULL != csd);
if (NULL == csd)
return;
if (0 == csd->mutex_spin_parms.mutex_hard_spin_count)
csd->mutex_spin_parms.mutex_hard_spin_count = MUTEX_HARD_SPIN_COUNT;
if (0 == csd->mutex_spin_parms.mutex_sleep_spin_count)
csd->mutex_spin_parms.mutex_sleep_spin_count = MUTEX_SLEEP_SPIN_COUNT;
/* zero is a legitimate value for csd->mutex_spin_parms.mutex_spin_sleep_mask; so can't detect if need re-initialization */
INIT_NUM_CRIT_ENTRY_IF_NEEDED(csd);
/* Auto upgrade based on minor database version number. This code currently only does auto upgrade and does not
* do auto downgrade although that certainly is possible to implement if necessary. For now, if the current version
* is at a lower level than the minor db version, we do nothing.
*
* Note the purpose of the minor_dbver field is so that some part of gtm (either runtime, or conversion utility) some
* time and several versions down the road from now knows by looking at this field what fields in the fileheader are
* valid so it is important that the minor db version be updated each time the fileheader is updated and this routine
* correspondingly updated. SE 5/2006.
*/
if (csd->minor_dbver < GDSMVCURR)
{ /* In general, the method for adding new versions is:
* 1) If there are no automatic updates for this version, it is optional to add the version to the switch
* statement below. Those there are more for example at this time (through V53000).
* 2) Update (or add) a case for the previous version to update any necessary fields.
*/
if (!csd->opened_by_gtmv53 && !csd->db_got_to_v5_once)
{
csd->opened_by_gtmv53 = TRUE;
/* This is a case of a database that has been used by a pre-V53 version of GT.M that did not contain
* the fix (C9H07-002873). At this point, the database might contain RECYCLED blocks that are a mix of
* a) Those blocks that were RECYCLED at the time of the MUPIP UPGRADE from V4 to V5.
* b) Those blocks that became RECYCLED due to M-kills in V5.
* It is only (a) that we have to mark as FREE as it might contain too-full v4 format blocks. But there
* is no way to distinguish the two. So we mark both (a) and (b) as FREE. This will mean no PBLKs written
* for (b) and hence no backward journal recovery possible to a point before the start of the REORG UPGRADE.
* We force a MUPIP REORG UPGRADE rerun (to mark RECYCLED blocks FREE) by setting fully_upgraded to FALSE.
* Note that this does not need to be done for databases created by a V5 version (C9I05-002987).
*/
if (MASTER_MAP_SIZE_V4 == csd->master_map_len)
{
csd->fully_upgraded = FALSE;
csd->reorg_upgrd_dwngrd_restart_block = 0; /* reorg upgrade should restart from block 0 */
/* Ensure reorg_db_fmt_start_tn and desired_db_format_tn are set to different
* values so fresh reorg upgrade can set fully_upgraded to TRUE once it is done.
*/
csd->reorg_db_fmt_start_tn = 0;
csd->desired_db_format_tn = 1;
} else
csd->db_got_to_v5_once = TRUE; /* db was created by V5 so safe to set this */
}
/* When adding a new minor version, the following template should be maintained
* a) Remove the penultimate 'break'
* b) Remove the assert(FALSE) in the last case (most recent minor version)
* c) If there are any file header fields added in the new minor version, initialize the fields to default values
* in the last case
* d) Add a new case with the new minor version
* e) Add assert(FALSE) and break (like it was before)
*/
switch(csd->minor_dbver)
{ /* Note that handling for any fields introduced in a version will not go in the "switch-case" block
* of code introduced for the new version but will go in the PREVIOUS "switch-case" block.
*/
case GDSMV51000: /* Multi-site replication available */
case GDSMV52000: /* Unicode */
case GDSMV53000: /* M-Itanium release */
gvstats_rec_upgrade(csa); /* Move GVSTATS information to new place in file header */
case GDSMV54002:
/* GT.M V54002B introduced jnl_eov_tn for backward recovery */
csd->jnl_eovtn = csd->trans_hist.curr_tn;
case GDSMV54002B:
/* GT.M V55000 introduced strm_reg_seqno, save_strm_reg_seqno, intrpt_recov_resync_strm_seqno
* AND obsoleted dualsite_resync_seqno. For new fields, we are guaranteed they are
* zero (in formerly unused sections of the file header) so no need for any initialization.
* For obsoleted fields, it would be good to clear them here so we dont run into issues later.
*/
UNIX_ONLY(csd->filler_seqno = 0;) /* was "dualsite_resync_seqno" in pre-V55000 versions */
/* In addition, V55000 introduced before_trunc_total_blks for MUPIP REORG -TRUNCATE.
* Since it is a new field no initialization necessary.
*/
case GDSMV55000:
UNIX_ONLY(csd->freeze_on_fail = FALSE;)
UNIX_ONLY(csd->span_node_absent = TRUE;)
UNIX_ONLY(csd->maxkeysz_assured = FALSE;)
case GDSMV60000:
case GDSMV60001:
/* GT.M V60002 introduced mutex_spin_parms.mutex_que_entry_space_size */
NUM_CRIT_ENTRY(csd) = DEFAULT_NUM_CRIT_ENTRY;
break;
case GDSMV60002:
/* Nothing to do for this version since it is GDSMVCURR for now. */
assert(FALSE); /* When this assert fails, it means a new GDSMV* was created, */
break; /* so a new "case" needs to be added BEFORE the assert. */
}
csd->minor_dbver = GDSMVCURR;
if (0 == csd->wcs_phase2_commit_wait_spincnt)
csd->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT;
}
csd->last_mdb_ver = GDSMVCURR;
if (csd->fully_upgraded && !csd->db_got_to_v5_once)
{ /* Database is fully upgraded but the db_got_to_v5_once field says different.
* Don't know how that could happen, except with DSE which can change both the database file header fields
*/
assert(!dse_running);
csd->db_got_to_v5_once = TRUE; /* fix it in PRO */
send_msg(VARLSTCNT(6) ERR_DBBADUPGRDSTATE, 4, REG_LEN_STR(reg), DB_LEN_STR(reg));
}
return;
}