1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/****************************************************************
* *
* Copyright (c) 2005-2017 Fidelity National Information *
* Services, Inc. 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 *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_time.h"
#include "gtm_string.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdscc.h"
#include "gdskill.h"
#include "jnl.h"
#include "iosp.h" /* for SS_NORMAL */
#include "util.h"
/* Prototypes */
#include "gtmmsg.h" /* for gtm_putmsg prototype */
#include "desired_db_format_set.h"
#include "send_msg.h" /* for send_msg */
#include "wcs_phase2_commit_wait.h"
#define WCS_PHASE2_COMMIT_WAIT_LIT "wcb_phase2_commit_wait"
LITREF char *gtm_dbversion_table[];
GBLREF inctn_opcode_t inctn_opcode;
GBLREF jnl_gbls_t jgbl;
GBLREF uint4 process_id;
GBLREF inctn_detail_t inctn_detail; /* holds detail to fill in to inctn jnl record */
error_def(ERR_ASYNCIONOV4);
error_def(ERR_COMMITWAITSTUCK);
error_def(ERR_CRYPTNOV4);
error_def(ERR_DBDSRDFMTCHNG);
error_def(ERR_MMNODYNDWNGRD);
error_def(ERR_MUDWNGRDTN);
error_def(ERR_MUNOACTION);
error_def(ERR_SNAPSHOTNOV4);
error_def(ERR_WCBLOCKED);
/* input parameter "command_name" is a string that is either "MUPIP REORG UPGRADE/DOWNGRADE" or "MUPIP SET VERSION" */
int4 desired_db_format_set(gd_region *reg, enum db_ver new_db_format, char *command_name)
{
boolean_t was_crit;
char *db_fmt_str;
char *wcblocked_ptr;
int4 status;
uint4 jnl_status;
inctn_opcode_t save_inctn_opcode;
sgmnt_addrs *csa;
sgmnt_data_ptr_t csd;
trans_num curr_tn;
jnl_private_control *jpc;
jnl_buffer_ptr_t jbp;
assert(reg->open);
csa = &FILE_INFO(reg)->s_addrs;
csd = csa->hdr;
/* We do not allow databases to be encrypted if the version is V4. */
if (USES_ENCRYPTION(csd->is_encrypted) && (GDSV4 == new_db_format))
{
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_CRYPTNOV4, 2, DB_LEN_STR(reg));
return ERR_CRYPTNOV4;
}
/* We do not allow databases in ASYNCIO mode if the block format is V4 */
if (csd->asyncio && (GDSV4 == new_db_format))
{
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_ASYNCIONOV4, 6, DB_LEN_STR(reg),
LEN_AND_LIT("ASYNCIO enabled"), LEN_AND_LIT("downgrade to V4"));
return ERR_ASYNCIONOV4;
}
/* We don't allow databases to be downgraded when snapshots are in progress */
if (SNAPSHOTS_IN_PROG(csa->nl) && (GDSV4 == new_db_format))
{
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) ERR_SNAPSHOTNOV4,
3, csa->nl->num_snapshots_in_effect, DB_LEN_STR(reg));
return ERR_SNAPSHOTNOV4;
}
was_crit = csa->now_crit;
if (FALSE == was_crit)
grab_crit(reg);
/* if MM and desired_db_format is not V5, gvcst_init would have issued MMNODYNDWNGRD error. assert that. */
assert((dba_bg == csd->acc_meth) || ((dba_mm == csd->acc_meth) && (GDSV6 == csd->desired_db_format)));
if (csd->desired_db_format == new_db_format)
{ /* no change in db_format. fix max_tn_warn if necessary and return right away. */
status = ERR_MUNOACTION;
assert(csd->trans_hist.curr_tn <= csd->max_tn);
if ((GDSV4 == new_db_format) && (MAX_TN_V4 < csd->max_tn))
{ /* reset max_tn to MAX_TN_V4 only if V4 format and the new value will still be greater than curr_tn */
assertpro(MAX_TN_V4 >= csd->trans_hist.curr_tn);
csd->max_tn = MAX_TN_V4;
/* since max_tn changed above, max_tn_warn might also need to correspondingly change */
SET_TN_WARN(csd, csd->max_tn_warn);
}
if (FALSE == was_crit)
rel_crit(reg);
return status;
}
if (dba_mm == csd->acc_meth)
{
status = ERR_MMNODYNDWNGRD;
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(4) status, 2, REG_LEN_STR(reg));
if (FALSE == was_crit)
rel_crit(reg);
return status;
}
/* check if curr_tn is too high to downgrade */
curr_tn = csd->trans_hist.curr_tn;
if ((GDSV4 == new_db_format) && (MAX_TN_V4 <= curr_tn))
{
status = ERR_MUDWNGRDTN;
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(5) status, 3, &curr_tn, DB_LEN_STR(reg));
if (FALSE == was_crit)
rel_crit(reg);
return status;
}
/* Wait for concurrent phase2 commits to complete before switching the desired db format */
if (csa->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(csa, NULL))
{ /* Set wc_blocked so next process to get crit will trigger cache-recovery */
SET_TRACEABLE_VAR(csa->nl->wc_blocked, TRUE);
wcblocked_ptr = WCS_PHASE2_COMMIT_WAIT_LIT;
send_msg_csa(CSA_ARG(csa) VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_STR(wcblocked_ptr),
process_id, &csd->trans_hist.curr_tn, DB_LEN_STR(reg));
status = ERR_COMMITWAITSTUCK;
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(7) status, 5, process_id,
1, csa->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(reg));
if (FALSE == was_crit)
rel_crit(reg);
return status;
}
if (JNL_ENABLED(csd))
{
SET_GBL_JREC_TIME; /* needed for jnl_ensure_open, jnl_write_pini and jnl_write_aimg_rec */
jpc = csa->jnl;
jbp = jpc->jnl_buff;
/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order of jnl records.
* This needs to be done BEFORE the jnl_ensure_open as that could write journal records
* (if it decides to switch to a new journal file)
*/
ADJUST_GBL_JREC_TIME(jgbl, jbp);
jnl_status = jnl_ensure_open(reg, csa);
if (0 == jnl_status)
{
save_inctn_opcode = inctn_opcode;
inctn_opcode = inctn_db_format_change;
inctn_detail.blks2upgrd_struct.blks_to_upgrd_delta = csd->blks_to_upgrd;
if (0 == jpc->pini_addr)
jnl_write_pini(csa);
jnl_write_inctn_rec(csa);
inctn_opcode = save_inctn_opcode;
} else
gtm_putmsg_csa(CSA_ARG(csa) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg));
}
csd->desired_db_format = new_db_format;
csd->fully_upgraded = FALSE;
csd->desired_db_format_tn = curr_tn;
switch (new_db_format)
{
case GDSV4:
csd->max_tn = MAX_TN_V4;
break;
case GDSV6:
csd->max_tn = MAX_TN_V6;
break;
default:
assertpro((GDSV4 == new_db_format) || (GDSV6 == new_db_format));
}
SET_TN_WARN(csd, csd->max_tn_warn); /* if max_tn changed above, max_tn_warn also needs a corresponding change */
assert(curr_tn < csd->max_tn); /* ensure CHECK_TN macro below will not issue TNTOOLARGE rts_error */
CHECK_TN(csa, csd, curr_tn); /* can issue rts_error TNTOOLARGE */
/* increment csd->trans_hist.curr_tn */
assert(csd->trans_hist.early_tn == csd->trans_hist.curr_tn);
csd->trans_hist.early_tn = csd->trans_hist.curr_tn + 1;
INCREMENT_CURR_TN(csd);
if (FALSE == was_crit)
rel_crit(reg);
status = SS_NORMAL;
send_msg_csa(CSA_ARG(csa) VARLSTCNT(11) ERR_DBDSRDFMTCHNG, 9, DB_LEN_STR(reg),
LEN_AND_STR(gtm_dbversion_table[new_db_format]), LEN_AND_STR(command_name), process_id, process_id, &curr_tn);
return status;
}
|