refresh_P4ROOT_from_offline_db.sh #7

  • //
  • guest/
  • perforce_software/
  • sdp/
  • dev/
  • Server/
  • Unix/
  • p4/
  • common/
  • bin/
  • refresh_P4ROOT_from_offline_db.sh
  • View
  • Commits
  • Open Download .zip Download (4 KB)
#!/bin/bash
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE
#------------------------------------------------------------------------------

declare -i PreserveOldP4ROOT=0

export SDP_INSTANCE=${SDP_INSTANCE:-Undefined} 
export SDP_INSTANCE=${1:-$SDP_INSTANCE} 
if [[ $SDP_INSTANCE == Undefined ]]; then 
   echo "Instance parameter not supplied." 
   echo "You must supply the Perforce instance as a parameter to this script." 
   exit 1 
fi 

# The '-K' option is currently an undocumented feature, though it may be documented
# in a future release (pending a separate change to normalize command line processing
# to add '-h' and '-man' options across all key scripts).  If '-K' is specified, this
# avoids removing the formerly saved db.* files in the old P4ROOT.
[[ "${2:-}" == "-K" ]] && PreserveOldP4ROOT=1

# shellcheck disable=SC1091
source /p4/common/bin/p4_vars "$SDP_INSTANCE"
# shellcheck disable=SC1091
source /p4/common/bin/backup_functions.sh
LOGFILE="$LOGS/refresh_P4ROOT_from_offline_db.log"

######### Start of Script ##########
check_vars
set_vars
rotate_last_run_logs
log "Start $P4SERVER Refresh P4ROOT from offline_db."
check_uid
check_dirs
check_offline_db_usable
if ! "$P4BIN" info -s > /dev/null 2>&1; then
   die "Error: p4d is not running as expected. Aborting."
fi
ckp_running
"$P4CBIN"/p4login
get_journalnum
get_offline_journal_num
stop_p4d
p4d_truncate_journal
replay_journals_to_offline_db

# On an edge or replica server, we have to replay the active journal as well because
# edges/replicas have been running since the journal was rotated.
if [[ "$SERVERID" != "$P4MASTER_ID" ]]; then
   replay_active_journal_to_offline_db
fi

# If run on a 'standby' replica, artificially set state to match statejcopy, as we have
# just successfully replayed the entire content of the locally pulled journal into the
# offline_db.
if [[ "$STANDBYSERVER" -eq 1 ]]; then
   if [[ -r "$P4ROOT/statejcopy" ]]; then
      log "Setting $P4ROOT/state to $P4ROOT/statejcopy"
      cp -f "$P4ROOT/statejcopy" "$P4ROOT/state"
   else
      log "Warning: Expected $P4ROOT/statejcopy file not found."
   fi
fi

# Call copy_readonly_clients_dir() to determine if clients.readonly.dir needs
# to be copied to offline_db.
if copy_readonly_clients_dir; then
   log "Successfully handled client.readonly.dir data (if any)."
else
   start_p4d
   die "Aborting due to failure to copy the client.readonly.dir. Because this failure mode did not affect data used by p4d, it was safe to continue using the p4d service, so the p4d service was restarted prior this abort."
fi

switch_db_files
start_p4d

if [[ "$PreserveOldP4ROOT" -eq 0 ]]; then
   log "Removing db files from save directory since we know the journal successfully replayed at this point."
   # The offline_db directory was the root, so this is where the save directory is now.
   rm -f "${OFFLINE_DB}"/save/db.* >> "$LOGFILE" 2>&1
else
   SavedDBDir="${OFFLINE_DB}/moved.$(date +'%Y-%m-%d-%H%M')"
   log "Preserving former P4ROOT files in $SavedDBDir due to -K."
   mkdir -p "$SavedDBDir" ||\
      die "Could not do: mkdir -p \"$SavedDBDir\""
   mv "${OFFLINE_DB}"/save/db.* "${SavedDBDir}/." ||\
      die "Could not do: mv \"${OFFLINE_DB}\"/save/db.* \"${SavedDBDir}/.\""
fi

recreate_offline_db_files
get_offline_journal_num
replay_journals_to_offline_db
# shellcheck disable=SC2034
ROOTDIR=$OFFLINE_DB

# If on the master, kick off the standard offline checkpoint.  For servers other than
# the master, skip this.
if [[ "$SERVERID" == "$P4MASTER_ID" ]]; then
   dump_checkpoint
fi
remove_old_checkpoints_and_journals
check_disk_space
remove_old_logs
set_counter
ckp_complete

log "End $P4SERVER Refresh P4ROOT from offline_db."
mail_log_file "$HOSTNAME $P4SERVER Refresh P4ROOT from offline_db log."
# Change User Description Committed
#7 31158 C. Thomas Tyler This is a change to unreleased new behaviour to handle the clients.readonly.dir
data as part of the database swap handling.

Added a disk space safety check, so the refresh_P4ROOT_from_offline_db will
safely abort early if there's not enough disk space to safely complete the
rsync of the readonly.clients.dir folder to the offline_db prior to the
database swap orchestrated by refresh_P4ROOT_from_offline_db.sh.

Renamed the copy function for improved clarity, and added a new rsync_with_preflight
function to improve modularity.

#review-31159
#6 31152 C. Thomas Tyler Added feature to preserve client.readonly.dir during a database swap.

Refined tmp file cleanup logic to search only for tmp files owned by
the defined OSUSER.

#review-31153 @robert_cowham
#5 30684 C. Thomas Tyler This replaces the prior change in @30682.

Added undoc '-K' option to preserve original P4ROOT
database files for analysis after the swap.

This is specifically for the scenario where the P4ROOT databases
have some kind of corruption to be analyed, but all checkpoints
and journals are known to be healthy, and also the offline_db is
known to be in a good state.

@review @d_benedict
#4 30682 C. Thomas Tyler Added undoc '-rebuild_offline_db' option to rebuild offline_db
from checkpoints and journal rather than doing a dump of the
former P4ROOT directory.

This is specifically for the scenario where the P4ROOT databases
have some kind of corruption, but all checkpoints and journals are
known to be healthy, and also the offline_db is known to be in a
good state.

#review-30683 @d_benedict
#3 30210 C. Thomas Tyler Adjusted set_counter() so the checkpoint counter is set consistently on any p4d
server (commit, edge, standby, filtered forwarding replica, etc.).  Also
enhanced auditability of counter setting.

#review-30211
#2 26468 C. Thomas Tyler Adjusted refresh_P4ROOT_from_offline_db.sh to work on maser/edge/replicas.

Added logic in functions like p4d_truncate_journal() to make them safe
to call on any host, master, replica, or edge. When called on any host
other than the master, appropriate behavior is expected.

Approving to deliver patch.
#1 26400 C. Thomas Tyler Added refresh_P4ROOT_from_offline_db.sh.

Updated backup_functions.sh to support functionality for db refresh.

Upgrade start_p4d() and stop_p4d() to use systemd if available, else
use the underlying SysV init scripts.

Updated verify_sdp.sh to be called from other scripts (sans
its own logging).  Added many checks to verify_sdp.sh to
support P4ROOT/offline_db swap.

Logic in P4ROOT/offline_db swap is more careful about what gets
swapped.

Added start_p4broker() and stop_p4broker() that behave similarly.

More shellcheck compliance.

#review-26401