@@ -126,12 +126,13 @@ ptrackCleanFiles(void)
126126#endif
127127
128128#ifndef PTRACK_USE_AIO
129+ #ifndef PTRACK_READ_CHUNK
129130static bool
130131ptrackMapReadFromFileSync (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
0 commit comments