Age Owner Branch data TLA Line data Source code
1 : : /* ----------
2 : : * backend_progress.c
3 : : *
4 : : * Command progress reporting infrastructure.
5 : : *
6 : : * Copyright (c) 2001-2026, PostgreSQL Global Development Group
7 : : *
8 : : * src/backend/utils/activity/backend_progress.c
9 : : * ----------
10 : : */
11 : : #include "postgres.h"
12 : :
13 : : #include "access/parallel.h"
14 : : #include "libpq/pqformat.h"
15 : : #include "storage/proc.h"
16 : : #include "utils/backend_progress.h"
17 : : #include "utils/backend_status.h"
18 : :
19 : :
20 : : /*-----------
21 : : * pgstat_progress_start_command() -
22 : : *
23 : : * Set st_progress_command (and st_progress_command_target) in own backend
24 : : * entry. Also, zero-initialize st_progress_param array.
25 : : *-----------
26 : : */
27 : : void
2042 andres@anarazel.de 28 :CBC 53767 : pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
29 : : {
30 : 53767 : volatile PgBackendStatus *beentry = MyBEEntry;
31 : :
32 [ + - - + ]: 53767 : if (!beentry || !pgstat_track_activities)
2042 andres@anarazel.de 33 :UBC 0 : return;
34 : :
2042 andres@anarazel.de 35 :CBC 53767 : PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
36 : 53767 : beentry->st_progress_command = cmdtype;
37 : 53767 : beentry->st_progress_command_target = relid;
17 peter@eisentraut.org 38 [ + + ]:GNC 1129107 : for (int i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
39 : 1075340 : beentry->st_progress_param[i] = 0;
2042 andres@anarazel.de 40 [ - + - + ]:CBC 53767 : PGSTAT_END_WRITE_ACTIVITY(beentry);
41 : : }
42 : :
43 : : /*-----------
44 : : * pgstat_progress_update_param() -
45 : : *
46 : : * Update index'th member in st_progress_param[] of own backend entry.
47 : : *-----------
48 : : */
49 : : void
50 : 13584449 : pgstat_progress_update_param(int index, int64 val)
51 : : {
52 : 13584449 : volatile PgBackendStatus *beentry = MyBEEntry;
53 : :
54 [ + - - + ]: 13584449 : Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM);
55 : :
56 [ + - - + ]: 13584449 : if (!beentry || !pgstat_track_activities)
2042 andres@anarazel.de 57 :UBC 0 : return;
58 : :
2042 andres@anarazel.de 59 :CBC 13584449 : PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
60 : 13584449 : beentry->st_progress_param[index] = val;
61 [ - + - + ]: 13584449 : PGSTAT_END_WRITE_ACTIVITY(beentry);
62 : : }
63 : :
64 : : /*-----------
65 : : * pgstat_progress_incr_param() -
66 : : *
67 : : * Increment index'th member in st_progress_param[] of own backend entry.
68 : : *-----------
69 : : */
70 : : void
1321 tgl@sss.pgh.pa.us 71 : 1958 : pgstat_progress_incr_param(int index, int64 incr)
72 : : {
73 : 1958 : volatile PgBackendStatus *beentry = MyBEEntry;
74 : :
75 [ + - - + ]: 1958 : Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM);
76 : :
77 [ + - - + ]: 1958 : if (!beentry || !pgstat_track_activities)
1321 tgl@sss.pgh.pa.us 78 :UBC 0 : return;
79 : :
1321 tgl@sss.pgh.pa.us 80 :CBC 1958 : PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
81 : 1958 : beentry->st_progress_param[index] += incr;
82 [ - + - + ]: 1958 : PGSTAT_END_WRITE_ACTIVITY(beentry);
83 : : }
84 : :
85 : : /*-----------
86 : : * pgstat_progress_parallel_incr_param() -
87 : : *
88 : : * A variant of pgstat_progress_incr_param to allow a worker to poke at
89 : : * a leader to do an incremental progress update.
90 : : *-----------
91 : : */
92 : : void
1213 msawada@postgresql.o 93 : 164 : pgstat_progress_parallel_incr_param(int index, int64 incr)
94 : : {
95 : : /*
96 : : * Parallel workers notify a leader through a PqParallelMsg_Progress
97 : : * message to update progress, passing the progress index and incremented
98 : : * value. Leaders can just call pgstat_progress_incr_param directly.
99 : : */
100 [ + + ]: 164 : if (IsParallelWorker())
101 : : {
102 : : static StringInfoData progress_message;
103 : :
56 nathan@postgresql.or 104 :GNC 12 : pq_beginmessage(&progress_message, PqParallelMsg_Progress);
1213 msawada@postgresql.o 105 :CBC 12 : pq_sendint32(&progress_message, index);
106 : 12 : pq_sendint64(&progress_message, incr);
107 : 12 : pq_endmessage(&progress_message);
108 : : }
109 : : else
110 : 152 : pgstat_progress_incr_param(index, incr);
111 : 164 : }
112 : :
113 : : /*-----------
114 : : * pgstat_progress_update_multi_param() -
115 : : *
116 : : * Update multiple members in st_progress_param[] of own backend entry.
117 : : * This is atomic; readers won't see intermediate states.
118 : : *-----------
119 : : */
120 : : void
2042 andres@anarazel.de 121 : 718897 : pgstat_progress_update_multi_param(int nparam, const int *index,
122 : : const int64 *val)
123 : : {
124 : 718897 : volatile PgBackendStatus *beentry = MyBEEntry;
125 : : int i;
126 : :
127 [ + - + - : 718897 : if (!beentry || !pgstat_track_activities || nparam == 0)
- + ]
2042 andres@anarazel.de 128 :UBC 0 : return;
129 : :
2042 andres@anarazel.de 130 :CBC 718897 : PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
131 : :
132 [ + + ]: 1848184 : for (i = 0; i < nparam; ++i)
133 : : {
134 [ + - - + ]: 1129287 : Assert(index[i] >= 0 && index[i] < PGSTAT_NUM_PROGRESS_PARAM);
135 : :
136 : 1129287 : beentry->st_progress_param[index[i]] = val[i];
137 : : }
138 : :
139 [ - + - + ]: 718897 : PGSTAT_END_WRITE_ACTIVITY(beentry);
140 : : }
141 : :
142 : : /*-----------
143 : : * pgstat_progress_end_command() -
144 : : *
145 : : * Reset st_progress_command (and st_progress_command_target) in own backend
146 : : * entry. This signals the end of the command.
147 : : *-----------
148 : : */
149 : : void
150 : 93662 : pgstat_progress_end_command(void)
151 : : {
152 : 93662 : volatile PgBackendStatus *beentry = MyBEEntry;
153 : :
154 [ + - - + ]: 93662 : if (!beentry || !pgstat_track_activities)
2042 andres@anarazel.de 155 :UBC 0 : return;
156 : :
2042 andres@anarazel.de 157 [ + + ]:CBC 93662 : if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID)
158 : 40639 : return;
159 : :
160 : 53023 : PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
161 : 53023 : beentry->st_progress_command = PROGRESS_COMMAND_INVALID;
162 : 53023 : beentry->st_progress_command_target = InvalidOid;
163 [ - + - + ]: 53023 : PGSTAT_END_WRITE_ACTIVITY(beentry);
164 : : }
|