diff --git a/src/catalog.c b/src/catalog.c
index 03099d1a2..a79aebea6 100644
--- a/src/catalog.c
+++ b/src/catalog.c
@@ -1118,7 +1118,7 @@ get_backup_filelist(pgBackup *backup, bool strict)
 			file->segno = (int) segno;
 
 		if (get_control_value_int64(buf, "n_blocks", &n_blocks, false))
-			file->n_blocks = (int) n_blocks;
+			file->n_blocks = (int64) n_blocks;
 
 		if (get_control_value_int64(buf, "n_headers", &n_headers, false))
 			file->n_headers = (int) n_headers;
@@ -2340,6 +2340,7 @@ pgBackupWriteControl(FILE *out, pgBackup *backup, bool utc)
 		fio_fprintf(out, "program-version = %s\n", backup->program_version);
 	if (backup->server_version[0] != '\0')
 		fio_fprintf(out, "server-version = %s\n", backup->server_version);
+	fio_fprintf(out,"large-file = %u\n",backup->large_file);
 
 	fio_fprintf(out, "\n#Result backup info\n");
 	fio_fprintf(out, "timelineid = %d\n", backup->tli);
@@ -2568,7 +2569,7 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
 			len += sprintf(line+len, ",\"linked\":\"%s\"", file->linked);
 
 		if (file->n_blocks > 0)
-			len += sprintf(line+len, ",\"n_blocks\":\"%i\"", file->n_blocks);
+			len += sprintf(line+len, ",\"n_blocks\":\"" INT64_FORMAT "\"", file->n_blocks);
 
 		if (file->n_headers > 0)
 		{
@@ -2632,6 +2633,7 @@ readBackupControlFile(const char *path)
 	char	   *merge_dest_backup = NULL;
 	char	   *program_version = NULL;
 	char	   *server_version = NULL;
+	bool       large_file = false;
 	char	   *compress_alg = NULL;
 	int			parsed_options;
 
@@ -2667,6 +2669,7 @@ readBackupControlFile(const char *path)
 		{'s', 0, "external-dirs",		&backup->external_dir_str, SOURCE_FILE_STRICT},
 		{'s', 0, "note",				&backup->note, SOURCE_FILE_STRICT},
 		{'u', 0, "content-crc",			&backup->content_crc, SOURCE_FILE_STRICT},
+		{'b',0, "large-file",			&large_file,SOURCE_FILE_STRICT},
 		{0}
 	};
 
@@ -2780,6 +2783,7 @@ readBackupControlFile(const char *path)
 	if (compress_alg)
 		backup->compress_alg = parse_compress_alg(compress_alg);
 
+	backup->large_file = large_file;
 	return backup;
 }
 
@@ -2936,6 +2940,7 @@ pgBackupInit(pgBackup *backup)
 	backup->files = NULL;
 	backup->note = NULL;
 	backup->content_crc = 0;
+	backup->large_file = true;
 }
 
 /* free pgBackup object */
diff --git a/src/data.c b/src/data.c
index 753f247f7..249bff7fc 100644
--- a/src/data.c
+++ b/src/data.c
@@ -34,6 +34,9 @@ typedef struct DataPage
 static bool get_page_header(FILE *in, const char *fullpath, BackupPageHeader *bph,
 							pg_crc32 *crc, bool use_crc32c);
 
+static BackupPageHeader2_v1*
+get_data_file_headers_v1(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict);
+
 #ifdef HAVE_LIBZ
 /* Implementation of zlib compression method */
 static int32
