Skip to content

Commit 799c4c4

Browse files
committed
(testing) prototype for async ptrack map file reading #2
1 parent fa170d7 commit 799c4c4

File tree

3 files changed

+145
-4
lines changed

3 files changed

+145
-4
lines changed

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ top_builddir = ../..
2020
include $(top_builddir)/src/Makefile.global
2121
include $(top_srcdir)/contrib/contrib-global.mk
2222
endif
23+
24+
engine.o: engine.h
25+

engine.c

+137-2
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,13 @@ ptrackCleanFiles(void)
126126
#endif
127127

128128
#ifndef PTRACK_USE_AIO
129+
#ifndef PTRACK_READ_CHUNK
129130
static bool
130131
ptrackMapReadFromFileSync(const char *ptrack_path)
131132
{
132133
instr_time func_start, func_end, crc_start, func_time, read_time, crc_time;
133134

134-
elog(LOG, "ptrack read map (sync version): start, ptrack_actual_size %zu bytes", PtrackActualSize);
135+
elog(LOG, "ptrack read map (sync greedy version): start, ptrack_actual_size %zu bytes", PtrackActualSize);
135136
INSTR_TIME_SET_CURRENT(func_start);
136137

137138
/* Do actual file read */
@@ -238,10 +239,144 @@ ptrackMapReadFromFileSync(const char *ptrack_path)
238239
INSTR_TIME_ACCUM_DIFF(read_time, crc_start, func_start);
239240
INSTR_TIME_SET_ZERO(crc_time);
240241
INSTR_TIME_ACCUM_DIFF(crc_time, func_end, crc_start);
241-
elog(LOG, "ptrack read map (sync version): end. Timings (microseconds): file io time = %lu, crc time = %lu, overall time = %lu",
242+
elog(LOG, "ptrack read map (sync greedy version): end. Timings (microseconds): file io time = %lu, crc time = %lu, overall time = %lu",
242243
INSTR_TIME_GET_MICROSEC(read_time), INSTR_TIME_GET_MICROSEC(crc_time), INSTR_TIME_GET_MICROSEC(func_time));
243244
return true;
244245
}
246+
#else
247+
static bool
248+
ptrackMapReadFromFileSync(const char *ptrack_path)
249+
{
250+
instr_time func_start, func_end, func_time,
251+
read_start, read_end, read_time,
252+
crc_start, crc_end, crc_time;
253+
int ptrack_fd;
254+
size_t readed = 0;
255+
size_t summed = 0;
256+
pg_crc32c crc;
257+
pg_crc32c *file_crc;
258+
259+
elog(LOG, "ptrack read map (sync non-greedy version): start, ptrack_actual_size %zu bytes, PTRACK_READ_CHUNK %zu bytes",
260+
PtrackActualSize, (size_t) PTRACK_READ_CHUNK);
261+
INSTR_TIME_SET_ZERO(func_time);
262+
INSTR_TIME_SET_ZERO(read_time);
263+
INSTR_TIME_SET_ZERO(crc_time);
264+
INSTR_TIME_SET_CURRENT(func_start);
265+
266+
INSTR_TIME_SET_CURRENT(crc_start);
267+
INIT_CRC32C(crc);
268+
file_crc = (pg_crc32c *) ((char *) ptrack_map + PtrackCrcOffset);
269+
INSTR_TIME_SET_CURRENT(crc_end);
270+
INSTR_TIME_ACCUM_DIFF(crc_time, crc_end, crc_start);
271+
272+
INSTR_TIME_SET_CURRENT(read_start);
273+
ptrack_fd = BasicOpenFile(ptrack_path, O_RDWR | PG_BINARY);
274+
if (ptrack_fd < 0)
275+
elog(ERROR, "ptrack read map: failed to open map file \"%s\": %m", ptrack_path);
276+
INSTR_TIME_SET_CURRENT(read_end);
277+
INSTR_TIME_ACCUM_DIFF(read_time, read_end, read_start);
278+
279+
do
280+
{
281+
ssize_t last_readed;
282+
283+
INSTR_TIME_SET_CURRENT(read_start);
284+
last_readed = read(ptrack_fd, (char *) ptrack_map + readed, Min(PTRACK_READ_CHUNK, PtrackActualSize - readed));
285+
286+
if (last_readed > 0)
287+
{
288+
elog(DEBUG1, "ptrack read map: read: offset = %zu, nbytes = %zu, readed = %zi",
289+
readed, Min((size_t) PTRACK_READ_CHUNK, PtrackActualSize - readed), last_readed);
290+
readed += last_readed;
291+
}
292+
else if (last_readed == 0)
293+
{
294+
/*
295+
* We don't try to read more that PtrackActualSize and
296+
* file size was already checked in ptrackMapInit()
297+
*/
298+
elog(ERROR, "ptrack read map: unexpected end of file while reading map file \"%s\", expected to read %zu, but read only %zu bytes",
299+
ptrack_path, PtrackActualSize, readed);
300+
}
301+
else if (last_readed < 0 && errno != EINTR)
302+
{
303+
ereport(WARNING,
304+
(errcode_for_file_access(),
305+
errmsg("ptrack read map: could not read map file \"%s\": %m", ptrack_path)));
306+
close(ptrack_fd);
307+
return false;
308+
}
309+
INSTR_TIME_SET_CURRENT(read_end);
310+
INSTR_TIME_ACCUM_DIFF(read_time, read_end, read_start);
311+
312+
if (last_readed > 0)
313+
{
314+
size_t sum_chunk_size = Min(last_readed, PtrackCrcOffset - summed);
315+
INSTR_TIME_SET_CURRENT(crc_start);
316+
elog(DEBUG1, "ptrack read map: COMP_CRC32C: offset = %zu, nbytes = %zu",
317+
summed, sum_chunk_size);
318+
COMP_CRC32C(crc, (char *) ptrack_map + summed, sum_chunk_size);
319+
summed += sum_chunk_size;
320+
INSTR_TIME_SET_CURRENT(crc_end);
321+
INSTR_TIME_ACCUM_DIFF(crc_time, crc_end, crc_start);
322+
}
323+
} while (readed < PtrackActualSize);
324+
325+
INSTR_TIME_SET_CURRENT(read_start);
326+
close(ptrack_fd);
327+
INSTR_TIME_SET_CURRENT(read_end);
328+
INSTR_TIME_ACCUM_DIFF(read_time, read_end, read_start);
329+
330+
331+
INSTR_TIME_SET_CURRENT(crc_start);
332+
/* Check PTRACK_MAGIC */
333+
if (strcmp(ptrack_map->magic, PTRACK_MAGIC) != 0)
334+
{
335+
elog(WARNING, "ptrack read map: wrong map format of file \"%s\"", ptrack_path);
336+
return false;
337+
}
338+
339+
/* Check ptrack version inside old ptrack map */
340+
if (ptrack_map->version_num != PTRACK_MAP_FILE_VERSION_NUM)
341+
{
342+
ereport(WARNING,
343+
(errcode(ERRCODE_DATA_CORRUPTED),
344+
errmsg("ptrack read map: map format version %d in the file \"%s\" is incompatible with file format of extension %d",
345+
ptrack_map->version_num, ptrack_path, PTRACK_MAP_FILE_VERSION_NUM),
346+
errdetail("Deleting file \"%s\" and reinitializing ptrack map.", ptrack_path)));
347+
return false;
348+
}
349+
350+
/* Check CRC */
351+
{
352+
FIN_CRC32C(crc);
353+
354+
/*
355+
* Read ptrack map values without atomics during initialization, since
356+
* postmaster is the only user right now.
357+
*/
358+
elog(DEBUG1, "ptrack read map: crc %u, file_crc %u, init_lsn %X/%X",
359+
crc, *file_crc, (uint32) (ptrack_map->init_lsn.value >> 32), (uint32) ptrack_map->init_lsn.value);
360+
361+
if (!EQ_CRC32C(*file_crc, crc))
362+
{
363+
ereport(WARNING,
364+
(errcode(ERRCODE_DATA_CORRUPTED),
365+
errmsg("ptrack read map: incorrect checksum of file \"%s\"", ptrack_path),
366+
errdetail("Deleting file \"%s\" and reinitializing ptrack map.", ptrack_path)));
367+
return false;
368+
}
369+
}
370+
INSTR_TIME_SET_CURRENT(crc_end);
371+
INSTR_TIME_ACCUM_DIFF(crc_time, crc_end, crc_start);
372+
373+
INSTR_TIME_SET_CURRENT(func_end);
374+
INSTR_TIME_ACCUM_DIFF(func_time, func_end, func_start);
375+
elog(LOG, "ptrack read map (sync non-greedy version): end. Timings (microseconds): file io time = %lu, crc time = %lu, overall time = %lu",
376+
INSTR_TIME_GET_MICROSEC(read_time), INSTR_TIME_GET_MICROSEC(crc_time), INSTR_TIME_GET_MICROSEC(func_time));
377+
return true;
378+
}
379+
#endif
245380
#endif
246381

247382
#ifdef PTRACK_USE_AIO

engine.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,13 @@ typedef PtrackMapHdr * PtrackMap;
9292
/* async io section*/
9393

9494
/* use aio ptrack map read if defined */
95-
#define PTRACK_USE_AIO
95+
//#define PTRACK_USE_AIO
9696

9797
/* size of one async read operation (bytes) */
98-
#define PTRACK_AIO_READ_CHUNK 1024*1024
98+
#define PTRACK_AIO_READ_CHUNK 2*1024*1024
99+
100+
/* size of one sync read operation (bytes), or try to read whole file if undefined */
101+
#define PTRACK_READ_CHUNK 1024*1024
99102

100103
/* maximum count of pending aio read operations */
101104
#define PTRACK_AIO_READ_QUEUE_DEPTH 4

0 commit comments

Comments
 (0)