5tarl0rd
Current Path : /bin/ |
|
Current File : //bin/postgresql-setup |
#!/bin/bash
#
# postgresql-setup - Initialization and upgrade operations for PostgreSQL
# For SELinux we need to use 'runuser' not 'su'
if [ -x /sbin/runuser ]; then
SU=runuser
else
SU=su
fi
if test "$(id -u)" -eq 0; then
cmd=
for v in PGSETUP_DEBUG PGSETUP_INITDB_OPTIONS PGSETUP_PGUPGRADE_OPTIONS; do
eval var_content=\$$v
test -z "$var_content" && continue
cmd+=$v="$(printf %q "$var_content") "
done
cmd+=$(printf %q "$(readlink -f "$0")")
for arg; do cmd+=" $(printf %q "$arg")" ; done
# Drop root privileges asap. It's not recommended to run postgresql-setup
# script under root nowadays; so we take the liberty to switch to the
# PostgreSQL admin user (by default 'postgres') without any other option.
exec $SU -s /bin/sh postgres -c "$cmd"
fi
die () { echo >&2 "$*"; exit 1; }
test "$(id -u)" -eq 0 && exit 1
# ensure privacy
umask 0077
: ${RESTORECON=/sbin/restorecon}
test -x $RESTORECON || RESTORECON=:
test x"$PGSETUP_DEBUG" != x && set -x
# PGVERSION is the full package version, e.g., 9.0.2
# Note: the specfile inserts the correct value during package build
PGVERSION=9.2.24
# PGMAJORVERSION is the major version, e.g. 9.0
PGMAJORVERSION=9.2
# PGENGINE is the directory containing the postmaster executable
PGENGINE=/usr/bin
# PREVMAJORVERSION is the previous major version, e.g., 8.4, for upgrades
PREVMAJORVERSION=8.4
# PREVPGENGINE is the directory containing the previous postmaster executable
PREVPGENGINE=/usr/lib64/pgsql/postgresql-8.4/bin
USER=postgres
# Absorb configuration settings from the specified systemd service file,
# or the default "postgresql" service if not specified
SERVICE_NAME="$2"
if [ x"$SERVICE_NAME" = x ]; then
SERVICE_NAME=postgresql
fi
# Pathname of the RPM distribution README
README_RPM_DIST=/usr/share/doc/postgresql-9.2.24/README.rpm-dist
USAGE_STRING=$"
Usage: $0 {initdb|upgrade} [SERVICE_NAME]
Script is aimed to help sysadmin with basic database cluster administration.
The SERVICE_NAME is used for selection of proper unit configuration file; For
more info and howto/when use this script please look at the docu file
$README_RPM_DIST. The 'postgresql'
string is used when no SERVICE_NAME is explicitly passed.
Available operation mode:
initdb Create a new PostgreSQL database cluster. This is usually the
first action you perform after PostgreSQL server installation.
upgrade Upgrade PostgreSQL database cluster to be usable with new
server. Use this if you upgraded your PostgreSQL server to
newer major version (currently from $PREVMAJORVERSION \
to $PGMAJORVERSION).
Environment:
PGSETUP_INITDB_OPTIONS Options carried by this variable are passed to
subsequent call of \`initdb\` binary (see man
initdb(1)). This variable is used also during
'upgrade' mode because the new cluster is actually
re-initialized from the old one.
PGSETUP_PGUPGRADE_OPTIONS Options in this variable are passed next to the
subsequent call of \`pg_upgrade\`. For more info
about possible options please look at man
pg_upgrade(1).
PGSETUP_DEBUG Set to '1' if you want to see debugging output."
# note that these options are useful at least for help2man processing
case "$1" in
--version)
echo "postgresql-setup $PGVERSION"
exit 0
;;
--help|--usage)
echo "$USAGE_STRING"
exit 0
;;
esac
# this parsing technique fails for PGDATA pathnames containing spaces,
# but there's not much I can do about it given systemctl's output format...
PGDATA=`systemctl show -p Environment "${SERVICE_NAME}.service" |
sed 's/^Environment=//' | tr ' ' '\n' |
sed -n 's/^PGDATA=//p' | tail -n 1`
if [ x"$PGDATA" = x ]; then
echo "failed to find PGDATA setting in ${SERVICE_NAME}.service"
exit 1
fi
PGPORT=`systemctl show -p Environment "${SERVICE_NAME}.service" |
sed 's/^Environment=//' | tr ' ' '\n' |
sed -n 's/^PGPORT=//p' | tail -n 1`
if [ x"$PGPORT" = x ]; then
echo "failed to find PGPORT setting in ${SERVICE_NAME}.service"
exit 1
fi
# Log file for initdb
PGLOG=/var/lib/pgsql/initdb.log
# Log file for pg_upgrade
PGUPLOG=/var/lib/pgsql/pgupgrade.log
export PGDATA
export PGPORT
script_result=0
test -w /var/lib/pgsql || {
echo >&2 $"The /var/lib/pgsql directory has wrong permissions."
echo >&2 $"Please make sure the directory is writable by postgres."
exit 1
}
# code shared between initdb and upgrade actions
perform_initdb(){
if [ ! -e "$PGDATA" ]; then
mkdir "$PGDATA" || return 1
fi
$RESTORECON "$PGDATA"
test -w "$PGDATA" || die "$PGDATA is not writeable by $USER"
# Create the initdb log file if needed
if [ ! -e "$PGLOG" ]; then
touch "$PGLOG" || return 1
fi
$RESTORECON "$PGLOG"
test -w "$PGLOG" || echo "$PGLOG is not writeable by $USER"
# Initialize the database
initdbcmd=(
"$PGENGINE/initdb" --pgdata="$PGDATA"
--auth=ident
)
eval "initdbcmd+=( $PGSETUP_INITDB_OPTIONS )"
"${initdbcmd[@]}" >> "$PGLOG" 2>&1 < /dev/null
mkdir "$PGDATA/pg_log"
$RESTORECON "$PGDATA/pg_log"
if [ -f "$PGDATA/PG_VERSION" ]; then
return 0
fi
return 1
}
initdb(){
if [ -f "$PGDATA/PG_VERSION" ]; then
echo $"Data directory is not empty!"
echo
script_result=1
else
echo -n $"Initializing database ... "
if perform_initdb; then
echo $"OK"
else
echo $"failed, see $PGLOG"
script_result=1
fi
echo
fi
}
upgrade(){
# must see previous version in PG_VERSION
if [ ! -f "$PGDATA/PG_VERSION" -o \
x`cat "$PGDATA/PG_VERSION"` != x"$PREVMAJORVERSION" ]
then
echo
echo $"Cannot upgrade because the database in $PGDATA is not of"
echo $"compatible previous version $PREVMAJORVERSION."
echo
exit 1
fi
if [ ! -x "$PGENGINE/pg_upgrade" ]; then
echo
echo $"Please install the postgresql-upgrade RPM."
echo
exit 5
fi
# Set up log file for pg_upgrade
rm -f "$PGUPLOG"
touch "$PGUPLOG" || exit 1
$RESTORECON "$PGUPLOG"
# Move old DB to PGDATAOLD
PGDATAOLD="${PGDATA}-old"
rm -rf "$PGDATAOLD"
mv "$PGDATA" "$PGDATAOLD" || exit 1
# Create configuration file for upgrade process
HBA_CONF_BACKUP="$PGDATAOLD/pg_hba.conf.postgresql-setup.`date +%s`"
HBA_CONF_BACKUP_EXISTS=0
if [ ! -f $HBA_CONF_BACKUP ]; then
mv "$PGDATAOLD/pg_hba.conf" "$HBA_CONF_BACKUP"
HBA_CONF_BACKUP_EXISTS=1
# For fluent upgrade 'postgres' user should be able to connect
# to any database without password. Temporarily, no other type
# of connection is needed.
echo "local all postgres ident" > "$PGDATAOLD/pg_hba.conf"
fi
echo -n $"Upgrading database: "
# Create empty new-format database
if perform_initdb; then
eval "add_options=( $PGSETUP_PGUPGRADE_OPTIONS )"
# Do the upgrade
( cd # pg_upgrade writes to $PWD
"$PGENGINE/pg_upgrade" \
--old-bindir="$PREVPGENGINE" \
--new-bindir="$PGENGINE" \
--old-datadir="$PGDATAOLD" \
--new-datadir="$PGDATA" \
--link \
--old-port="$PGPORT" \
--new-port="$PGPORT" \
--user=postgres \
"${add_options[@]}" \
>> "$PGUPLOG" 2>&1 < /dev/null
)
if [ $? -ne 0 ]; then
# pg_upgrade failed
script_result=1
fi
else
# initdb failed
script_result=1
fi
# Move back the backed-up pg_hba.conf regardless of the script_result.
if [ x$HBA_CONF_BACKUP_EXISTS = x1 ]; then
mv -f "$HBA_CONF_BACKUP" "$PGDATAOLD/pg_hba.conf"
fi
if [ $script_result -eq 0 ]; then
echo $"OK"
echo
echo $"The configuration files were replaced by default configuration."
echo $"The previous configuration and data are stored in folder"
echo $PGDATAOLD.
else
# Clean up after failure
rm -rf "$PGDATA"
mv "$PGDATAOLD" "$PGDATA"
echo $"failed"
fi
echo
echo $"See $PGUPLOG for details."
}
# See how we were called.
case "$1" in
initdb)
initdb
;;
upgrade)
upgrade
;;
*)
echo >&2 "$USAGE_STRING"
exit 2
esac
exit $script_result
5tarL0rd By