Skip to content

Commit ebfb814

Browse files
committed
walmethods.c/h: Make WalWriteMethod more object-oriented.
Normally when we use object-oriented programming techniques, we provide a pointer to an object and then some way of looking up the associated table of callbacks, but walmethods.c/h took the alternative approach of providing only a pointer to the table of callbacks and thus imposed the artificial restriction that there could only ever be one object of each type, so that the callbacks could find it via a global variable. That doesn't seem like the right idea, so revise the approach. Each callback which does not already have an argument of type Walfile * now takes a pointer to the relevant WalWriteMethod * so that these callbacks need not rely on there being only one object of each type. Freeing a WalWriteMethod is now performed via a callback provided for that purpose rather than requiring the caller to know which WAL method they want to free. Discussion: http://postgr.es/m/CA+TgmoZS0Kw98fOoAcGz8B9iDhdqB4Be4e=vDZaJZ5A-xMYBqA@mail.gmail.com
1 parent c35ba14 commit ebfb814

File tree

5 files changed

+357
-316
lines changed

5 files changed

+357
-316
lines changed

src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ LogStreamerMain(logstreamer_param *param)
570570
return 1;
571571
}
572572

573-
if (!stream.walmethod->finish())
573+
if (!stream.walmethod->ops->finish(stream.walmethod))
574574
{
575575
pg_log_error("could not finish writing WAL files: %m");
576576
#ifdef WIN32
@@ -581,11 +581,7 @@ LogStreamerMain(logstreamer_param *param)
581581

582582
PQfinish(param->bgconn);
583583

584-
if (format == 'p')
585-
FreeWalDirectoryMethod();
586-
else
587-
FreeWalTarMethod();
588-
pg_free(stream.walmethod);
584+
stream.walmethod->ops->free(stream.walmethod);
589585

590586
return 0;
591587
}

src/bin/pg_basebackup/pg_receivewal.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ StreamLog(void)
658658

659659
ReceiveXlogStream(conn, &stream);
660660

661-
if (!stream.walmethod->finish())
661+
if (!stream.walmethod->ops->finish(stream.walmethod))
662662
{
663663
pg_log_info("could not finish writing WAL files: %m");
664664
return;
@@ -667,9 +667,7 @@ StreamLog(void)
667667
PQfinish(conn);
668668
conn = NULL;
669669

670-
FreeWalDirectoryMethod();
671-
pg_free(stream.walmethod);
672-
pg_free(stream.sysidentifier);
670+
stream.walmethod->ops->free(stream.walmethod);
673671
}
674672

675673
/*

src/bin/pg_basebackup/receivelog.c

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,19 @@ mark_file_as_archived(StreamCtl *stream, const char *fname)
5959
snprintf(tmppath, sizeof(tmppath), "archive_status/%s.done",
6060
fname);
6161

62-
f = stream->walmethod->open_for_write(tmppath, NULL, 0);
62+
f = stream->walmethod->ops->open_for_write(stream->walmethod, tmppath,
63+
NULL, 0);
6364
if (f == NULL)
6465
{
6566
pg_log_error("could not create archive status file \"%s\": %s",
66-
tmppath, stream->walmethod->getlasterror());
67+
tmppath, GetLastWalMethodError(stream->walmethod));
6768
return false;
6869
}
6970

70-
if (stream->walmethod->close(f, CLOSE_NORMAL) != 0)
71+
if (stream->walmethod->ops->close(f, CLOSE_NORMAL) != 0)
7172
{
7273
pg_log_error("could not close archive status file \"%s\": %s",
73-
tmppath, stream->walmethod->getlasterror());
74+
tmppath, GetLastWalMethodError(stream->walmethod));
7475
return false;
7576
}
7677

@@ -98,8 +99,9 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
9899
XLogFileName(walfile_name, stream->timeline, segno, WalSegSz);
99100

100101
/* Note that this considers the compression used if necessary */
101-
fn = stream->walmethod->get_file_name(walfile_name,
102-
stream->partial_suffix);
102+
fn = stream->walmethod->ops->get_file_name(stream->walmethod,
103+
walfile_name,
104+
stream->partial_suffix);
103105

