mahout 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/config/mahout.example.yml +55 -0
- data/config/templates/datadog-pgbackrest-check.py +54 -0
- data/config/templates/datadog-postgres.yaml.erb +29 -0
- data/config/templates/pg_hba.conf.erb +8 -0
- data/config/templates/pgbackrest.conf.erb +24 -0
- data/config/templates/pgbouncer.ini.erb +13 -0
- data/config/templates/postgresql.conf.erb +80 -0
- data/exe/mahout +6 -0
- data/lib/mahout/backup.rb +51 -0
- data/lib/mahout/benchmark.rb +464 -0
- data/lib/mahout/cli.rb +577 -0
- data/lib/mahout/config.rb +322 -0
- data/lib/mahout/disk_benchmark.rb +172 -0
- data/lib/mahout/extension_registry.rb +144 -0
- data/lib/mahout/health.rb +372 -0
- data/lib/mahout/remote.rb +142 -0
- data/lib/mahout/restore.rb +88 -0
- data/lib/mahout/runner.rb +81 -0
- data/lib/mahout/setup/datadog.rb +116 -0
- data/lib/mahout/setup/extensions.rb +51 -0
- data/lib/mahout/setup/hardening.rb +109 -0
- data/lib/mahout/setup/os.rb +198 -0
- data/lib/mahout/setup/pgbackrest.rb +125 -0
- data/lib/mahout/setup/pgbouncer.rb +32 -0
- data/lib/mahout/setup/postgres.rb +140 -0
- data/lib/mahout/setup/ssl.rb +29 -0
- data/lib/mahout/setup/systemd.rb +205 -0
- data/lib/mahout/status.rb +99 -0
- data/lib/mahout/step_runner.rb +321 -0
- data/lib/mahout/tuner.rb +174 -0
- data/lib/mahout/version.rb +3 -0
- data/lib/mahout.rb +51 -0
- metadata +180 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mahout
|
|
4
|
+
module Setup
|
|
5
|
+
class Postgres
|
|
6
|
+
def call(runner, config, tuned)
|
|
7
|
+
stop_existing(runner, config)
|
|
8
|
+
init_cluster(runner, config)
|
|
9
|
+
render_config(runner, config, tuned)
|
|
10
|
+
start_postgres(runner, config)
|
|
11
|
+
create_tablespace(runner, config)
|
|
12
|
+
create_database(runner, config)
|
|
13
|
+
create_user(runner, config)
|
|
14
|
+
set_connection_limit(runner, config, tuned)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def stop_existing(runner, config)
|
|
20
|
+
runner.run("systemctl stop postgresql", allow_failure: true)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def init_cluster(runner, config)
|
|
24
|
+
result = runner.run("test -f #{config.pg_data_dir}/PG_VERSION", allow_failure: true)
|
|
25
|
+
return if result.success?
|
|
26
|
+
|
|
27
|
+
runner.run("pg_dropcluster --stop #{config.pg_version} main", allow_failure: true)
|
|
28
|
+
runner.run("find #{config.data_mount}/tablespace -mindepth 1 -delete", allow_failure: true)
|
|
29
|
+
|
|
30
|
+
waldir_flag = config.pg_wal_dir ? "--waldir=#{config.pg_wal_dir}" : ""
|
|
31
|
+
runner.run(
|
|
32
|
+
"pg_createcluster #{config.pg_version} main " \
|
|
33
|
+
"--datadir=#{config.pg_data_dir} " \
|
|
34
|
+
"-- --auth-local=peer --auth-host=scram-sha-256 #{waldir_flag}"
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def render_config(runner, config, tuned)
|
|
39
|
+
tuned ||= {}
|
|
40
|
+
extensions = ExtensionRegistry.resolve(config.extensions, pg_version: config.pg_version)
|
|
41
|
+
preload = ExtensionRegistry.preload_libraries(extensions)
|
|
42
|
+
preload << "pg_prewarm" unless preload.include?("pg_prewarm")
|
|
43
|
+
|
|
44
|
+
runner.render_and_upload(
|
|
45
|
+
"postgresql.conf.erb",
|
|
46
|
+
"/etc/postgresql/#{config.pg_version}/main/postgresql.conf",
|
|
47
|
+
locals: {
|
|
48
|
+
config: config,
|
|
49
|
+
tuned: tuned,
|
|
50
|
+
preload_libraries: preload
|
|
51
|
+
},
|
|
52
|
+
owner: "postgres:postgres"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
runner.run("mkdir -p /etc/postgresql/#{config.pg_version}/main/conf.d")
|
|
56
|
+
runner.run("chown postgres:postgres /etc/postgresql/#{config.pg_version}/main/conf.d")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def start_postgres(runner, config)
|
|
60
|
+
runner.run("systemctl enable postgresql")
|
|
61
|
+
runner.run("systemctl start postgresql", allow_failure: true)
|
|
62
|
+
sleep(2) unless runner.dry_run?
|
|
63
|
+
|
|
64
|
+
ready = runner.run("pg_isready --timeout=10", allow_failure: true)
|
|
65
|
+
return if ready.success?
|
|
66
|
+
|
|
67
|
+
pg_log = runner.run("tail -10 /var/log/postgresql/postgresql-#{config.pg_version}-main.log", allow_failure: true)
|
|
68
|
+
|
|
69
|
+
if pg_log.stdout.include?("huge pages") || pg_log.stdout.include?("Cannot allocate memory")
|
|
70
|
+
$stdout.puts("postgres failed to start with huge_pages = on, falling back to huge_pages = try")
|
|
71
|
+
conf_path = "/etc/postgresql/#{config.pg_version}/main/postgresql.conf"
|
|
72
|
+
runner.run("sed -i 's/huge_pages = on/huge_pages = try/' #{conf_path}")
|
|
73
|
+
runner.run("systemctl restart postgresql", allow_failure: true)
|
|
74
|
+
sleep(2) unless runner.dry_run?
|
|
75
|
+
ready = runner.run("pg_isready --timeout=30", allow_failure: true)
|
|
76
|
+
raise RemoteError, "postgresql failed to start even with huge_pages = try\n#{pg_log.stdout}" unless ready.success?
|
|
77
|
+
else
|
|
78
|
+
raise RemoteError, "postgresql failed to start\n#{pg_log.stdout}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def create_tablespace(runner, config)
|
|
83
|
+
result = runner.run(
|
|
84
|
+
"sudo -u postgres psql -tAc \"SELECT 1 FROM pg_tablespace WHERE spcname = 'mahout_data'\"",
|
|
85
|
+
sudo: false, allow_failure: true
|
|
86
|
+
)
|
|
87
|
+
return if result.stdout.strip == "1"
|
|
88
|
+
|
|
89
|
+
runner.run("find #{config.data_mount}/tablespace -mindepth 1 -delete", allow_failure: true)
|
|
90
|
+
runner.run("mkdir -p #{config.data_mount}/tablespace")
|
|
91
|
+
runner.run("chown postgres:postgres #{config.data_mount}/tablespace")
|
|
92
|
+
runner.run(
|
|
93
|
+
"sudo -u postgres psql -c \"CREATE TABLESPACE mahout_data LOCATION '#{config.data_mount}/tablespace'\"",
|
|
94
|
+
sudo: false
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def create_database(runner, config)
|
|
99
|
+
runner.run(
|
|
100
|
+
"sudo -u postgres psql -tc " \
|
|
101
|
+
"\"SELECT 1 FROM pg_database WHERE datname = '#{config.pg_database}'\" | grep -q 1 || " \
|
|
102
|
+
"sudo -u postgres createdb #{config.pg_database} --tablespace=mahout_data",
|
|
103
|
+
sudo: false
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def create_user(runner, config)
|
|
108
|
+
password = config.secret("pg_password")
|
|
109
|
+
|
|
110
|
+
result = runner.run(
|
|
111
|
+
"sudo -u postgres psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname = '#{config.pg_username}'\"",
|
|
112
|
+
sudo: false, allow_failure: true
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
unless result.stdout.strip == "1"
|
|
116
|
+
escaped_password = password.to_s.gsub("'", "''")
|
|
117
|
+
sql = "CREATE USER #{config.pg_username} WITH PASSWORD '#{escaped_password}';"
|
|
118
|
+
runner.upload(sql, "/tmp/mahout-create-user.sql", mode: "0600", owner: "postgres:postgres")
|
|
119
|
+
runner.run("sudo -u postgres psql -f /tmp/mahout-create-user.sql", sudo: false)
|
|
120
|
+
runner.run("rm -f /tmp/mahout-create-user.sql")
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
runner.run(
|
|
124
|
+
"sudo -u postgres psql -c " \
|
|
125
|
+
"\"GRANT ALL PRIVILEGES ON DATABASE #{config.pg_database} TO #{config.pg_username}\"",
|
|
126
|
+
sudo: false
|
|
127
|
+
)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def set_connection_limit(runner, config, tuned)
|
|
131
|
+
max_conn = tuned&.dig(:max_connections) || 200
|
|
132
|
+
app_limit = (max_conn * 0.8).to_i
|
|
133
|
+
runner.run(
|
|
134
|
+
"sudo -u postgres psql -c \"ALTER USER #{config.pg_username} CONNECTION LIMIT #{app_limit}\"",
|
|
135
|
+
sudo: false
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mahout
|
|
4
|
+
module Setup
|
|
5
|
+
class Ssl
|
|
6
|
+
def call(runner, config, _tuned)
|
|
7
|
+
cert_dir = "/etc/postgresql/#{config.pg_version}/main"
|
|
8
|
+
pg_conf = "#{cert_dir}/postgresql.conf"
|
|
9
|
+
|
|
10
|
+
runner.run(
|
|
11
|
+
"openssl req -new -x509 -days 3650 -nodes " \
|
|
12
|
+
"-out #{cert_dir}/server.crt " \
|
|
13
|
+
"-keyout #{cert_dir}/server.key " \
|
|
14
|
+
"-subj /CN=#{config.instance_name}"
|
|
15
|
+
)
|
|
16
|
+
runner.run("chmod 0600 #{cert_dir}/server.key")
|
|
17
|
+
runner.run("chown postgres:postgres #{cert_dir}/server.crt #{cert_dir}/server.key")
|
|
18
|
+
|
|
19
|
+
ssl_conf = <<~CONF
|
|
20
|
+
ssl = on
|
|
21
|
+
ssl_cert_file = '#{cert_dir}/server.crt'
|
|
22
|
+
ssl_key_file = '#{cert_dir}/server.key'
|
|
23
|
+
CONF
|
|
24
|
+
runner.upload(ssl_conf, "/etc/postgresql/#{config.pg_version}/main/conf.d/ssl.conf", owner: "postgres:postgres")
|
|
25
|
+
runner.run("systemctl reload postgresql")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mahout
|
|
4
|
+
module Setup
|
|
5
|
+
class Systemd
|
|
6
|
+
def call(runner, config, _tuned)
|
|
7
|
+
if config.pgbackrest_enabled?
|
|
8
|
+
install_backup_units(runner, config)
|
|
9
|
+
install_verify_timer(runner, config)
|
|
10
|
+
install_wal_check(runner, config)
|
|
11
|
+
end
|
|
12
|
+
install_health_check(runner, config)
|
|
13
|
+
install_oom_override(runner, config)
|
|
14
|
+
install_stats_reset_timer(runner)
|
|
15
|
+
runner.run("systemctl daemon-reload")
|
|
16
|
+
enable_timers(runner, config)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def install_backup_units(runner, config)
|
|
22
|
+
stanza = config.pgbackrest_stanza
|
|
23
|
+
|
|
24
|
+
%w[full diff incr].each do |type|
|
|
25
|
+
service = <<~UNIT
|
|
26
|
+
[Unit]
|
|
27
|
+
Description=pgBackRest #{type} backup
|
|
28
|
+
After=postgresql.service
|
|
29
|
+
|
|
30
|
+
[Service]
|
|
31
|
+
Type=oneshot
|
|
32
|
+
User=postgres
|
|
33
|
+
ExecStart=/usr/bin/pgbackrest --stanza=#{stanza} --type=#{type} backup
|
|
34
|
+
UNIT
|
|
35
|
+
|
|
36
|
+
calendar = case type
|
|
37
|
+
when "full" then config.pgbackrest_schedule_full
|
|
38
|
+
when "diff" then config.pgbackrest_schedule_diff
|
|
39
|
+
when "incr" then config.pgbackrest_schedule_incr
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
timer = <<~UNIT
|
|
43
|
+
[Unit]
|
|
44
|
+
Description=pgBackRest #{type} backup timer
|
|
45
|
+
|
|
46
|
+
[Timer]
|
|
47
|
+
OnCalendar=#{calendar}
|
|
48
|
+
Persistent=true
|
|
49
|
+
|
|
50
|
+
[Install]
|
|
51
|
+
WantedBy=timers.target
|
|
52
|
+
UNIT
|
|
53
|
+
|
|
54
|
+
runner.upload(service, "/etc/systemd/system/pgbackrest-#{type}-backup.service")
|
|
55
|
+
runner.upload(timer, "/etc/systemd/system/pgbackrest-#{type}-backup.timer")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def install_verify_timer(runner, config)
|
|
60
|
+
stanza = config.pgbackrest_stanza
|
|
61
|
+
|
|
62
|
+
service = <<~UNIT
|
|
63
|
+
[Unit]
|
|
64
|
+
Description=pgBackRest verify
|
|
65
|
+
After=postgresql.service
|
|
66
|
+
|
|
67
|
+
[Service]
|
|
68
|
+
Type=oneshot
|
|
69
|
+
User=postgres
|
|
70
|
+
ExecStart=/usr/bin/pgbackrest --stanza=#{stanza} verify
|
|
71
|
+
UNIT
|
|
72
|
+
|
|
73
|
+
timer = <<~UNIT
|
|
74
|
+
[Unit]
|
|
75
|
+
Description=pgBackRest weekly verify timer
|
|
76
|
+
|
|
77
|
+
[Timer]
|
|
78
|
+
OnCalendar=Sun *-*-* 04:00:00
|
|
79
|
+
Persistent=true
|
|
80
|
+
|
|
81
|
+
[Install]
|
|
82
|
+
WantedBy=timers.target
|
|
83
|
+
UNIT
|
|
84
|
+
|
|
85
|
+
runner.upload(service, "/etc/systemd/system/pgbackrest-verify.service")
|
|
86
|
+
runner.upload(timer, "/etc/systemd/system/pgbackrest-verify.timer")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def install_wal_check(runner, config)
|
|
90
|
+
stanza = config.pgbackrest_stanza
|
|
91
|
+
|
|
92
|
+
service = <<~UNIT
|
|
93
|
+
[Unit]
|
|
94
|
+
Description=pgBackRest WAL archive check
|
|
95
|
+
After=postgresql.service
|
|
96
|
+
|
|
97
|
+
[Service]
|
|
98
|
+
Type=oneshot
|
|
99
|
+
User=postgres
|
|
100
|
+
ExecStart=/usr/bin/pgbackrest --stanza=#{stanza} check
|
|
101
|
+
UNIT
|
|
102
|
+
|
|
103
|
+
timer = <<~UNIT
|
|
104
|
+
[Unit]
|
|
105
|
+
Description=pgBackRest WAL archive check timer
|
|
106
|
+
|
|
107
|
+
[Timer]
|
|
108
|
+
OnCalendar=*-*-* *:00/5:00
|
|
109
|
+
Persistent=true
|
|
110
|
+
|
|
111
|
+
[Install]
|
|
112
|
+
WantedBy=timers.target
|
|
113
|
+
UNIT
|
|
114
|
+
|
|
115
|
+
runner.upload(service, "/etc/systemd/system/pgbackrest-wal-check.service")
|
|
116
|
+
runner.upload(timer, "/etc/systemd/system/pgbackrest-wal-check.timer")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def install_health_check(runner, config)
|
|
120
|
+
service = <<~UNIT
|
|
121
|
+
[Unit]
|
|
122
|
+
Description=mahout health check
|
|
123
|
+
After=postgresql.service
|
|
124
|
+
|
|
125
|
+
[Service]
|
|
126
|
+
Type=oneshot
|
|
127
|
+
ExecStart=/bin/bash -c 'pg_isready -q && echo ok > /var/log/mahout/health.status || echo fail > /var/log/mahout/health.status'
|
|
128
|
+
UNIT
|
|
129
|
+
|
|
130
|
+
timer = <<~UNIT
|
|
131
|
+
[Unit]
|
|
132
|
+
Description=mahout health check timer
|
|
133
|
+
|
|
134
|
+
[Timer]
|
|
135
|
+
OnCalendar=*-*-* *:*:00
|
|
136
|
+
Persistent=true
|
|
137
|
+
|
|
138
|
+
[Install]
|
|
139
|
+
WantedBy=timers.target
|
|
140
|
+
UNIT
|
|
141
|
+
|
|
142
|
+
runner.run("mkdir -p /var/log/mahout")
|
|
143
|
+
runner.upload(service, "/etc/systemd/system/pg-health-check.service")
|
|
144
|
+
runner.upload(timer, "/etc/systemd/system/pg-health-check.timer")
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def install_oom_override(runner, config)
|
|
148
|
+
runner.run("mkdir -p /etc/systemd/system/postgresql.service.d")
|
|
149
|
+
dropin = <<~UNIT
|
|
150
|
+
[Service]
|
|
151
|
+
OOMScoreAdjust=-1000
|
|
152
|
+
UNIT
|
|
153
|
+
runner.upload(dropin, "/etc/systemd/system/postgresql.service.d/oom.conf")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def install_stats_reset_timer(runner)
|
|
157
|
+
service = <<~UNIT
|
|
158
|
+
[Unit]
|
|
159
|
+
Description=Reset pg_stat_statements
|
|
160
|
+
After=postgresql.service
|
|
161
|
+
|
|
162
|
+
[Service]
|
|
163
|
+
Type=oneshot
|
|
164
|
+
ExecStart=/usr/bin/sudo -u postgres psql -c "SELECT pg_stat_statements_reset()"
|
|
165
|
+
UNIT
|
|
166
|
+
|
|
167
|
+
timer = <<~UNIT
|
|
168
|
+
[Unit]
|
|
169
|
+
Description=Weekly pg_stat_statements reset
|
|
170
|
+
|
|
171
|
+
[Timer]
|
|
172
|
+
OnCalendar=Mon *-*-* 03:00:00
|
|
173
|
+
Persistent=true
|
|
174
|
+
|
|
175
|
+
[Install]
|
|
176
|
+
WantedBy=timers.target
|
|
177
|
+
UNIT
|
|
178
|
+
|
|
179
|
+
runner.upload(service, "/etc/systemd/system/pg-stats-reset.service")
|
|
180
|
+
runner.upload(timer, "/etc/systemd/system/pg-stats-reset.timer")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def enable_timers(runner, config)
|
|
184
|
+
timers = %w[
|
|
185
|
+
pg-health-check.timer
|
|
186
|
+
pg-stats-reset.timer
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
if config.pgbackrest_enabled?
|
|
190
|
+
timers.unshift(
|
|
191
|
+
"pgbackrest-full-backup.timer",
|
|
192
|
+
"pgbackrest-diff-backup.timer",
|
|
193
|
+
"pgbackrest-incr-backup.timer",
|
|
194
|
+
"pgbackrest-verify.timer",
|
|
195
|
+
"pgbackrest-wal-check.timer"
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
timers.each do |timer|
|
|
200
|
+
runner.run("systemctl enable --now #{timer}")
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mahout
|
|
4
|
+
class Status
|
|
5
|
+
def initialize(runner:, config:)
|
|
6
|
+
@runner = runner
|
|
7
|
+
@config = config
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
show_pg_info
|
|
12
|
+
show_disk_usage
|
|
13
|
+
show_connections
|
|
14
|
+
show_backup_info if @config.pgbackrest_enabled?
|
|
15
|
+
show_pgbouncer_stats
|
|
16
|
+
show_extensions
|
|
17
|
+
show_timer_status
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def show_pg_info
|
|
23
|
+
result = @runner.run(
|
|
24
|
+
"sudo -u postgres psql -tAc \"SELECT version()\"",
|
|
25
|
+
sudo: false, allow_failure: true
|
|
26
|
+
)
|
|
27
|
+
$stdout.puts("postgresql: #{result.stdout.strip.split(" ").first(2).join(" ")}") if result.success?
|
|
28
|
+
|
|
29
|
+
result = @runner.run(
|
|
30
|
+
"sudo -u postgres psql -tAc \"SELECT now() - pg_postmaster_start_time()\"",
|
|
31
|
+
sudo: false, allow_failure: true
|
|
32
|
+
)
|
|
33
|
+
$stdout.puts("uptime: #{result.stdout.strip}") if result.success?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def show_disk_usage
|
|
37
|
+
[@config.data_mount, @config.wal_mount].compact.each do |mount|
|
|
38
|
+
result = @runner.run("df -h --output=size,used,avail,pcent #{mount} | tail -1", allow_failure: true)
|
|
39
|
+
$stdout.puts("disk #{mount}: #{result.stdout.strip}") if result.success?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def show_connections
|
|
44
|
+
result = @runner.run(
|
|
45
|
+
"sudo -u postgres psql -tAc \"SELECT count(*) || '/' || current_setting('max_connections') FROM pg_stat_activity\"",
|
|
46
|
+
sudo: false, allow_failure: true
|
|
47
|
+
)
|
|
48
|
+
$stdout.puts("connections: #{result.stdout.strip}") if result.success?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def show_backup_info
|
|
52
|
+
result = @runner.run(
|
|
53
|
+
"sudo -u postgres pgbackrest --stanza=#{@config.pgbackrest_stanza} info --output json",
|
|
54
|
+
sudo: false, allow_failure: true
|
|
55
|
+
)
|
|
56
|
+
return unless result.success? && !result.stdout.strip.empty?
|
|
57
|
+
|
|
58
|
+
info = JSON.parse(result.stdout) rescue return
|
|
59
|
+
backups = info.dig(0, "backup")
|
|
60
|
+
return $stdout.puts("backups: none") if backups.nil? || backups.empty?
|
|
61
|
+
|
|
62
|
+
latest = backups.last
|
|
63
|
+
$stdout.puts("last backup: #{latest["type"]} at #{Time.at(latest.dig("timestamp", "stop")).utc}")
|
|
64
|
+
$stdout.puts("total backups: #{backups.length}")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def show_pgbouncer_stats
|
|
68
|
+
result = @runner.run(
|
|
69
|
+
"psql -h 127.0.0.1 -p #{@config.pgbouncer_port} -U #{@config.pg_username} pgbouncer -tAc 'SHOW POOLS' 2>&1",
|
|
70
|
+
sudo: false, allow_failure: true
|
|
71
|
+
)
|
|
72
|
+
if result.success?
|
|
73
|
+
$stdout.puts("pgbouncer: active")
|
|
74
|
+
else
|
|
75
|
+
$stdout.puts("pgbouncer: not responding")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def show_extensions
|
|
80
|
+
result = @runner.run(
|
|
81
|
+
"sudo -u postgres psql -d #{@config.pg_database} -tAc \"SELECT extname || ' ' || extversion FROM pg_extension ORDER BY extname\"",
|
|
82
|
+
sudo: false, allow_failure: true
|
|
83
|
+
)
|
|
84
|
+
return unless result.success?
|
|
85
|
+
|
|
86
|
+
exts = result.stdout.strip.split("\n").reject(&:empty?)
|
|
87
|
+
$stdout.puts("extensions: #{exts.join(", ")}")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def show_timer_status
|
|
91
|
+
result = @runner.run("systemctl list-timers --no-pager pgbackrest-* pg-* 2>/dev/null | head -10", allow_failure: true)
|
|
92
|
+
return unless result.success? && !result.stdout.strip.empty?
|
|
93
|
+
|
|
94
|
+
$stdout.puts("")
|
|
95
|
+
$stdout.puts("timers:")
|
|
96
|
+
$stdout.puts(result.stdout.strip)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|