-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathff-seq.sh
More file actions
72 lines (61 loc) · 2.73 KB
/
Copy pathff-seq.sh
File metadata and controls
72 lines (61 loc) · 2.73 KB
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
set -e
usage() {
printf "Usage: sh %s --primary \e[4mconninfo\e[0m --replica \e[4mconninfo\e[0m [--skip \e[4mseconds\e[0m] [--views]\n" "$(basename "$0")" >&2
printf " --primary \e[4mconninfo\e[0m connection information for the primary Postgres database whose sequences (or views) will be read\n" >&2
printf " --replica \e[4mconninfo\e[0m connection information for the replica Postgres database whose sequences will be fast-forwarded\n" >&2
printf " --skip \e[4mseconds\e[0m skip approximately \e[4mseconds\e[0m ahead in all sequences (default 3600)\n" >&2
printf " --views read views of sequences instead of the sequences themselves\n" >&2
exit "$1"
}
SKIP="3600" PRIMARY="" REPLICA="" VIEWS=""
while [ "$#" -gt 0 ]
do
case "$1" in
"-p"|"--primary") PRIMARY="$2" shift 2;;
"-p"*) PRIMARY="$(echo "$1" | cut -c"3-")" shift;;
"--primary="*) PRIMARY="$(echo "$1" | cut -d"=" -f"2-")" shift;;
"-r"|"--replica") REPLICA="$2" shift 2;;
"-r"*) REPLICA="$(echo "$1" | cut -c"3-")" shift;;
"--replica="*) REPLICA="$(echo "$1" | cut -d"=" -f"2-")" shift;;
"--skip") SKIP="$2" shift 2;;
"--skip="*) SKIP="$(echo "$1" | cut -d"=" -f"2-")" shift;;
"--views") VIEWS="--views" shift;;
"-h"|"--help") usage 0;;
*) usage 1;;
esac
done
if [ -z "$PRIMARY" -o -z "$REPLICA" -o -z "$SKIP" ]
then usage 1
fi
export PSQL_PAGER=""
set -x
# Fast-forward all the sequences on the replica well past their values on the
# primary. The gap here is precarious - if we don't fast-forward far enough we
# will generate duplicate values before completing the move. We sample 10
# seconds worth of sequence usage and then skip the anticipated number of
# values generated since the sampling plus the requested additional time to
# give the traffic-swinging deploy or transaction or whatever plenty of time.
SLEEP=10
psql "$REPLICA" -A -c '\ds' -t |
cut -d "|" -f "2" |
while read SEQ
do
if [ "$VIEWS" ]
then
SEQ_T0="$(psql "$PRIMARY" -A -c "SELECT ${SEQ}_view_nextval();" -t)"
sleep "$SLEEP"
SEQ_T1="$(psql "$PRIMARY" -A -c "SELECT ${SEQ}_view_nextval();" -t)"
else
SEQ_T0="$(psql "$PRIMARY" -A -c "SELECT nextval('$SEQ');" -t)"
sleep "$SLEEP"
SEQ_T1="$(psql "$PRIMARY" -A -c "SELECT nextval('$SEQ');" -t)"
fi
echo "$SEQ $(date +"%s") $SLEEP $SEQ_T0 $SEQ_T1"
done |
while read SEQ TS SLEEP SEQ_T0 SEQ_T1
do
psql "$REPLICA" -c "SELECT setval('$SEQ', $SEQ_T1 + (($(date +"%s") - $TS) / $SLEEP + $SKIP / $SLEEP ) * ($SEQ_T1 - $SEQ_T0 ));"
# (recent high-water mark) + (( sleeps since measured ) + (sleeps to skip)) * (nextval/sleep rate)
done
#psql "$PRIMARY"
#psql "$REPLICA"