104106
/*
105107
* When streaming to files, if an existing file exists we verify that it's
@@ -111,35 +113,35 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
111113
* When streaming to tar, no file with this name will exist before, so we
112114
* never have to verify a size.
113115
*/
114-
if (stream->walmethod->compression_algorithm() == PG_COMPRESSION_NONE &&
115-
stream->walmethod->existsfile(fn))
116+
if (stream->walmethod->compression_algorithm == PG_COMPRESSION_NONE &&
117+
stream->walmethod->ops->existsfile(stream->walmethod, fn))
116118
{
117-
size = stream->walmethod->get_file_size(fn);
119+
size = stream->walmethod->ops->get_file_size(stream->walmethod, fn);
118120
if (size < 0)
119121
{
120122
pg_log_error("could not get size of write-ahead log file \"%s\": %s",
121-
fn, stream->walmethod->getlasterror());
123+
fn, GetLastWalMethodError(stream->walmethod));
122124
pg_free(fn);
123125
return false;
124126
}
125127
if (size == WalSegSz)
126128
{
127129
/* Already padded file. Open it for use */
128-
f = stream->walmethod->open_for_write(walfile_name, stream->partial_suffix, 0);
130+
f = stream->walmethod->ops->open_for_write(stream->walmethod, walfile_name, stream->partial_suffix, 0);
129131
if (f == NULL)
130132
{
131133
pg_log_error("could not open existing write-ahead log file \"%s\": %s",
132-
fn, stream->walmethod->getlasterror());
134+
fn, GetLastWalMethodError(stream->walmethod));
133135
pg_free(fn);
134136
return false;
135137
}
136138

137139
/* fsync file in case of a previous crash */
138-
if (stream->walmethod->sync(f) != 0)
140+
if (stream->walmethod->ops->sync(f) != 0)
139141
{
140142
pg_log_error("could not fsync existing write-ahead log file \"%s\": %s",
141-
fn, stream->walmethod->getlasterror());
142-
stream->walmethod->close(f, CLOSE_UNLINK);
143+
fn, GetLastWalMethodError(stream->walmethod));
144+
stream->walmethod->ops->close(f, CLOSE_UNLINK);
143145
exit(1);
144146
}
145147

@@ -164,12 +166,14 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
164166

165167
/* No file existed, so create one */
166168

167-
f = stream->walmethod->open_for_write(walfile_name,
168-
stream->partial_suffix, WalSegSz);
169+
f = stream->walmethod->ops->open_for_write(stream->walmethod,
170+
walfile_name,
171+
stream->partial_suffix,
172+
WalSegSz);
169173
if (f == NULL)
170174
{
171175
pg_log_error("could not open write-ahead log file \"%s\": %s",
172-
fn, stream->walmethod->getlasterror());
176+
fn, GetLastWalMethodError(stream->walmethod));
173177
pg_free(fn);
174178
return false;
175179
}
@@ -199,28 +203,29 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
199203
currpos = walfile->currpos;
200204

201205
/* Note that this considers the compression used if necessary */
202-
fn = stream->walmethod->get_file_name(walfile_name,
203-
stream->partial_suffix);
206+
fn = stream->walmethod->ops->get_file_name(stream->walmethod,
207+
walfile_name,
208+
stream->partial_suffix);
204209

205210
if (stream->partial_suffix)
206211
{
207212
if (currpos == WalSegSz)
208-
r = stream->walmethod->close(walfile, CLOSE_NORMAL);
213+
r = stream->walmethod->ops->close(walfile, CLOSE_NORMAL);
209214
else
210215
{
211216
pg_log_info("not renaming \"%s\", segment is not complete", fn);
212-
r = stream->walmethod->close(walfile, CLOSE_NO_RENAME);
217+
r = stream->walmethod->ops->close(walfile, CLOSE_NO_RENAME);
213218
}
214219
}
215220
else
216-
r = stream->walmethod->close(walfile, CLOSE_NORMAL);
221+
r = stream->walmethod->ops->close(walfile, CLOSE_NORMAL);
217222

218223
walfile = NULL;
219224

220225
if (r != 0)
221226
{
222227
pg_log_error("could not close file \"%s\": %s",
223-
fn, stream->walmethod->getlasterror());
228+
fn, GetLastWalMethodError(stream->walmethod));
224229

225230
pg_free(fn);
226231
return false;
@@ -263,7 +268,7 @@ existsTimeLineHistoryFile(StreamCtl *stream)
263268

264269
TLHistoryFileName(histfname, stream->timeline);
265270

