gpcreateseg.sh 14.4 KB
Newer Older
1
#!/usr/bin/env bash
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
#	Filename:-		gpcreateseg.sh
#	Version:-		$Revision$
#	Updated:-		$Date$	
#	Status:-		Released	
#	Author:-		G Coombe	
#	Contact:-		gcoombe@greenplum.com
#	Release date:-		Dec 2006
#	Release stat:-		Released
#                               Copyright (c) Metapa 2005. All Rights Reserved.
#                               Copyright (c) 2007 Greenplum Inc
#******************************************************************************
# Update History
#******************************************************************************
# Ver	Date		Who		Update
#******************************************************************************
# Detailed Description
#******************************************************************************
#******************************************************************************
# Prep Code

WORKDIR=`dirname $0`

# Source required functions file, this required for script to run
# exit if cannot locate this file. Change location of FUNCTIONS variable
# as required.
FUNCTIONS=$WORKDIR/gp_bash_functions.sh
if [ -f $FUNCTIONS ]; then
    . $FUNCTIONS
else
    echo "[FATAL]:-Cannot source $FUNCTIONS file Script Exits!"
    exit 2
fi

#******************************************************************************
# Script Specific Variables
#******************************************************************************
# Log file that will record script actions
CUR_DATE=`$DATE +%Y%m%d`
TIME=`$DATE +%H%M%S`
PROG_NAME=`$BASENAME $0`
# Level of script feedback 0=small 1=verbose
unset VERBOSE
unset PG_CONF_ADD_FILE
# MPP database specific parameters
GP_USER=$USER_NAME
GP_TBL=gp_id
# System table names
GP_CONFIGURATION_TBL=gp_segment_configuration
EXIT_STATUS=0
51
# SED_PG_CONF search text values
52 53 54
PORT_TXT="#port"
LOG_STATEMENT_TXT="#log_statement ="
LISTEN_ADR_TXT="listen_addresses"
55 56
CONTENT_ID_TXT="gp_contentid"
DBID_TXT="gp_dbid"
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
TMP_PG_HBA=/tmp/pg_hba_conf_master.$$

#******************************************************************************
# Functions
#******************************************************************************

CHK_CALL () {
	FILE_PREFIX=`$ECHO $PARALLEL_STATUS_FILE|$CUT -d"." -f1`
	if [ ! -f ${FILE_PREFIX}.$PARENT_PID ];then
		$ECHO "[FATAL]:-Not called from correct parent program" 
		exit 2
	fi
}

SET_VAR () {
    # 
    # MPP-13617: If segment contains a ~, we assume ~ is the field delimiter.
    # Otherwise we assume : is the delimiter.  This allows us to easily 
    # handle IPv6 addresses which may contain a : by using a ~ as a delimiter. 
    # 
    I=$1
    case $I in
        *~*)
	    S="~"
            ;;
        *)
	    S=":"
            ;;
    esac
    GP_HOSTADDRESS=`$ECHO $I|$CUT -d$S -f1`
    GP_PORT=`$ECHO $I|$CUT -d$S -f2`
    GP_DIR=`$ECHO $I|$CUT -d$S -f3`
    GP_DBID=`$ECHO $I|$CUT -d$S -f4`
    GP_CONTENT=`$ECHO $I|$CUT -d$S -f5`
}

PARA_EXIT () {
	if [ $1 -ne 0 ];then
95
		$ECHO "FAILED:$SEGMENT_TO_CREATE" >> $PARALLEL_STATUS_FILE
96 97 98 99 100 101 102
		LOG_MSG "[FATAL][$INST_COUNT]:-Failed $2"
		exit 2
	else
		LOG_MSG "[INFO][$INST_COUNT]:-Completed $2"
	fi
}

103 104 105 106 107 108 109 110 111 112 113
ADD_PG_HBA_ENTRIES() {
    local ADDR
    local CIDR_ADDR

    for ADDR in "$@"; do
        # MPP-15889
        CIDR_ADDR=$(GET_CIDRADDR $ADDR)
        $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host     all          $USER_NAME         $CIDR_ADDR      trust >> ${GP_DIR}/$PG_HBA"
    done
}

