-
Notifications
You must be signed in to change notification settings - Fork 4
/
pg-ps.sh
executable file
·122 lines (104 loc) · 3.75 KB
/
pg-ps.sh
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
#!/bin/bash
K8S_UTILS_DIR="${BASH_SOURCE%/*}"
source ${K8S_UTILS_DIR}/helpers.sh
function show_help {
echo "
ktl pg:ps -istaging -utalkinto -dtalkinto [-nkube-system -h -v]
View active queries with execution time.
Options:
-iINSTANCE_NAME Cloud SQL Instance name to which connection is established. Required.
-uUSERNAME PostgreSQL user name which would be used to log in. Required.
-nNAMESPACE Namespace for a pod that exposes PostgreSQL instance. Default: kube-system.
-dpostgres Database name to use. Required.
-h Show help and exit.
-v Verbose output, includes idle transactions.
Examples:
ktl pg:ps -istaging -utalkinto -dtalkinto
Available databases:
"
list_sql_proxy_users "ktl pg:ps -i\(.metadata.labels.instance_name) -u\(.data.username | @base64d) -d\$DATABASE_NAME" " "
}
PORT=$(get_free_random_port)
POSTGRES_DB="postgres"
PROXY_POD_NAMESPACE="kube-system"
VERBOSE="AND state <> 'idle'"
# Read configuration from CLI
while getopts "hn:i:u:d:v" opt; do
case "$opt" in
n) PROXY_POD_NAMESPACE="--namespace=${OPTARG}"
;;
i) INSTANCE_NAME="${OPTARG}"
;;
u) POSTGRES_USER="${OPTARG}"
;;
d) POSTGRES_DB="${OPTARG}"
;;
h) show_help
exit 0
;;
v) VERBOSE=""
;;
esac
done
if [[ "${INSTANCE_NAME}" == "" ]]; then
error "Instance name is not set, use -i option to set it or -h for list of available values"
fi
if [[ "${POSTGRES_USER}" == "" ]]; then
error "User name is not set, use -u option to set it or -h for list of available values"
fi
if [[ "${POSTGRES_DB}" == "" ]]; then
error "Posgres database is not set, use -d option."
fi
log_step "Selecting Cloud SQL proxy pod"
PROXY_POD_NAME=$(fetch_pod_name "${PROXY_POD_NAMESPACE}" "instance_name=${INSTANCE_NAME}")
POSTGRES_PASSWORD=$(get_postgres_user_password "${INSTANCE_NAME}" "${POSTGRES_USER}")
POSTGRES_CONNECTION_STRING=$(get_postgres_connection_url "${POSTGRES_USER}" "${POSTGRES_PASSWORD}" ${PORT} "${POSTGRES_DB}")
tunnel_postgres_connections "${PROXY_POD_NAMESPACE}" "${PROXY_POD_NAME}" ${PORT}
WAIT_RAND=$(awk 'BEGIN{srand();print int(rand()*(63000-2000))+2000 }')
WAIT_RETURN=$(
psql "${POSTGRES_CONNECTION_STRING}" --no-psqlrc --command "SELECT '${WAIT_RAND}' || '${WAIT_RAND}' WHERE EXISTS (
SELECT 1 FROM information_schema.columns WHERE table_schema = 'pg_catalog'
AND table_name = 'pg_stat_activity'
AND column_name = 'waiting'
)
"
)
if [[ "${WAIT_RETURN}" = *"${WAIT_RAND}${WAIT_RAND}"* ]]; then
WAITING="waiting"
else
WAITING="wait_event IS NOT NULL AS waiting"
fi
echo "Active queries: "
psql "${POSTGRES_CONNECTION_STRING}" --no-psqlrc --command "
SELECT
pid,
state,
application_name AS source,
usename AS username,
age(now(),xact_start) AS running_for,
xact_start AS transaction_start,
${WAITING},
query
FROM pg_stat_activity
WHERE query <> '<insufficient privilege>'
${VERBOSE}
AND pid <> pg_backend_pid()
ORDER BY query_start DESC
"
echo "Queries with active locks: "
psql "${POSTGRES_CONNECTION_STRING}" --no-psqlrc --command "
SELECT
pg_stat_activity.pid,
pg_class.relname,
pg_locks.transactionid,
pg_locks.granted,
CASE WHEN length(pg_stat_activity.query) <= 40 THEN pg_stat_activity.query ELSE substr(pg_stat_activity.query, 0, 39) || '…' END AS query_snippet,
age(now(),pg_stat_activity.query_start) AS lock_age
FROM pg_stat_activity,pg_locks left
OUTER JOIN pg_class
ON (pg_locks.relation = pg_class.oid)
WHERE pg_stat_activity.query <> '<insufficient privilege>'
AND pg_locks.pid = pg_stat_activity.pid
AND pg_locks.mode = 'ExclusiveLock'
AND pg_stat_activity.pid <> pg_backend_pid() order by query_start;
"