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-2025, 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
40 akapila@postgresql.o 28 :GNC 94 : pgstat_report_subscription_error(Oid subid, LogicalRepWorkerType wtype)
29 : : {
30 : : PgStat_EntryRef *entry_ref;
31 : : PgStat_BackendSubEntry *pending;
32 : :
1351 andres@anarazel.de 33 :CBC 94 : entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_SUBSCRIPTION,
34 : : InvalidOid, subid, NULL);
35 : 94 : pending = entry_ref->pending;
36 : :
40 akapila@postgresql.o 37 [ + + + - ]:GNC 94 : switch (wtype)
38 : : {
39 : 78 : case WORKERTYPE_APPLY:
40 : 78 : pending->apply_error_count++;
41 : 78 : break;
42 : :
43 : 4 : case WORKERTYPE_SEQUENCESYNC:
29 44 : 4 : pending->sync_seq_error_count++;
40 45 : 4 : break;
46 : :
47 : 12 : case WORKERTYPE_TABLESYNC:
29 48 : 12 : pending->sync_table_error_count++;
40 49 : 12 : break;
50 : :
40 akapila@postgresql.o 51 :UNC 0 : default:
52 : : /* Should never happen. */
53 : 0 : Assert(0);
54 : : break;
55 : : }
1367 andres@anarazel.de 56 :CBC 94 : }
57 : :
58 : : /*
59 : : * Report a subscription conflict.
60 : : */
61 : : void
469 akapila@postgresql.o 62 : 52 : pgstat_report_subscription_conflict(Oid subid, ConflictType type)
63 : : {
64 : : PgStat_EntryRef *entry_ref;
65 : : PgStat_BackendSubEntry *pending;
66 : :
67 : 52 : entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_SUBSCRIPTION,
68 : : InvalidOid, subid, NULL);
69 : 52 : pending = entry_ref->pending;
70 : 52 : pending->conflict_count[type]++;
71 : 52 : }
72 : :
73 : : /*
74 : : * Report creating the subscription.
75 : : */
76 : : void
1351 andres@anarazel.de 77 : 165 : pgstat_create_subscription(Oid subid)
78 : : {
79 : : /* Ensures that stats are dropped if transaction rolls back */
80 : 165 : pgstat_create_transactional(PGSTAT_KIND_SUBSCRIPTION,
81 : : InvalidOid, subid);
82 : :
83 : : /* Create and initialize the subscription stats entry */
1168 84 : 165 : pgstat_get_entry_ref(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid,
85 : : true, NULL);
86 : 165 : pgstat_reset_entry(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid, 0);
1351 87 : 165 : }
88 : :
89 : : /*
90 : : * Report dropping the subscription.
91 : : *
92 : : * Ensures that stats are dropped if transaction commits.
93 : : */
94 : : void
95 : 116 : pgstat_drop_subscription(Oid subid)
96 : : {
97 : 116 : pgstat_drop_transactional(PGSTAT_KIND_SUBSCRIPTION,
98 : : InvalidOid, subid);
1367 99 : 116 : }
100 : :
101 : : /*
102 : : * Support function for the SQL-callable pgstat* functions. Returns
103 : : * the collected statistics for one subscription or NULL.
104 : : */
105 : : PgStat_StatSubEntry *
1351 106 : 37 : pgstat_fetch_stat_subscription(Oid subid)
107 : : {
108 : 37 : return (PgStat_StatSubEntry *)
109 : 37 : pgstat_fetch_entry(PGSTAT_KIND_SUBSCRIPTION, InvalidOid, subid);
110 : : }
111 : :
112 : : /*
113 : : * Flush out pending stats for the entry
114 : : *
115 : : * If nowait is true and the lock could not be immediately acquired, returns
116 : : * false without flushing the entry. Otherwise returns true.
117 : : */
118 : : bool
119 : 109 : pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
120 : : {
121 : : PgStat_BackendSubEntry *localent;
122 : : PgStatShared_Subscription *shsubent;
123 : :
124 : 109 : localent = (PgStat_BackendSubEntry *) entry_ref->pending;
125 : 109 : shsubent = (PgStatShared_Subscription *) entry_ref->shared_stats;
126 : :
127 : : /* localent always has non-zero content */
128 : :
129 [ - + ]: 109 : if (!pgstat_lock_entry(entry_ref, nowait))
1351 andres@anarazel.de 130 :UBC 0 : return false;
131 : :
132 : : #define SUB_ACC(fld) shsubent->stats.fld += localent->fld
1351 andres@anarazel.de 133 :CBC 109 : SUB_ACC(apply_error_count);
29 akapila@postgresql.o 134 :GNC 109 : SUB_ACC(sync_seq_error_count);
135 : 109 : SUB_ACC(sync_table_error_count);
469 akapila@postgresql.o 136 [ + + ]:CBC 981 : for (int i = 0; i < CONFLICT_NUM_TYPES; i++)
137 : 872 : SUB_ACC(conflict_count[i]);
138 : : #undef SUB_ACC
139 : :
1351 andres@anarazel.de 140 : 109 : pgstat_unlock_entry(entry_ref);
141 : 109 : return true;
142 : : }
143 : :
144 : : void
145 : 177 : pgstat_subscription_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts)
146 : : {
147 : 177 : ((PgStatShared_Subscription *) header)->stats.stat_reset_timestamp = ts;
148 : 177 : }
|