114
CREATE_QES_PRIMARY () {
115 116
    LOG_MSG "[INFO][$INST_COUNT]:-Start Function $FUNCNAME"
    LOG_MSG "[INFO][$INST_COUNT]:-Processing segment $GP_HOSTADDRESS"
117 118 119 120 121 122 123 124 125 126
    # build initdb command, capturing output in ${GP_DIR}.initdb
    cmd="$EXPORT_LIB_PATH;$INITDB"
    cmd="$cmd -E $ENCODING"
    cmd="$cmd -D $GP_DIR"
    cmd="$cmd --locale=$LOCALE_SETTING"
    cmd="$cmd $LC_ALL_SETTINGS"
    cmd="$cmd --max_connections=$QE_MAX_CONNECT"
    cmd="$cmd --shared_buffers=$QE_SHARED_BUFFERS"
    if [ x"$HEAP_CHECKSUM" == x"on" ]; then
        cmd="$cmd --data-checksums"
127
    fi
128 129 130 131 132 133 134
    cmd="$cmd --backend_output=$GP_DIR.initdb"
    
    $TRUSTED_SHELL ${GP_HOSTADDRESS} $cmd >> $LOG_FILE 2>&1
    RETVAL=$?
    
    if [ $RETVAL -ne 0 ]; then
        $TRUSTED_SHELL ${GP_HOSTADDRESS} "cat $GP_DIR.initdb" >> $LOG_FILE 2>&1
135
    fi
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
    $TRUSTED_SHELL ${GP_HOSTADDRESS} "rm -f $GP_DIR.initdb" >> $LOG_FILE 2>&1
    BACKOUT_COMMAND "$TRUSTED_SHELL ${GP_HOSTADDRESS} \"$RM -rf $GP_DIR > /dev/null 2>&1\""
    BACKOUT_COMMAND "$ECHO \"removing directory $GP_DIR on $GP_HOSTADDRESS\""
    PARA_EXIT $RETVAL "to start segment instance database $GP_HOSTADDRESS $GP_DIR"
    
    # Configure postgresql.conf
    LOG_MSG "[INFO][$INST_COUNT]:-Configuring segment $PG_CONF"
    $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO \"#MPP Specific parameters\" >> ${GP_DIR}/$PG_CONF"
    RETVAL=$?
    PARA_EXIT $RETVAL "Update ${GP_DIR}/$PG_CONF file"
    $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO \"#----------------------\" >> ${GP_DIR}/$PG_CONF"
    RETVAL=$?
    PARA_EXIT $RETVAL "Update ${GP_DIR}/$PG_CONF file"
    SED_PG_CONF ${GP_DIR}/$PG_CONF "$PORT_TXT" port=$GP_PORT 0 $GP_HOSTADDRESS
    PARA_EXIT $RETVAL "Update port number to $GP_PORT"
    SED_PG_CONF ${GP_DIR}/$PG_CONF "$LISTEN_ADR_TXT" listen_addresses=\'*\' 0 $GP_HOSTADDRESS
    PARA_EXIT $RETVAL "Update listen address"
    SED_PG_CONF ${GP_DIR}/$PG_CONF "$CONTENT_ID_TXT" "gp_contentid=${GP_CONTENT}" 0 $GP_HOSTADDRESS
    PARA_EXIT $RETVAL "Update gp_contentid"
    SED_PG_CONF ${GP_DIR}/$PG_INTERNAL_CONF "$DBID_TXT" "gp_dbid=${GP_DBID}" 0 $GP_HOSTADDRESS
    PARA_EXIT $RETVAL "Update gp_dbid"
    
    if [ x"" != x"$PG_CONF_ADD_FILE" ]; then
        LOG_MSG "[INFO][$INST_COUNT]:-Processing additional configuration parameters"
        for NEW_PARAM in `$CAT $PG_CONF_ADD_FILE|$TR -s ' '|$TR -d ' '|$GREP -v "^#"`
        do
            LOG_MSG "[INFO][$INST_COUNT]:-Adding config $NEW_PARAM to segment"
            SEARCH_TXT=`$ECHO $NEW_PARAM |$CUT -d"=" -f1`
            SED_PG_CONF ${GP_DIR}/$PG_CONF $SEARCH_TXT $NEW_PARAM 0 $GP_HOSTADDRESS
            PARA_EXIT $RETVAL "Update $PG_CONF $SEARCH_TXT $NEW_PARAM"
        done
167
    fi
168
    # Configuring PG_HBA
169
    LOG_MSG "[INFO][$INST_COUNT]:-Configuring segment $PG_HBA"
170
    if [ $HBA_HOSTNAMES -eq 0 ]; then
171 172 173 174 175 176
        for MASTER_IP in "${MASTER_IP_ADDRESS[@]}"
        do
            # MPP-15889
            CIDR_MASTER_IP=$(GET_CIDRADDR $MASTER_IP)
            $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host	all	all	${CIDR_MASTER_IP}	trust >> ${GP_DIR}/$PG_HBA"
            PARA_EXIT $? "Update $PG_HBA for master IP address ${CIDR_MASTER_IP}"
177
          done
178
        if [ x"" != x"$STANDBY_HOSTNAME" ];then
179 180 181 182 183 184 185 186
          LOG_MSG "[INFO][$INST_COUNT]:-Processing Standby master IP address for segment instances"
          for STANDBY_IP in "${STANDBY_IP_ADDRESS[@]}"
          do
          # MPP-15889
              CIDR_STANDBY_IP=$(GET_CIDRADDR $STANDBY_IP)
              $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host	all	all	${CIDR_STANDBY_IP}	trust >> ${GP_DIR}/$PG_HBA"
              PARA_EXIT $? "Update $PG_HBA for master standby address ${CIDR_STANDBY_IP}"
          done
187
        fi
188
    
189 190
        # Add all local IPV4 addresses
        SEGMENT_IPV4_LOCAL_ADDRESS_ALL=(`$TRUSTED_SHELL $GP_HOSTADDRESS "$IPV4_ADDR_LIST_CMD | $GREP inet | $GREP -v \"127.0.0\" | $AWK '{print \\$2}' | $CUT -d'/' -f1"`)
191
        ADD_PG_HBA_ENTRIES "${SEGMENT_IPV4_LOCAL_ADDRESS_ALL[@]}"
192 193 194 195 196
    
        if [ x"" != x"$MIRROR_HOSTADDRESS" ]; then
          # Add all mirror segments local IPV4 addresses
          MIRROR_SEGMENT_IPV4_LOCAL_ADDRESS_ALL=(`$TRUSTED_SHELL $MIRROR_HOSTADDRESS "$IPV4_ADDR_LIST_CMD | $GREP inet | $GREP -v \"127.0.0\" | $AWK '{print \\$2}' | $CUT -d'/' -f1"`)
          ADD_PG_HBA_ENTRIES "${MIRROR_SEGMENT_IPV4_LOCAL_ADDRESS_ALL[@]}"
197
        fi
198
    
199 200
        # Add all local IPV6 addresses
        SEGMENT_IPV6_LOCAL_ADDRESS_ALL=(`$TRUSTED_SHELL $GP_HOSTADDRESS "$IPV6_ADDR_LIST_CMD | $GREP inet6 | $AWK '{print \\$2}' | $CUT -d'/' -f1"`)
201
        ADD_PG_HBA_ENTRIES "${SEGMENT_IPV6_LOCAL_ADDRESS_ALL[@]}"
202 203 204 205 206
    
        if [ x"" != x"$MIRROR_HOSTADDRESS" ]; then
          # Add all mirror segments local IPV6 addresses
          MIRROR_SEGMENT_IPV6_LOCAL_ADDRESS_ALL=(`$TRUSTED_SHELL $MIRROR_HOSTADDRESS "$IPV6_ADDR_LIST_CMD | $GREP inet6 | $AWK '{print \\$2}' | $CUT -d'/' -f1"`)
          ADD_PG_HBA_ENTRIES "${MIRROR_SEGMENT_IPV6_LOCAL_ADDRESS_ALL[@]}"
207
        fi
208 209 210 211 212 213
    else # use hostnames in pg_hba.conf
        # add localhost
        $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host     all          all         localhost      trust >> ${GP_DIR}/$PG_HBA"
        $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host	all	all	${MASTER_HOSTNAME}	trust >> ${GP_DIR}/$PG_HBA"
        if [ x"" != x"$MIRROR_HOSTADDRESS" ]; then
          $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host     all          $USER_NAME         $MIRROR_HOSTADDRESS      trust >> ${GP_DIR}/$PG_HBA"
214
        fi
215 216 217 218 219
        PARA_EXIT $? "Update $PG_HBA for master IP address ${MASTER_HOSTNAME}"
        if [ x"" != x"$STANDBY_HOSTNAME" ];then
            LOG_MSG "[INFO][$INST_COUNT]:-Processing Standby master IP address for segment instances"
            $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host	all	all	${STANDBY_HOSTNAME}	trust >> ${GP_DIR}/$PG_HBA"
            PARA_EXIT $? "Update $PG_HBA for master standby address ${STANDBY_HOSTNAME}"
220
        fi
221
        $TRUSTED_SHELL ${GP_HOSTADDRESS} "$ECHO host     all          $USER_NAME         $GP_HOSTADDRESS      trust >> ${GP_DIR}/$PG_HBA"
222
    fi
223 224
    LOG_MSG "[INFO][$INST_COUNT]:-End Function $FUNCNAME"
}
225

