43
43
metric_replication_delay_bytes ,
44
44
metric_wal_file_amount ,
45
45
metric_incoming_replication_running ,
46
+ metric_multixact_members_per_mxid ,
47
+ metric_multixact_remaining_ratio ,
48
+ metric_xid_remaining_ratio ,
49
+ metric_multixact_members_remaining_ratio ,
46
50
)
47
51
48
- from postgresql_metrics .localhost_postgres_stats import get_amount_of_wal_files
52
+ from postgresql_metrics .localhost_postgres_stats import get_amount_of_wal_files , get_multixact_member_files
49
53
50
54
from postgresql_metrics .postgres_queries import (
51
55
get_client_connections_amount ,
60
64
get_replication_delays ,
61
65
get_tables_with_oids_for_current_db ,
62
66
get_wal_receiver_status ,
67
+ get_max_mxid_age ,
68
+ get_max_xid_age ,
63
69
)
64
70
71
+ MEMBERS_PER_MEMBER_FILE = 52352
72
+ MAX_MULTIXACT_MEMBERS = 2 ** 32
73
+ WRAPAROUND_LIMIT = (2 ** 32 / 2 ) - 1
65
74
66
75
# Notice that all functions here are expected to return a list of metrics.
67
76
# Notice also that the names of these functions should match the configuration.
68
77
69
- def get_stats_client_connections (db_connection ):
78
+
79
+ def get_stats_client_connections (_data_dir , db_connection ):
70
80
client_amount = get_client_connections_amount (db_connection )
71
81
return [metric_client_connections (client_amount )]
72
82
73
83
74
- def get_stats_disk_usage_for_database (db_connection ):
84
+ def get_stats_disk_usage_for_database (_data_dir , db_connection ):
75
85
db_size = get_disk_usage_for_database (db_connection )
76
86
return [metric_database_size (db_size [0 ], db_size [1 ])]
77
87
78
88
79
- def get_stats_tx_rate_for_database (db_connection ):
89
+ def get_stats_tx_rate_for_database (_data_dir , db_connection ):
80
90
db_name , tx_rate , tx_rollbacks = get_transaction_rate_for_database (db_connection )
81
91
if tx_rate is not None :
82
92
return [metric_transaction_rate (db_name , tx_rate ),
@@ -85,15 +95,15 @@ def get_stats_tx_rate_for_database(db_connection):
85
95
return []
86
96
87
97
88
- def get_stats_seconds_since_last_vacuum_per_table (db_connection ):
98
+ def get_stats_seconds_since_last_vacuum_per_table (_data_dir , db_connection ):
89
99
last_vacuums_data = get_seconds_since_last_vacuum_per_table (db_connection )
90
100
metrics = []
91
101
for db_name , table_name , seconds_since in last_vacuums_data :
92
102
metrics .append (metric_seconds_since_last_vacuum (db_name , table_name , seconds_since ))
93
103
return metrics
94
104
95
105
96
- def get_stats_heap_hit_statistics (db_connection ):
106
+ def get_stats_heap_hit_statistics (_data_dir , db_connection ):
97
107
db_name , heap_read , heap_hit , heap_hit_ratio = get_heap_hit_statistics (db_connection )
98
108
metrics = []
99
109
if heap_hit_ratio is not None :
@@ -103,7 +113,7 @@ def get_stats_heap_hit_statistics(db_connection):
103
113
return metrics
104
114
105
115
106
- def get_stats_lock_statistics (db_connection ):
116
+ def get_stats_lock_statistics (_data_dir , db_connection ):
107
117
locks_by_type , [total_locks_waiting , total_locks_granted ] = get_lock_statistics (db_connection )
108
118
metrics = []
109
119
for lock_type , [locks_waiting , locks_granted ] in locks_by_type .items ():
@@ -114,15 +124,15 @@ def get_stats_lock_statistics(db_connection):
114
124
return metrics
115
125
116
126
117
- def get_stats_oldest_transaction_timestamp (db_connection ):
127
+ def get_stats_oldest_transaction_timestamp (_data_dir , db_connection ):
118
128
db_name , sec_since_oldest_xact_start = get_oldest_transaction_timestamp (db_connection )
119
129
metrics = []
120
130
if sec_since_oldest_xact_start is not None :
121
131
metrics .append (metric_sec_since_oldest_xact_start (db_name , sec_since_oldest_xact_start ))
122
132
return metrics
123
133
124
134
125
- def get_stats_table_bloat (db_connection ):
135
+ def get_stats_table_bloat (_data_dir , db_connection ):
126
136
tables_with_oids = get_tables_with_oids_for_current_db (db_connection )
127
137
metrics = []
128
138
for table_oid , table_name in tables_with_oids :
@@ -132,7 +142,7 @@ def get_stats_table_bloat(db_connection):
132
142
return metrics
133
143
134
144
135
- def get_stats_index_hit_rates (db_connection ):
145
+ def get_stats_index_hit_rates (_data_dir , db_connection ):
136
146
index_hit_rates = get_index_hit_rates (db_connection )
137
147
metrics = []
138
148
for db_name , table_name , index_hit_ratio in index_hit_rates :
@@ -141,18 +151,56 @@ def get_stats_index_hit_rates(db_connection):
141
151
return metrics
142
152
143
153
144
- def get_stats_replication_delays (db_connection ):
154
+ def get_stats_replication_delays (_data_dir , db_connection ):
145
155
replication_delays = get_replication_delays (db_connection )
146
156
metrics = []
147
157
for client_addr , delay_in_bytes in replication_delays :
148
158
metrics .append (metric_replication_delay_bytes (client_addr , delay_in_bytes ))
149
159
return metrics
150
160
151
161
152
- def get_stats_wal_file_amount (data_dir ):
162
+ def _get_multixact_members (data_dir ):
163
+ return get_multixact_member_files (data_dir ) * MEMBERS_PER_MEMBER_FILE
164
+
165
+
166
+ def get_multixact_members_per_mxid (data_dir , db_connection ):
167
+ members = _get_multixact_members (data_dir )
168
+ mxid_age = get_max_mxid_age (db_connection )
169
+ if not mxid_age :
170
+ return []
171
+ members_per_id = round (members / mxid_age , 2 )
172
+ return [metric_multixact_members_per_mxid (members_per_id )]
173
+
174
+
175
+ def get_multixact_members_usage_ratio (data_dir , _db_connection ):
176
+ members = _get_multixact_members (data_dir )
177
+ ratio = members // MAX_MULTIXACT_MEMBERS
178
+ percentage_remaining = (1.0 - ratio ) * 100
179
+ return [metric_multixact_members_remaining_ratio (percentage_remaining )]
180
+
181
+
182
+ def get_multixact_remaining_ratio (_data_dir , db_connection ):
183
+ mxid_age = get_max_mxid_age (db_connection )
184
+ if not mxid_age :
185
+ return []
186
+ ratio = mxid_age // WRAPAROUND_LIMIT
187
+ percentage_remaining = (1.0 - ratio ) * 100
188
+ return [metric_multixact_remaining_ratio (percentage_remaining )]
189
+
190
+
191
+ def get_xid_remaining_ratio (_data_dir , db_connection ):
192
+ xid_age = get_max_xid_age (db_connection )
193
+ if not xid_age :
194
+ return []
195
+ ratio = xid_age // WRAPAROUND_LIMIT
196
+ percentage_remaining = (1.0 - ratio ) * 100
197
+ return [metric_xid_remaining_ratio (percentage_remaining )]
198
+
199
+
200
+ def get_stats_wal_file_amount (data_dir , _db_connection ):
153
201
return [metric_wal_file_amount (get_amount_of_wal_files (data_dir ))]
154
202
155
203
156
- def get_stats_incoming_replication_status (db_connection ):
204
+ def get_stats_incoming_replication_status (_data_dir , db_connection ):
157
205
return [metric_incoming_replication_running (host , is_streaming )
158
206
for host , is_streaming in get_wal_receiver_status (db_connection )]
0 commit comments