summaryrefslogtreecommitdiffstats
path: root/postgresql-setup
blob: 8b2a9ce4c7403b6c360658ab39dea0c738bc4fa6 (plain)
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
196
197
198
199
#!/bin/sh
#
# postgresql-setup	Initialization and upgrade operations for PostgreSQL

# PGVERSION is the full package version, e.g., 9.0.2
# Note: the specfile inserts the correct value during package build
PGVERSION=xxxx
# PGENGINE is the directory containing the postmaster executable
# Note: the specfile inserts the correct value during package build
PGENGINE=xxxx
# PREVMAJORVERSION is the previous major version, e.g., 8.4, for upgrades
# Note: the specfile inserts the correct value during package build
PREVMAJORVERSION=xxxx
# PREVPGENGINE is the directory containing the previous postmaster executable
# Note: the specfile inserts the correct value during package build
PREVPGENGINE=xxxx

# 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

if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]
then
    SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
elif [ -f "/lib/systemd/system/${SERVICE_NAME}.service" ]
then
    SERVICE_FILE="/lib/systemd/system/${SERVICE_NAME}.service"
else
    echo "Could not find systemd unit file ${SERVICE_NAME}.service"
    exit 1
fi

# Get port number and data directory from the service file
PGPORT=`sed -n 's/Environment=PGPORT=//p' "${SERVICE_FILE}"`
PGDATA=`sed -n 's/Environment=PGDATA=//p' "${SERVICE_FILE}"`

# Log file for initdb
PGLOG=/var/lib/pgsql/initdb.log

# Log file for pg_upgrade
PGUPLOG=/var/lib/pgsql/pgupgrade.log

export PGPORT
export PGDATA

# For SELinux we need to use 'runuser' not 'su'
if [ -x /sbin/runuser ]
then
    SU=runuser
else
    SU=su
fi

script_result=0

# code shared between initdb and upgrade actions
perform_initdb(){
	if [ ! -e "$PGDATA" -a ! -h "$PGDATA" ]
	then
		mkdir -p "$PGDATA" || return 1
		chown postgres:postgres "$PGDATA"
		chmod go-rwx "$PGDATA"
	fi
	# Clean up SELinux tagging for PGDATA
	[ -x /sbin/restorecon ] && /sbin/restorecon "$PGDATA"

	# Create the initdb log file if needed
	if [ ! -e "$PGLOG" -a ! -h "$PGLOG" ]
	then
		touch "$PGLOG" || return 1
		chown postgres:postgres "$PGLOG"
		chmod go-rwx "$PGLOG"
		[ -x /sbin/restorecon ] && /sbin/restorecon "$PGLOG"
	fi

	# Initialize the database
	$SU -l postgres -c "$PGENGINE/initdb --pgdata='$PGDATA' --auth='ident'" >> "$PGLOG" 2>&1 < /dev/null

	# Create directory for postmaster log files
	mkdir "$PGDATA/pg_log"
	chown postgres:postgres "$PGDATA/pg_log"
	chmod go-rwx "$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 database is not of version $PREVMAJORVERSION."
	echo
	exit 1
    fi
    if [ ! -x "$PGENGINE/pg_upgrade" ]
    then
	echo
	echo $"Please install the postgresql-upgrade RPM."
	echo
	exit 5
    fi

    # Make sure service is stopped
    # Using service here makes it work both with systemd and other init systems
    service "$SERVICE_NAME" stop

    # Set up log file for pg_upgrade
    rm -f "$PGUPLOG"
    touch "$PGUPLOG" || exit 1
    chown postgres:postgres "$PGUPLOG"
    chmod go-rwx "$PGUPLOG"
    [ -x /sbin/restorecon ] && /sbin/restorecon "$PGUPLOG"

    # Move old DB to PGDATAOLD
    PGDATAOLD="${PGDATA}-old"
    rm -rf "$PGDATAOLD"
    mv "$PGDATA" "$PGDATAOLD" || exit 1

    echo -n $"Upgrading database: "

    # Create empty new-format database
    if perform_initdb
    then
	# Do the upgrade
	$SU -l postgres -c "$PGENGINE/pg_upgrade \
		'--old-bindir=$PREVPGENGINE' \
		'--new-bindir=$PGENGINE' \
		'--old-datadir=$PGDATAOLD' \
		'--new-datadir=$PGDATA' \
		--link \
		'--old-port=$PGPORT' '--new-port=$PGPORT' \
		--user=postgres" >> "$PGUPLOG" 2>&1 < /dev/null
	if [ $? -ne 0 ]
	then
	    # pg_upgrade failed
	    script_result=1
	fi
    else
	# initdb failed
	script_result=1
    fi

    if [ $script_result -eq 0 ]
    then
	    echo $"OK"
    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 $"Usage: $0 {initdb|upgrade} [ service_name ]"
	exit 2
esac

exit $script_result