226 227 228 229 230 231 232 233 234 235 236
CREATE_QES_MIRROR () {
    LOG_MSG "[INFO][$INST_COUNT]:-Start Function $FUNCNAME"
    LOG_MSG "[INFO][$INST_COUNT]:-Processing segment $GP_HOSTADDRESS"
    # on mirror, just copy data from primary as the primary has all the relevant pg_hba.conf content
    # only the entry for replication is added on the primary if mirror hosts are there
    LOG_MSG "[INFO]:-Running pg_basebackup to init mirror on ${GP_HOSTADDRESS} using primary on ${PRIMARY_HOSTADDRESS} ..." 1
    RUN_COMMAND_REMOTE ${PRIMARY_HOSTADDRESS} "${EXPORT_GPHOME}; . ${GPHOME}/greenplum_path.sh; echo 'host  replication ${GP_USER} samenet trust' >> ${PRIMARY_DIR}/pg_hba.conf; pg_ctl -D ${PRIMARY_DIR} reload"
    RUN_COMMAND_REMOTE ${GP_HOSTADDRESS} "${EXPORT_GPHOME}; . ${GPHOME}/greenplum_path.sh; rm -rf ${GP_DIR}; ${GPHOME}/bin/pg_basebackup --xlog-method=stream --slot='internal_wal_replication_slot' -R -c fast -E ./db_dumps -E ./gpperfmon/data -E ./gpperfmon/logs -D ${GP_DIR} -h ${PRIMARY_HOSTADDRESS} -p ${PRIMARY_PORT} --target-gp-dbid ${GP_DBID};"
    START_QE "-w"
    RETVAL=$?
    PARA_EXIT $RETVAL "pg_basebackup of segment data directory from ${PRIMARY_HOSTADDRESS} to ${GP_HOSTADDRESS}"
237
    LOG_MSG "[INFO][$INST_COUNT]:-End Function $FUNCNAME"
238 239 240 241
}

