@@ -126,12 +126,13 @@ ptrackCleanFiles(void)
126
126
#endif
127
127
128
128
#ifndef PTRACK_USE_AIO
129
+ #ifndef PTRACK_READ_CHUNK
129
130
static bool
130
131
ptrackMapReadFromFileSync (const char * ptrack_path )
131
132
{
132
133
instr_time func_start , func_end , crc_start , func_time , read_time , crc_time ;
133
134
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 );
135
136
INSTR_TIME_SET_CURRENT (func_start );
136
137
137
138
/* Do actual file read */
@@ -238,10 +239,144 @@ ptrackMapReadFromFileSync(const char *ptrack_path)
238
239
INSTR_TIME_ACCUM_DIFF (read_time , crc_start , func_start );
239
240
INSTR_TIME_SET_ZERO (crc_time );
240
241
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" ,
242
243
INSTR_TIME_GET_MICROSEC (read_time ), INSTR_TIME_GET_MICROSEC (crc_time ), INSTR_TIME_GET_MICROSEC (func_time ));
243
244
return true;
244
245
}
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
245
380
#endif
246
381
247
382
#ifdef PTRACK_USE_AIO
0 commit comments