Age Owner Branch data TLA Line data Source code
1 : : /* -------------------------------------------------------------------------
2 : : *
3 : : * pgstat_subscription.c
4 : : * Implementation of subscription statistics.
5 : : *
6 : : * This file contains the implementation of subscription statistics. It is kept
7 : : * separate from pgstat.c to enforce the line between the statistics access /
8 : : * storage implementation and the details about individual types of
9 : : * statistics.
10 : : *
11 : : * Copyright (c) 2001-2026, PostgreSQL Global Development Group
12 : : *
13 : : * IDENTIFICATION
14 : : * src/backend/utils/activity/pgstat_subscription.c
15 : : * -------------------------------------------------------------------------
16 : : */
17 : :
18 : : #include "postgres.h"
19 : :
20 : : #include "replication/worker_internal.h"
21 : : #include "utils/pgstat_internal.h"
22 : :
23 : :
24 : : /*
25 : : * Report a subscription error.
26 : : */
27 : : void
130 akapila@postgresql.o 28 :GNC 109 : pgstat_report_subscription_error(Oid subid)
29 : : {
30 : : PgStat_EntryRef *entry_ref;
31 : : PgStat_BackendSubEntry *pending;
32 : 109 : LogicalRepWorkerType wtype = get_logical_worker_type();
33 : :
1546 andres@anarazel.de 34 :CBC 109 : entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_SUBSCRIPTION,
35 : : InvalidOid, subid, NULL);
36 : 109 : pending = entry_ref->pending;
37 : :
235 akapila@postgresql.o 38 [ + + + - ]:GNC 109 : switch (wtype)
39 : : {
40 : 91 : case WORKERTYPE_APPLY:
41 : 91 : pending->apply_error_count++;
42 : 91 : break;
43 : :
44 : 6 : case WORKERTYPE_SEQUENCESYNC:
224 45 : 6 : pending->sync_seq_error_count++;
235 46 : 6 : break;
47 : :
48 : 12 : case WORKERTYPE_TABLESYNC:
224 49 : 12 : pending->sync_table_error_count++;
235 50 : 12 : break;
51 : :
235 akapila@postgresql.o 52 :UNC 0 : default:
53 : : /* Should never happen. */
54 : 0 : Assert(0);
55 : : break;
56 : : }
1562 andres@anarazel.de 57 :CBC 109 : }
58 : :
59 : : /*
60 : : * Report a subscription conflict.
61 : : */
62 : : void
664 akapila@postgresql.o 63 : 56 : pgstat_report_subscription_conflict(Oid subid, ConflictType type)
64 : : {
65 : : PgStat_EntryRef *entry_ref;
66 : : PgStat_BackendSubEntry *pending;
67 : :
68 : 56 : entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_SUBSCRIPTION,
69 : : InvalidOid, subid, NULL);
70 : 56 : pending = entry_ref->pending;
71 : 56 : pending->conflict_count[type]++;
72 : 56 : }
73 : :
74 : : /*
75 : : * Report creating the subscription.
76 : : */
77 : : void
1546 andres@anarazel.de 78 : 194 : pgstat_create_subscription(Oid subid)
79 : : {
80 : : /* Ensures that stats are dropped if transaction rolls back */
81 : 194 : pgstat_create_transactional(PGSTAT_KIND_SUBSCRIPTION,
82 : : InvalidOid, subid);
83 : :
84 : : /* Create and initialize the subscription stats entry */
1363 85 : 194 : pgstat_get_entry_ref(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid,
86 : : true, NULL);
87 : 194 : pgstat_reset_entry(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid, 0);
1546 88 : 194 : }
89 : :
90 : : /*
91 : : * Report dropping the subscription.
92 : : *
93 : : * Ensures that stats are dropped if transaction commits.
94 : : */
95 : : void
96 : 150 : pgstat_drop_subscription(Oid subid)
97 : : {
98 : 150 : pgstat_drop_transactional(PGSTAT_KIND_SUBSCRIPTION,
99 : : InvalidOid, subid);
1562 100 : 150 : }
101 : :
102 : : /*
103 : : * Support function for the SQL-callable pgstat* functions. Returns
104 : : * the collected statistics for one subscription or NULL.
105 : : */
106 : : PgStat_StatSubEntry *
1546 107 : 41 : pgstat_fetch_stat_subscription(Oid subid)
108 : : {
109 : 41 : return (PgStat_StatSubEntry *)
82 nathan@postgresql.or 110 :GNC 41 : pgstat_fetch_entry(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid, NULL);
111 : : }
112 : :
113 : : /*
114 : : * Flush out pending stats for the entry
115 : : *
116 : : * If nowait is true and the lock could not be immediately acquired, returns
117 : : * false without flushing the entry. Otherwise returns true.
118 : : */
119 : : bool
1546 andres@anarazel.de 120 :CBC 125 : pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
121 : : {
122 : : PgStat_BackendSubEntry *localent;
123 : : PgStatShared_Subscription *shsubent;
124 : :
125 : 125 : localent = (PgStat_BackendSubEntry *) entry_ref->pending;
126 : 125 : shsubent = (PgStatShared_Subscription *) entry_ref->shared_stats;
127 : :
128 : : /* localent always has non-zero content */
129 : :
130 [ - + ]: 125 : if (!pgstat_lock_entry(entry_ref, nowait))
1546 andres@anarazel.de 131 :UBC 0 : return false;
132 : :
133 : : #define SUB_ACC(fld) shsubent->stats.fld += localent->fld
1546 andres@anarazel.de 134 :CBC 125 : SUB_ACC(apply_error_count);
224 akapila@postgresql.o 135 :GNC 125 : SUB_ACC(sync_seq_error_count);
136 : 125 : SUB_ACC(sync_table_error_count);
664 akapila@postgresql.o 137 [ + + ]:CBC 1125 : for (int i = 0; i < CONFLICT_NUM_TYPES; i++)
138 : 1000 : SUB_ACC(conflict_count[i]);
139 : : #undef SUB_ACC
140 : :
1546 andres@anarazel.de 141 : 125 : pgstat_unlock_entry(entry_ref);
142 : 125 : return true;
143 : : }
144 : :
145 : : void
146 : 208 : pgstat_subscription_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts)
147 : : {
148 : 208 : ((PgStatShared_Subscription *) header)->stats.stat_reset_timestamp = ts;
149 : 208 : }
|