START_QE() {
	LOG_MSG "[INFO][$INST_COUNT]:-Starting Functioning instance on segment ${GP_HOSTADDRESS}"
242
	PG_CTL_WAIT=$1
243
	$TRUSTED_SHELL ${GP_HOSTADDRESS} "$EXPORT_LIB_PATH;export PGPORT=${GP_PORT}; $PG_CTL $PG_CTL_WAIT -l $GP_DIR/pg_log/startup.log -D $GP_DIR -o \"-i -p ${GP_PORT}\" start" >> $LOG_FILE 2>&1
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	RETVAL=$?
	if [ $RETVAL -ne 0 ]; then
		BACKOUT_COMMAND "$TRUSTED_SHELL $GP_HOSTADDRESS \"${EXPORT_LIB_PATH};export PGPORT=${GP_PORT}; $PG_CTL -w -D $GP_DIR -o \"-i -p ${GP_PORT}\" -m immediate  stop\""
		BACKOUT_COMMAND "$ECHO \"Stopping segment instance on $GP_HOSTADDRESS\""
		$TRUSTED_SHELL ${GP_HOSTADDRESS} "$CAT ${GP_DIR}/pg_log/startup.log "|$TEE -a $LOG_FILE
		PARA_EXIT $RETVAL "Start segment instance database"
	fi	
	BACKOUT_COMMAND "$TRUSTED_SHELL $GP_HOSTADDRESS \"${EXPORT_LIB_PATH};export PGPORT=${GP_PORT}; $PG_CTL -w -D $GP_DIR -o \"-i -p ${GP_PORT}\" -m immediate  stop\""
	BACKOUT_COMMAND "$ECHO \"Stopping segment instance on $GP_HOSTADDRESS\""
	LOG_MSG "[INFO][$INST_COUNT]:-Successfully started segment instance on $GP_HOSTADDRESS"
}

#******************************************************************************
# Main Section
#******************************************************************************
S
Shoaib Lari 已提交
259
trap '$ECHO "KILLED:$SEGMENT_TO_CREATE" >> $PARALLEL_STATUS_FILE;ERROR_EXIT "[FATAL]:-[$INST_COUNT]-Recieved INT or TERM signal"' INT TERM
D
Daniel Gustafsson 已提交
260
while getopts ":qp:" opt
261 262 263
do
	case $opt in
		q ) unset VERBOSE ;;
