15 #ifdef HAVE_COPYFILE_H
19 #include <sys/ioctl.h>
40 const char *schemaName,
const char *relName)
42 #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
43 if (copyfile(src, dst, NULL, COPYFILE_CLONE_FORCE) < 0)
44 pg_fatal(
"error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
45 schemaName, relName, src, dst);
46 #elif defined(__linux__) && defined(FICLONE)
50 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
51 pg_fatal(
"error while cloning relation \"%s.%s\": could not open file \"%s\": %m",
52 schemaName, relName, src);
54 if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
56 pg_fatal(
"error while cloning relation \"%s.%s\": could not create file \"%s\": %m",
57 schemaName, relName, dst);
59 if (ioctl(dest_fd, FICLONE, src_fd) < 0)
61 int save_errno = errno;
65 pg_fatal(
"error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s",
66 schemaName, relName, src, dst,
strerror(save_errno));
83 const char *schemaName,
const char *relName)
90 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
91 pg_fatal(
"error while copying relation \"%s.%s\": could not open file \"%s\": %m",
92 schemaName, relName, src);
94 if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
96 pg_fatal(
"error while copying relation \"%s.%s\": could not create file \"%s\": %m",
97 schemaName, relName, dst);
100 #define COPY_BUF_SIZE (50 * BLCKSZ)
110 pg_fatal(
"error while copying relation \"%s.%s\": could not read file \"%s\": %m",
111 schemaName, relName, src);
117 if (
write(dest_fd, buffer, nbytes) != nbytes)
122 pg_fatal(
"error while copying relation \"%s.%s\": could not write file \"%s\": %m",
123 schemaName, relName, dst);
133 if (CopyFile(src, dst,
true) == 0)
136 pg_fatal(
"error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
137 schemaName, relName, src, dst);
152 const char *schemaName,
const char *relName)
154 #ifdef HAVE_COPY_FILE_RANGE
159 if ((src_fd = open(src, O_RDONLY |
PG_BINARY, 0)) < 0)
160 pg_fatal(
"error while copying relation \"%s.%s\": could not open file \"%s\": %m",
161 schemaName, relName, src);
163 if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
165 pg_fatal(
"error while copying relation \"%s.%s\": could not create file \"%s\": %m",
166 schemaName, relName, dst);
170 nbytes = copy_file_range(src_fd, NULL, dest_fd, NULL, SSIZE_MAX, 0);
172 pg_fatal(
"error while copying relation \"%s.%s\": could not copy file range from \"%s\" to \"%s\": %m",
173 schemaName, relName, src, dst);
191 const char *schemaName,
const char *relName)
193 if (
link(src, dst) < 0)
194 pg_fatal(
"error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %m",
195 schemaName, relName, src, dst);
217 const char *schemaName,
const char *relName)
223 ssize_t totalBytesRead = 0;
224 ssize_t src_filesize;
225 int rewriteVmBytesPerPage;
232 if ((src_fd = open(fromfile, O_RDONLY |
PG_BINARY, 0)) < 0)
233 pg_fatal(
"error while copying relation \"%s.%s\": could not open file \"%s\": %m",
234 schemaName, relName, fromfile);
236 if (
fstat(src_fd, &statbuf) != 0)
237 pg_fatal(
"error while copying relation \"%s.%s\": could not stat file \"%s\": %m",
238 schemaName, relName, fromfile);
240 if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
242 pg_fatal(
"error while copying relation \"%s.%s\": could not create file \"%s\": %m",
243 schemaName, relName, tofile);
246 src_filesize = statbuf.
st_size;
254 while (totalBytesRead < src_filesize)
263 if ((bytesRead =
read(src_fd, buffer.
data, BLCKSZ)) != BLCKSZ)
266 pg_fatal(
"error while copying relation \"%s.%s\": could not read file \"%s\": %m",
267 schemaName, relName, fromfile);
269 pg_fatal(
"error while copying relation \"%s.%s\": partial page found in file \"%s\"",
270 schemaName, relName, fromfile);
273 totalBytesRead += BLCKSZ;
274 old_lastblk = (totalBytesRead == src_filesize);
286 old_blkend = buffer.
data + bytesRead;
287 old_break = old_cur + rewriteVmBytesPerPage;
289 while (old_break <= old_blkend)
299 old_lastpart = old_lastblk && (old_break == old_blkend);
304 while (old_cur < old_break)
322 new_cur[0] = (char) (new_vmbits & 0xFF);
323 new_cur[1] = (char) (new_vmbits >> 8);
330 if (old_lastpart && empty)
339 if (
write(dst_fd, new_vmbuf.
data, BLCKSZ) != BLCKSZ)
344 pg_fatal(
"error while copying relation \"%s.%s\": could not write file \"%s\": %m",
345 schemaName, relName, tofile);
349 old_break += rewriteVmBytesPerPage;
367 unlink(new_link_file);
369 #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
370 if (copyfile(existing_file, new_link_file, NULL, COPYFILE_CLONE_FORCE) < 0)
371 pg_fatal(
"could not clone file between old and new data directories: %m");
372 #elif defined(__linux__) && defined(FICLONE)
377 if ((src_fd = open(existing_file, O_RDONLY |
PG_BINARY, 0)) < 0)
378 pg_fatal(
"could not open file \"%s\": %m",
381 if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
383 pg_fatal(
"could not create file \"%s\": %m",
386 if (ioctl(dest_fd, FICLONE, src_fd) < 0)
387 pg_fatal(
"could not clone file between old and new data directories: %m");
393 pg_fatal(
"file cloning not supported on this platform");
396 unlink(new_link_file);
407 unlink(new_link_file);
409 #if defined(HAVE_COPY_FILE_RANGE)
414 if ((src_fd = open(existing_file, O_RDONLY |
PG_BINARY, 0)) < 0)
415 pg_fatal(
"could not open file \"%s\": %m",
418 if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL |
PG_BINARY,
420 pg_fatal(
"could not create file \"%s\": %m",
423 if (copy_file_range(src_fd, NULL, dest_fd, NULL, SSIZE_MAX, 0) < 0)
424 pg_fatal(
"could not copy file range between old and new data directories: %m");
430 pg_fatal(
"copy_file_range not supported on this platform");
433 unlink(new_link_file);
444 unlink(new_link_file);
446 if (
link(existing_file, new_link_file) < 0)
447 pg_fatal(
"could not create hard link between old and new data directories: %m\n"
448 "In link mode the old and new data directories must be on the same file system.");
450 unlink(new_link_file);
PageHeaderData * PageHeader
#define SizeOfPageHeaderData
uint16 pg_checksum_page(char *page, BlockNumber blkno)
void * pg_malloc(size_t size)
void linkFile(const char *src, const char *dst, const char *schemaName, const char *relName)
void check_file_clone(void)
void rewriteVisibilityMap(const char *fromfile, const char *tofile, const char *schemaName, const char *relName)
void cloneFile(const char *src, const char *dst, const char *schemaName, const char *relName)
void copyFileByRange(const char *src, const char *dst, const char *schemaName, const char *relName)
void check_hard_link(void)
void copyFile(const char *src, const char *dst, const char *schemaName, const char *relName)
void check_copy_file_range(void)
uint32 data_checksum_version
#define BITS_PER_HEAPBLOCK
#define VISIBILITYMAP_ALL_VISIBLE
void _dosmaperr(unsigned long)
int link(const char *src, const char *dst)