@@ -300,7 +303,7 @@ prepare_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
 	while (!page_is_valid && try_again--)
 	{
 		/* read the block */
-		int read_len = fio_pread(in, page, blknum * BLCKSZ);
+		int read_len = fio_pread(in, page, ((int64)blknum) * BLCKSZ);
 
 		/* The block could have been truncated. It is fine. */
 		if (read_len == 0)
@@ -489,7 +492,7 @@ backup_data_file(pgFile *file, const char *from_fullpath, const char *to_fullpat
 				 CompressAlg calg, int clevel, uint32 checksum_version,
 				 HeaderMap *hdr_map, bool is_merge)
 {
-	int         rc;
+	int64         rc;
 	bool        use_pagemap;
 	char	   *errmsg = NULL;
 	BlockNumber err_blknum = 0;
@@ -758,7 +761,7 @@ catchup_data_file(pgFile *file, const char *from_fullpath, const char *to_fullpa
 			elog(ERROR, "Cannot read file \"%s\"", from_fullpath);
 	}
 
-	file->read_size = rc * BLCKSZ;
+	file->read_size = ((int64)rc) * BLCKSZ;
 
 	/* Determine that file didn`t changed in case of incremental catchup */
 	if (backup_mode != BACKUP_MODE_FULL &&
@@ -908,7 +911,8 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out,
 		if (use_headers && tmp_file->n_headers > 0)
 			headers = get_data_file_headers(&(backup->hdr_map), tmp_file,
 											parse_program_version(backup->program_version),
-											true);
+											true,
+											backup->large_file);
 
 		if (use_headers && !headers && tmp_file->n_headers > 0)
 			elog(ERROR, "Failed to get page headers for file \"%s\"", from_fullpath);
@@ -952,7 +956,7 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out,
  */
 size_t
 restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_version,
-						   const char *from_fullpath, const char *to_fullpath, int nblocks,
+						   const char *from_fullpath, const char *to_fullpath, int64 nblocks,
 						   datapagemap_t *map, PageState *checksum_map, int checksum_version,
 						   datapagemap_t *lsn_map, BackupPageHeader2 *headers)
 {
@@ -1075,7 +1079,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
 			if (fio_fseek(out, 0) < 0)
 				elog(ERROR, "Cannot seek to the start of file \"%s\": %s", to_fullpath, strerror(errno));
 
-			if (fio_ftruncate(out, blknum * BLCKSZ) != 0)
+			if (fio_ftruncate(out, ((int64)blknum) * BLCKSZ) != 0)
 				elog(ERROR, "Cannot truncate file \"%s\": %s", to_fullpath, strerror(errno));
 
 			break;
@@ -1126,7 +1130,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
 			cur_pos_in != headers[n_hdr].pos)
 		{
 			if (fseek(in, headers[n_hdr].pos, SEEK_SET) != 0)
-				elog(ERROR, "Cannot seek to offset %u of \"%s\": %s",
+				elog(ERROR, "Cannot seek to offset " INT64_FORMAT " of \"%s\": %s",
 					headers[n_hdr].pos, from_fullpath, strerror(errno));
 
 			cur_pos_in = headers[n_hdr].pos;
@@ -1161,7 +1165,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
 		 * When restoring file from FULL backup, pages are written sequentially,
 		 * so there is no need to issue fseek for every page.
 		 */
-		write_pos = blknum * BLCKSZ;
+		write_pos = ((int64)blknum) * BLCKSZ;
 
 		if (cur_pos_out != write_pos)
 		{
@@ -1675,7 +1679,7 @@ check_data_file(ConnectionArgs *arguments, pgFile *file,
 /* Valiate pages of datafile in backup one by one */
 bool
 validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
-					uint32 checksum_version, uint32 backup_version, HeaderMap *hdr_map)
+					uint32 checksum_version, uint32 backup_version, HeaderMap *hdr_map, bool large_file)
 {
 	size_t		read_len = 0;
 	bool		is_valid = true;
@@ -1696,7 +1700,7 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
 		elog(ERROR, "Cannot open file \"%s\": %s",
 			 fullpath, strerror(errno));
 
-	headers = get_data_file_headers(hdr_map, file, backup_version, false);
+	headers = get_data_file_headers(hdr_map, file, backup_version, false, large_file);
 
 	if (!headers && file->n_headers > 0)
 	{
@@ -1745,7 +1749,7 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
 					elog(ERROR, "Cannot seek block %u of \"%s\": %s",
 						blknum, fullpath, strerror(errno));
 				else
-					elog(VERBOSE, "Seek to %u", headers[n_hdr].pos);
+					elog(VERBOSE, "Seek to " INT64_FORMAT, headers[n_hdr].pos);
 
 				cur_pos_in = headers[n_hdr].pos;
 			}
@@ -1882,7 +1886,7 @@ validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
 /* read local data file and construct map with block checksums */
 PageState*
 get_checksum_map(const char *fullpath, uint32 checksum_version,
-							int n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno)
+							int64 n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno)
 {
 	PageState  *checksum_map = NULL;
 	FILE       *in = NULL;
@@ -1897,7 +1901,7 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
 
 	/* truncate up to blocks */
 	if (ftruncate(fileno(in), n_blocks * BLCKSZ) != 0)
-		elog(ERROR, "Cannot truncate file to blknum %u \"%s\": %s",
+		elog(ERROR, "Cannot truncate file to blknum " INT64_FORMAT " \"%s\": %s",
 				n_blocks, fullpath, strerror(errno));
 
 	setvbuf(in, in_buf, _IOFBF, STDIO_BUFSIZE);
@@ -1951,7 +1955,7 @@ get_checksum_map(const char *fullpath, uint32 checksum_version,
 /* return bitmap of valid blocks, bitmap is empty, then NULL is returned */
 datapagemap_t *
 get_lsn_map(const char *fullpath, uint32 checksum_version,
-			int n_blocks, XLogRecPtr shift_lsn, BlockNumber segmentno)
+			int64 n_blocks, XLogRecPtr shift_lsn, BlockNumber segmentno)
 {
 	FILE          *in = NULL;
 	BlockNumber	   blknum = 0;
@@ -1968,7 +1972,7 @@ get_lsn_map(const char *fullpath, uint32 checksum_version,
 
 	/* truncate up to blocks */
 	if (ftruncate(fileno(in), n_blocks * BLCKSZ) != 0)
-		elog(ERROR, "Cannot truncate file to blknum %u \"%s\": %s",
+		elog(ERROR, "Cannot truncate file to blknum " INT64_FORMAT " \"%s\": %s",
 				n_blocks, fullpath, strerror(errno));
 
 	setvbuf(in, in_buf, _IOFBF, STDIO_BUFSIZE);
@@ -2035,10 +2039,10 @@ get_page_header(FILE *in, const char *fullpath, BackupPageHeader* bph,
 			return false;		/* EOF found */
 		else if (read_len != 0 && feof(in))
 			elog(ERROR,
-				 "Odd size page found at offset %ld of \"%s\"",
+				 "Odd size page found at offset " INT64_FORMAT " of \"%s\"",
 				 ftello(in), fullpath);
 		else
-			elog(ERROR, "Cannot read header at offset %ld of \"%s\": %s",
+			elog(ERROR, "Cannot read header at offset " INT64_FORMAT " of \"%s\": %s",
 				 ftello(in), fullpath, strerror(errno));
 	}
 
@@ -2299,9 +2303,9 @@ copy_pages(const char *to_fullpath, const char *from_fullpath,
 
 		else if (rc == PageIsOk)
 		{
-			if (fseek(out, blknum * BLCKSZ, SEEK_SET) != 0)
-				elog(ERROR, "Cannot seek to position %u in destination file \"%s\": %s",
-					 blknum * BLCKSZ, to_fullpath, strerror(errno));
+			if (fseek(out, ((int64)blknum) * BLCKSZ, SEEK_SET) != 0)
+				elog(ERROR, "Cannot seek to position %ld in destination file \"%s\": %s",
+					 ((int64)blknum) * BLCKSZ, to_fullpath, strerror(errno));
 
 			if (write_page(file, out, curr_page) != BLCKSZ)
 				elog(ERROR, "File: \"%s\", cannot write at block %u: %s",
@@ -2361,20 +2365,143 @@ copy_pages(const char *to_fullpath, const char *from_fullpath,
 	return n_blocks_read;
 }
 
+BackupPageHeader2*
+get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict, bool large_file)
+{
+	bool     success = false;
+	FILE    *in = NULL;
+	size_t   read_len = 0;
+	pg_crc32 hdr_crc;
+	BackupPageHeader2 *headers = NULL;
+	/* header decompression */
+	int     z_len = 0;
+	char   *zheaders = NULL;
+	const char *errormsg = NULL;
+
+	if (backup_version < 20400)
+		return NULL;
+
+	if (file->n_headers <= 0)
+		return NULL;
+
+	if(!large_file)
+	{
+		BackupPageHeader2_v1 *tmp_headers;
+		read_len = (file->n_headers+1) * sizeof(BackupPageHeader2);
+		tmp_headers = get_data_file_headers_v1(hdr_map, file, backup_version, strict);
+		headers = pgut_malloc(read_len);
+		memset(headers, 0, read_len);
+		if(!tmp_headers)
+		{
+			return NULL;
+		}
+		for(int i=0; i<file->n_headers+1; i++)
+		{
+			headers[i].block = tmp_headers[i].block;
+			headers[i].lsn = tmp_headers[i].lsn;
+			headers[i].pos = tmp_headers[i].pos;
+			headers[i].checksum = tmp_headers[i].checksum;
+		}
+		pg_free(tmp_headers);
+		return headers;
+	}
+	/* TODO: consider to make this descriptor thread-specific */
+	in = fopen(hdr_map->path, PG_BINARY_R);
+
+	if (!in)
+	{
+		elog(strict ? ERROR : WARNING, "Cannot open header file \"%s\": %s", hdr_map->path, strerror(errno));
+		return NULL;
+	}
+	/* disable buffering for header file */
+	setvbuf(in, NULL, _IONBF, 0);
+
+	if (fseeko(in, file->hdr_off, SEEK_SET))
+	{
+		elog(strict ? ERROR : WARNING, "Cannot seek to position %llu in page header map \"%s\": %s",
+			file->hdr_off, hdr_map->path, strerror(errno));
+		goto cleanup;
+	}
+
+	/*
+	 * The actual number of headers in header file is n+1, last one is a dummy header,
+	 * used for calculation of read_len for actual last header.
+	 */
+	read_len = (file->n_headers+1) * sizeof(BackupPageHeader2);
+
+	/* allocate memory for compressed headers */
+	zheaders = pgut_malloc(file->hdr_size);
+	memset(zheaders, 0, file->hdr_size);
+
+	if (fread(zheaders, 1, file->hdr_size, in) != file->hdr_size)
+	{
+		elog(strict ? ERROR : WARNING, "Cannot read header file at offset: %llu len: %i \"%s\": %s",
+			file->hdr_off, file->hdr_size, hdr_map->path, strerror(errno));
+		goto cleanup;
+	}
+
+	/* allocate memory for uncompressed headers */
+	headers = pgut_malloc(read_len);
+	memset(headers, 0, read_len);
+
+	z_len = do_decompress(headers, read_len, zheaders, file->hdr_size,
+						  ZLIB_COMPRESS, &errormsg);
+	if (z_len <= 0)
+	{
+		if (errormsg)
+			elog(strict ? ERROR : WARNING, "An error occured during metadata decompression for file \"%s\": %s",
+				 file->rel_path, errormsg);
+		else
+			elog(strict ? ERROR : WARNING, "An error occured during metadata decompression for file \"%s\": %i",
+				 file->rel_path, z_len);
+
+		goto cleanup;
+	}
+
+	/* validate checksum */
+	INIT_FILE_CRC32(true, hdr_crc);
+	COMP_FILE_CRC32(true, hdr_crc, headers, read_len);
+	FIN_FILE_CRC32(true, hdr_crc);
+
+	if (hdr_crc != file->hdr_crc)
+	{
+		elog(strict ? ERROR : WARNING, "Header map for file \"%s\" crc mismatch \"%s\" "
+				"offset: %llu, len: %lu, current: %u, expected: %u",
+			file->rel_path, hdr_map->path, file->hdr_off, read_len, hdr_crc, file->hdr_crc);
+		goto cleanup;
+	}
+
+	success = true;
+
+cleanup:
+
+	pg_free(zheaders);
+	if (in && fclose(in))
+		elog(ERROR, "Cannot close file \"%s\"", hdr_map->path);
+
+	if (!success)
+	{
+		pg_free(headers);
+		headers = NULL;
+	}
+
+	return headers;
+}
+
 /*
  * Attempt to open header file, read content and return as
  * array of headers.
  * TODO: some access optimizations would be great here:
  * less fseeks, buffering, descriptor sharing, etc.
  */
-BackupPageHeader2*
-get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict)
+BackupPageHeader2_v1*
+get_data_file_headers_v1(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict)
 {
 	bool     success = false;
 	FILE    *in = NULL;
 	size_t   read_len = 0;
 	pg_crc32 hdr_crc;
-	BackupPageHeader2 *headers = NULL;
+	BackupPageHeader2_v1 *headers = NULL;
 	/* header decompression */
 	int     z_len = 0;
 	char   *zheaders = NULL;
@@ -2408,7 +2535,7 @@ get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, b
 	 * The actual number of headers in header file is n+1, last one is a dummy header,
 	 * used for calculation of read_len for actual last header.
 	 */
-	read_len = (file->n_headers+1) * sizeof(BackupPageHeader2);
+	read_len = (file->n_headers+1) * sizeof(BackupPageHeader2_v1);
 
 	/* allocate memory for compressed headers */
 	zheaders = pgut_malloc(file->hdr_size);
diff --git a/src/merge.c b/src/merge.c
index 1ce49f9a2..abf4ae5ce 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -1084,7 +1084,7 @@ merge_files(void *arg)
 				tmp_file->n_headers = file->n_headers;
 				headers = get_data_file_headers(&(arguments->full_backup->hdr_map), file,
 						parse_program_version(arguments->full_backup->program_version),
-						true);
+						true, arguments->full_backup->large_file);
 
 				/* sanity */
 				if (!headers && file->n_headers > 0)
diff --git a/src/pg_probackup.h b/src/pg_probackup.h
index f8c1acad1..c35e02e58 100644
--- a/src/pg_probackup.h
+++ b/src/pg_probackup.h
@@ -274,7 +274,7 @@ typedef struct pgFile
 	Oid		relOid;			/* relOid extracted from path, if applicable */
 	ForkName   forkName;	/* forkName extracted from path, if applicable */
 	int		segno;			/* Segment number for ptrack */
-	int		n_blocks;		/* number of blocks in the data file in data directory */
+	int64		n_blocks;		/* number of blocks in the data file in data directory */
 	bool	is_cfs;			/* Flag to distinguish files compressed by CFS*/
 	int		external_dir_num;	/* Number of external directory. 0 if not external */
 	bool	exists_in_prev;		/* Mark files, both data and regular, that exists in previous backup */
@@ -532,6 +532,7 @@ struct pgBackup
 
 	/* map used for access to page headers */
 	HeaderMap       hdr_map;
+	bool 			large_file;     /* file's size is greate 2G*/
 };
 
 /* Recovery target for restore and validate subcommands */
@@ -685,13 +686,22 @@ typedef struct BackupPageHeader
 	int32		compressed_size;
 } BackupPageHeader;
 
-/* 4MB for 1GB file */
-typedef struct BackupPageHeader2
+/* 4MB for 1GB file ,for version 1*/
+typedef struct BackupPageHeader2_v1
 {
 	XLogRecPtr  lsn;
 	int32	    block;			 /* block number */
 	int32       pos;             /* position in backup file */
 	uint16      checksum;
+} BackupPageHeader2_v1;
+
+/* 4MB for 2GB file ,for last version*/
+typedef struct BackupPageHeader2_v2
+{
+	XLogRecPtr  lsn;
+	int64	    block;			 /* block number */
+	int64       pos;             /* position in backup file */
+	uint16      checksum;
 } BackupPageHeader2;
 
 typedef struct StopBackupCallbackParams
@@ -1119,7 +1129,7 @@ extern size_t restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *o
 								const char *to_fullpath, bool use_bitmap, PageState *checksum_map,
 								XLogRecPtr shift_lsn, datapagemap_t *lsn_map, bool use_headers);
 extern size_t restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_version,
-										 const char *from_fullpath, const char *to_fullpath, int nblocks,
+										 const char *from_fullpath, const char *to_fullpath, int64 nblocks,
 										 datapagemap_t *map, PageState *checksum_map, int checksum_version,
 										 datapagemap_t *lsn_map, BackupPageHeader2 *headers);
 extern size_t restore_non_data_file(parray *parent_chain, pgBackup *dest_backup,
@@ -1131,13 +1141,13 @@ extern bool create_empty_file(fio_location from_location, const char *to_root,
 							  fio_location to_location, pgFile *file);
 
 extern PageState *get_checksum_map(const char *fullpath, uint32 checksum_version,
-								int n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno);
+								int64 n_blocks, XLogRecPtr dest_stop_lsn, BlockNumber segmentno);
 extern datapagemap_t *get_lsn_map(const char *fullpath, uint32 checksum_version,
-								  int n_blocks, XLogRecPtr shift_lsn, BlockNumber segmentno);
+								  int64 n_blocks, XLogRecPtr shift_lsn, BlockNumber segmentno);
 extern bool validate_file_pages(pgFile *file, const char *fullpath, XLogRecPtr stop_lsn,
-							    uint32 checksum_version, uint32 backup_version, HeaderMap *hdr_map);
+							uint32 checksum_version, uint32 backup_version, HeaderMap *hdr_map, bool large_file);
 
-extern BackupPageHeader2* get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict);
+extern BackupPageHeader2* get_data_file_headers(HeaderMap *hdr_map, pgFile *file, uint32 backup_version, bool strict,bool large_file);
 extern void write_page_headers(BackupPageHeader2 *headers, pgFile *file, HeaderMap *hdr_map, bool is_merge);
 extern void init_header_map(pgBackup *backup);
 extern void cleanup_header_map(HeaderMap *hdr_map);
@@ -1252,7 +1262,7 @@ extern bool pgut_rmtree(const char *path, bool rmtopdir, bool strict);
 extern void pgut_setenv(const char *key, const char *val);
 extern void pgut_unsetenv(const char *key);
 
-extern PageState *fio_get_checksum_map(const char *fullpath, uint32 checksum_version, int n_blocks,
+extern PageState *fio_get_checksum_map(const char *fullpath, uint32 checksum_version, int64 n_blocks,
 									XLogRecPtr dest_stop_lsn, BlockNumber segmentno, fio_location location);
 
 extern datapagemap_t *fio_get_lsn_map(const char *fullpath, uint32 checksum_version,
diff --git a/src/utils/file.c b/src/utils/file.c
index 727b48c60..fb57518c4 100644
--- a/src/utils/file.c
+++ b/src/utils/file.c
@@ -2146,7 +2146,7 @@ fio_copy_pages(const char *to_fullpath, const char *from_fullpath, pgFile *file,
 
 			COMP_FILE_CRC32(true, file->crc, buf, hdr.size);
 
-			if (fio_fseek(out, blknum * BLCKSZ) < 0)
+			if (fio_fseek(out, ((int64)blknum) * BLCKSZ) < 0)
 			{
 				elog(ERROR, "Cannot seek block %u of \"%s\": %s",
 					blknum, to_fullpath, strerror(errno));
@@ -2188,7 +2188,7 @@ fio_send_pages_impl(int out, char* buf)
 {
 	FILE        *in = NULL;
 	BlockNumber  blknum = 0;
-	int          current_pos = 0;
+	int64          current_pos = 0;
 	BlockNumber  n_blocks_read = 0;
 	PageState    page_st;
 	char         read_buffer[BLCKSZ+1];
@@ -2204,7 +2204,7 @@ fio_send_pages_impl(int out, char* buf)
 	datapagemap_iterator_t *iter = NULL;
 	/* page headers */
 	int32       hdr_num = -1;
-	int32       cur_pos_out = 0;
+	int64       cur_pos_out = 0;
 	BackupPageHeader2 *headers = NULL;
 
 	/* open source file */
@@ -2275,11 +2275,11 @@ fio_send_pages_impl(int out, char* buf)
 			 * Optimize stdio buffer usage, fseek only when current position
 			 * does not match the position of requested block.
 			 */
-			if (current_pos != blknum*BLCKSZ)
+			if (current_pos != ((int64)blknum)*BLCKSZ)
 			{
-				current_pos = blknum*BLCKSZ;
+				current_pos = ((int64)blknum)*BLCKSZ;
 				if (fseek(in, current_pos, SEEK_SET) != 0)
-					elog(ERROR, "fseek to position %u is failed on remote file '%s': %s",
+					elog(ERROR, "fseek to position " INT64_FORMAT " is failed on remote file '%s': %s",
 							current_pos, from_fullpath, strerror(errno));
 			}
 
@@ -2962,7 +2962,7 @@ fio_list_dir(parray *files, const char *root, bool exclude,
 }
 
 PageState *
-fio_get_checksum_map(const char *fullpath, uint32 checksum_version, int n_blocks,
+fio_get_checksum_map(const char *fullpath, uint32 checksum_version, int64 n_blocks,
 					 XLogRecPtr dest_stop_lsn, BlockNumber segmentno, fio_location location)
 {
 	if (fio_is_remote(location))
diff --git a/src/validate.c b/src/validate.c
index 4044ac158..9aa12018f 100644
--- a/src/validate.c
+++ b/src/validate.c
@@ -39,6 +39,7 @@ typedef struct
 	 * 0 means there is no error, 1 - there is an error.
 	 */
 	int			ret;
+	bool 		large_file;
 } validate_files_arg;
 
 /*
@@ -152,6 +153,7 @@ pgBackupValidate(pgBackup *backup, pgRestoreParams *params)
 		arg->backup_version = parse_program_version(backup->program_version);
 		arg->external_prefix = external_prefix;
 		arg->hdr_map = &(backup->hdr_map);
+		arg->large_file = backup->large_file;
 //		arg->dbOid_exclude_list = dbOid_exclude_list;
 		/* By default there are some error */
 		threads_args[i].ret = 1;
@@ -362,7 +364,7 @@ pgBackupValidateFiles(void *arg)
 			if (!validate_file_pages(file, file_fullpath, arguments->stop_lsn,
 								  arguments->checksum_version,
 								  arguments->backup_version,
-								  arguments->hdr_map))
+								  arguments->hdr_map,arguments->large_file))
 				arguments->corrupted = true;
 		}
 	}