D
Daniel Gustafsson 已提交
264
		p ) PG_CONF_ADD_FILE=$OPTARG
265 266
		    shift
		    shift ;;
D
Daniel Gustafsson 已提交
267 268
		\? ) echo "Invalid option: -$OPTARG"
			 exit 1 ;;
269 270 271
	esac
done

272 273 274 275 276 277 278 279
# gpcreateseg.sh is called for creating primary and mirror segments.
# Below is an example for invocation to create a primary
# MASTER_HOSTNAME=bhuvi.local HBA_HOSTNAMES=0 /usr/local/gpdb/bin/lib/gpcreateseg.sh -p clusterConfigPostgresAddonsFile 65324 1
# IS_PRIMARY host1.local~45432~/tmp/demoDataDir0~2~0 host2.local~45433~/tmp/demoDataDir0~3~0 0
# /tmp/gpAdminLogs/gpinitsystem_20190903.log on  10.64.249.254~192.168.1.72~::1~fe80::1%lo0 10.64.249.252~192.168.1.73~::1~fe81::1%lo1 &
# PARALLEL_COUNT 1 4
# Now process supplied call parameters
PARENT_PID=$1;shift		# PID of calling gpinitsystem program ex: 31578
280 281
CHK_CALL

282 283 284
# for primary: it's IS_PRIMARY
# for mirror: it's IS_MIRROR
PRIMARY_OR_MIRROR_IDENTIFIER=$1;shift
285

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
# string containing details of segment to create, format: hostname~port~datadir~dbid~content
SEGMENT_TO_CREATE=$1;shift

# string containing details of the corresponding pair (if mirroring enabled else empty)
CORRESPONDING_PAIR_INFO=$1;shift

# SET_VAR populates, GP_HOSTADDRESS, GP_DIR, GP_PORT, GP_CONTENT
SET_VAR $CORRESPONDING_PAIR_INFO
if [ x"IS_MIRROR" == x"$PRIMARY_OR_MIRROR_IDENTIFIER" ]; then
   # store the corresponding primary info
   PRIMARY_HOSTADDRESS=$GP_HOSTADDRESS
   PRIMARY_DIR=$GP_DIR
   PRIMARY_PORT=$GP_PORT
   PRIMARY_CONTENT=$GP_CONTENT
else
   # store the corresponding mirror hostname
   MIRROR_HOSTADDRESS=$GP_HOSTADDRESS
fi

# update GP_HOSTADDRESS, GP_DIR, GP_PORT, GP_CONTENT with the segment to create
SET_VAR $SEGMENT_TO_CREATE

if [ x"IS_MIRROR" == x"$PRIMARY_OR_MIRROR_IDENTIFIER" ]; then
    if [ x"$GP_CONTENT" != x"$PRIMARY_CONTENT" ]; then
        $ECHO "[FATAL]:-mismatch between content id and primary content id"
        exit 2
    fi
fi

INST_COUNT=$1;shift		#Unique number for this parallel script, starts at 0
BACKOUT_FILE=/tmp/gpsegcreate.sh_backout.$$
LOG_FILE=$1;shift		#Central logging file
LOG_MSG "[INFO][$INST_COUNT]:-Start Main"
LOG_MSG "[INFO][$INST_COUNT]:-Command line options passed to utility = $*"
HEAP_CHECKSUM=$1;shift
TMP_MASTER_IP_ADDRESS=$1;shift	#List of IP addresses for the master instance
MASTER_IP_ADDRESS=(`$ECHO $TMP_MASTER_IP_ADDRESS|$TR '~' ' '`)
TMP_STANDBY_IP_ADDRESS=$1;shift #List of IP addresses for standby master
STANDBY_IP_ADDRESS=(`$ECHO $TMP_STANDBY_IP_ADDRESS|$TR '~' ' '`)
if [ x"IS_PRIMARY" == x"$PRIMARY_OR_MIRROR_IDENTIFIER" ]; then
    CREATE_QES_PRIMARY
else
    CREATE_QES_MIRROR
fi
$ECHO "COMPLETED:$SEGMENT_TO_CREATE" >> $PARALLEL_STATUS_FILE
331 332 333

LOG_MSG "[INFO][$INST_COUNT]:-End Main"
exit $EXIT_STATUS