266-
return stream->walmethod->existsfile(histfname);
271+
return stream->walmethod->ops->existsfile(stream->walmethod, histfname);
267272
}
268273

269274
static bool
@@ -285,31 +290,32 @@ writeTimeLineHistoryFile(StreamCtl *stream, char *filename, char *content)
285290
return false;
286291
}
287292

288-
f = stream->walmethod->open_for_write(histfname, ".tmp", 0);
293+
f = stream->walmethod->ops->open_for_write(stream->walmethod,
294+
histfname, ".tmp", 0);
289295
if (f == NULL)
290296
{
291297
pg_log_error("could not create timeline history file \"%s\": %s",
292-
histfname, stream->walmethod->getlasterror());
298+
histfname, GetLastWalMethodError(stream->walmethod));
293299
return false;
294300
}
295301

296-
if ((int) stream->walmethod->write(f, content, size) != size)
302+
if ((int) stream->walmethod->ops->write(f, content, size) != size)
297303
{
298304
pg_log_error("could not write timeline history file \"%s\": %s",
299-
histfname, stream->walmethod->getlasterror());
305+
histfname, GetLastWalMethodError(stream->walmethod));
300306

301307
/*
302308
* If we fail to make the file, delete it to release disk space
303309
*/
304-
stream->walmethod->close(f, CLOSE_UNLINK);
310+
stream->walmethod->ops->close(f, CLOSE_UNLINK);
305311

306312
return false;
307313
}
308314

309-
if (stream->walmethod->close(f, CLOSE_NORMAL) != 0)
315+
if (stream->walmethod->ops->close(f, CLOSE_NORMAL) != 0)
310316
{
311317
pg_log_error("could not close file \"%s\": %s",
312-
histfname, stream->walmethod->getlasterror());
318+
histfname, GetLastWalMethodError(stream->walmethod));
313319
return false;
314320
}
315321

@@ -678,9 +684,9 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
678684
}
679685

680686
error:
681-
if (walfile != NULL && stream->walmethod->close(walfile, CLOSE_NO_RENAME) != 0)
687+
if (walfile != NULL && stream->walmethod->ops->close(walfile, CLOSE_NO_RENAME) != 0)
682688
pg_log_error("could not close file \"%s\": %s",
683-
walfile->pathname, stream->walmethod->getlasterror());
689+
walfile->pathname, GetLastWalMethodError(stream->walmethod));
684690
walfile = NULL;
685691
return false;
686692
}
@@ -765,9 +771,9 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream,
765771
*/
766772
if (stream->synchronous && lastFlushPosition < blockpos && walfile != NULL)
767773
{
768-
if (stream->walmethod->sync(walfile) != 0)
774+
if (stream->walmethod->ops->sync(walfile) != 0)
769775
pg_fatal("could not fsync file \"%s\": %s",
770-
walfile->pathname, stream->walmethod->getlasterror());
776+
walfile->pathname, GetLastWalMethodError(stream->walmethod));
771777
lastFlushPosition = blockpos;
772778

773779
/*
@@ -1012,9 +1018,9 @@ ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
10121018
* data has been successfully replicated or not, at the normal
10131019
* shutdown of the server.
10141020
*/
1015-
if (stream->walmethod->sync(walfile) != 0)
1021+
if (stream->walmethod->ops->sync(walfile) != 0)
10161022
pg_fatal("could not fsync file \"%s\": %s",
1017-
walfile->pathname, stream->walmethod->getlasterror());
1023+
walfile->pathname, GetLastWalMethodError(stream->walmethod));
10181024
lastFlushPosition = blockpos;
10191025
}
10201026

@@ -1115,12 +1121,13 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
11151121
}
11161122
}
11171123

1118-
if (stream->walmethod->write(walfile, copybuf + hdr_len + bytes_written,
1119-
bytes_to_write) != bytes_to_write)
1124+
if (stream->walmethod->ops->write(walfile,
1125+
copybuf + hdr_len + bytes_written,
1126+
bytes_to_write) != bytes_to_write)
11201127
{
11211128
pg_log_error("could not write %d bytes to WAL file \"%s\": %s",
11221129
bytes_to_write, walfile->pathname,
1123-
stream->walmethod->getlasterror());
1130+
GetLastWalMethodError(stream->walmethod));
11241131
return false;
11251132
}
11261133

0 commit comments

Comments
 (0)