master
go 189 lines 3.58 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package postgres
4
5 import (
6 "database/sql"
7 "strconv"
8
9 "github.com/jackc/pgx/v5/stdlib"
10 )
11
12 func (c *Collector) doQueryServerVersion() (int, error) {
13 q := queryServerVersion()
14
15 var s string
16 if err := c.doQueryRow(q, &s); err != nil {
17 return 0, err
18 }
19
20 return strconv.Atoi(s)
21 }
22
23 func (c *Collector) doQueryIsSuperUser() (bool, error) {
24 q := queryIsSuperUser()
25
26 var v bool
27 if err := c.doQueryRow(q, &v); err != nil {
28 return false, err
29 }
30
31 return v, nil
32 }
33
34 func (c *Collector) doQueryCanExecutePgLsDir() (bool, error) {
35 q := queryCanExecutePgLsDir()
36
37 var v bool
38 if err := c.doQueryRow(q, &v); err != nil {
39 return false, err
40 }
41
42 return v, nil
43 }
44
45 func (c *Collector) doQueryPGIsInRecovery() (bool, error) {
46 q := queryPGIsInRecovery()
47
48 var v bool
49 if err := c.doQueryRow(q, &v); err != nil {
50 return false, err
51 }
52
53 return v, nil
54 }
55
56 func (c *Collector) doQuerySettingsMaxConnections() (int64, error) {
57 q := querySettingsMaxConnections()
58
59 var s string
60 if err := c.doQueryRow(q, &s); err != nil {
61 return 0, err
62 }
63
64 return strconv.ParseInt(s, 10, 64)
65 }
66
67 func (c *Collector) doQuerySettingsMaxLocksHeld() (int64, error) {
68 q := querySettingsMaxLocksHeld()
69
70 var s string
71 if err := c.doQueryRow(q, &s); err != nil {
72 return 0, err
73 }
74
75 return strconv.ParseInt(s, 10, 64)
76 }
77
78 const connErrMax = 3
79
80 var unregisterConnConfig = stdlib.UnregisterConnConfig
81
82 func closeDBAndUnregisterConnConfig(db *sql.DB, connStr string) {
83 if db != nil {
84 _ = db.Close()
85 }
86 if connStr != "" {
87 unregisterConnConfig(connStr)
88 }
89 }
90
91 func (c *Collector) doQueryQueryableDatabases() error {
92 q := queryQueryableDatabaseList()
93
94 var dbs []string
95 err := c.doQuery(q, func(_, value string, _ bool) {
96 if c.dbSr != nil && c.dbSr.MatchString(value) {
97 dbs = append(dbs, value)
98 }
99 })
100 if err != nil {
101 return err
102 }
103
104 seen := make(map[string]bool, len(dbs))
105
106 for _, dbname := range dbs {
107 seen[dbname] = true
108
109 conn, ok := c.dbConns[dbname]
110 if !ok {
111 conn = &dbConn{}
112 c.dbConns[dbname] = conn
113 }
114
115 if conn.db != nil || conn.connErrors >= connErrMax {
116 continue
117 }
118
119 db, connStr, err := c.openSecondaryConnection(dbname)
120 if err != nil {
121 c.Warning(err)
122 conn.connErrors++
123 continue
124 }
125
126 tables, err := c.doDBQueryUserTablesCount(db)
127 if err != nil {
128 c.Warning(err)
129 conn.connErrors++
130 closeDBAndUnregisterConnConfig(db, connStr)
131 continue
132 }
133
134 indexes, err := c.doDBQueryUserIndexesCount(db)
135 if err != nil {
136 c.Warning(err)
137 conn.connErrors++
138 closeDBAndUnregisterConnConfig(db, connStr)
139 continue
140 }
141
142 if (c.MaxDBTables != 0 && tables > c.MaxDBTables) || (c.MaxDBIndexes != 0 && indexes > c.MaxDBIndexes) {
143 c.Warningf("database '%s' has too many user tables(%d/%d)/indexes(%d/%d), skipping it",
144 dbname, tables, c.MaxDBTables, indexes, c.MaxDBIndexes)
145 conn.connErrors = connErrMax
146 closeDBAndUnregisterConnConfig(db, connStr)
147 continue
148 }
149
150 conn.db, conn.connStr = db, connStr
151 }
152
153 for dbname, conn := range c.dbConns {
154 if seen[dbname] {
155 continue
156 }
157 delete(c.dbConns, dbname)
158 if conn.connStr != "" {
159 stdlib.UnregisterConnConfig(conn.connStr)
160 }
161 if conn.db != nil {
162 _ = conn.db.Close()
163 }
164 }
165
166 return nil
167 }
168
169 func (c *Collector) doDBQueryUserTablesCount(db *sql.DB) (int64, error) {
170 q := queryUserTablesCount()
171
172 var v string
173 if err := c.doDBQueryRow(db, q, &v); err != nil {
174 return 0, err
175 }
176
177 return parseInt(v), nil
178 }
179
180 func (c *Collector) doDBQueryUserIndexesCount(db *sql.DB) (int64, error) {
181 q := queryUserIndexesCount()
182
183 var v string
184 if err := c.doDBQueryRow(db, q, &v); err != nil {
185 return 0, err
186 }
187
188 return parseInt(v), nil
189 }