Skip to content

Commit af3348d

Browse files
committed
(PDB-5672) Analyze reports every hour
postgres (up to at least 16) never analyzes partitioned table parents Nearly fixed in 14, but removed before release: https://www.postgresql.org/about/news/postgresql-14-beta-1-released-2213/ https://www.postgresql.org/about/news/postgresql-14-rc-1-released-2309/ Assumes the analysis runs quickly enough to avoid needing any enforced serialization, and to avoid (with the current single threaded executor) ever delaying gc enough to matter.
1 parent 443ca1e commit af3348d

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/puppetlabs/puppetdb/cli/services.clj

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@
3838
data may linger in the database. We periodically sweep the
3939
database, compacting it and performing regular cleanup so we can
4040
maintain acceptable performance."
41-
(:require [clojure.string :as str]
41+
(:require [clojure.java.jdbc :as sql]
42+
[clojure.string :as str]
4243
[clojure.tools.logging :as log]
4344
[metrics.counters :as counters :refer [counter inc!]]
4445
[metrics.gauges :refer [gauge-fn]]
4546
[metrics.timers :refer [time! timer]]
4647
[metrics.reporters.jmx :as jmx-reporter]
4748
[murphy :refer [try! with-final]]
49+
[next.jdbc :as nxt]
4850
[puppetlabs.i18n.core :refer [trs tru]]
4951
[puppetlabs.kitchensink.core :as kitchensink]
5052
[puppetlabs.puppetdb.cli.tk-util :refer [run-tk-cli-cmd]]
@@ -939,6 +941,21 @@
939941
(catch InterruptedException _
940942
(log/info (trs "Garbage collector interrupted")))))))
941943

944+
(defn analyze-partitioned-tables [db shutdown-for-ex]
945+
(with-nonfatal-exceptions-suppressed
946+
(with-monitored-execution shutdown-for-ex
947+
(try!
948+
(jdbc/with-db-connection db
949+
(jdbc/with-db-transaction []
950+
(let [c (sql/db-connection jdbc/*db*)]
951+
(doseq [table ["reports" "resource_events"]]
952+
(try!
953+
(nxt/execute! c [(str "analyze " table)])
954+
(catch InterruptedException _
955+
(log/info (trs (str table " analysis interrupted")))))))))
956+
(catch Exception ex
957+
(log/error ex))))))
958+
942959
(defn start-garbage-collection
943960
"Starts garbage collection of the databases represented in db-configs"
944961
[{:keys [clean-lock] :as _context}
@@ -952,7 +969,18 @@
952969
(schedule-with-fixed-delay sched #(invoke-periodic-gc db cfg request
953970
shutdown-for-ex
954971
clean-lock lock-status)
955-
(to-millis interval) (to-millis interval)))))))
972+
(to-millis interval) (to-millis interval))))
973+
;; pg (up to at least 16) never analyzes partitioned table parents
974+
;; Nearly fixed in 14, but removed before release:
975+
;; https://www.postgresql.org/about/news/postgresql-14-beta-1-released-2213/
976+
;; https://www.postgresql.org/about/news/postgresql-14-rc-1-released-2309/
977+
;;
978+
;; Assumes the analysis runs quickly enough to avoid needing any
979+
;; enforced serialization, and to avoid (with the current single
980+
;; threaded executor) ever delaying gc enough to matter.
981+
(let [hourly (* 60 60 1000)
982+
analyze #(analyze-partitioned-tables db shutdown-for-ex)]
983+
(schedule-with-fixed-delay sched analyze 0 hourly)))))
956984

957985

958986
(defn database-lock-status []

test/puppetlabs/puppetdb/cli/services_test.clj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns puppetlabs.puppetdb.cli.services-test
22
(:require [clojure.set :refer [subset?]]
3+
[next.jdbc.plan :refer [select-one!]]
34
[puppetlabs.http.client.sync :as pl-http]
45
[puppetlabs.puppetdb.cli.util :refer [err-exit-status]]
56
[puppetlabs.puppetdb.command.constants :as cmd-consts]
@@ -620,3 +621,30 @@
620621
:db-lock-status db-lock-status})
621622
(is (= 1 (count (jdbc/query ["SELECT * FROM reports_latest"]))))
622623
(is (empty? (jdbc/query ["SELECT * FROM reports_historical"])))))))))
624+
625+
(deftest reports-analysis
626+
;; For now, just test for the initial invocation
627+
(let [start (now)
628+
is-analyzed
629+
(fn is-analyzed
630+
([table] (is-analyzed table 0))
631+
([table i]
632+
(let [r (jdbc/with-db-transaction []
633+
(->> [(str "select last_analyze, last_autoanalyze"
634+
" from pg_stat_user_tables where relname = '" table "'")]
635+
(select-one! (jdbc/connection) [:last_analyze :last_autoanalyze])))
636+
last-ms (some-> r :last_analyze .getTime time/from-long)]
637+
(if (and last-ms (nil? (:last_autoanalyze r)))
638+
(do
639+
(is (= nil (:last_autoanalyze r)))
640+
(is (time/after? last-ms start)))
641+
(if (= i 100)
642+
(is false (str table " was eventually analyzed"))
643+
(do
644+
(Thread/sleep 100)
645+
(is-analyzed table (inc i))))))))]
646+
(svc-utils/with-puppetdb-instance
647+
(doseq [parent ["reports" "reports_historical" "reports_latest"
648+
"resource_events" "resource_events_historical" "resource_events_latest"]]
649+
(testing (str parent " analysis times")
650+
(is-analyzed parent))))))

0 commit comments

Comments
 (0)