/* * Copy all relation data files from datadir_source to datadir_target, which * are marked in the given data page map. */ void copy_executeFileMap(filemap_t *map) { file_entry_t *entry; int i; for (i = 0; i < map->narray; i++) { entry = map->array[i]; execute_pagemap(&entry->pagemap, entry->path); switch (entry->action) { case FILE_ACTION_NONE: /* ok, do nothing.. */ break; case FILE_ACTION_COPY: rewind_copy_file_range(entry->path, 0, entry->newsize, true); break; case FILE_ACTION_TRUNCATE: truncate_target_file(entry->path, entry->newsize); break; case FILE_ACTION_COPY_TAIL: rewind_copy_file_range(entry->path, entry->oldsize, entry->newsize, false); break; case FILE_ACTION_CREATE: create_target(entry); break; case FILE_ACTION_REMOVE: remove_target(entry); break; } } close_target_file(); }
/* * Copy all relation data files from datadir_source to datadir_target, which * are marked in the given data page map. */ void copy_executeFileMap(filemap_t *map) { file_entry_t *entry; for (entry = map->first; entry != NULL; entry = entry->next) { execute_pagemap(&entry->pagemap, entry->path); switch (entry->action) { case FILE_ACTION_NONE: /* ok, do nothing.. */ break; case FILE_ACTION_COPY: copy_file_range(entry->path, 0, entry->newsize, true); break; case FILE_ACTION_REMOVE: remove_target_file(entry->path); break; case FILE_ACTION_TRUNCATE: truncate_target_file(entry->path, entry->newsize); break; case FILE_ACTION_COPY_TAIL: copy_file_range(entry->path, entry->oldsize, entry->newsize, false); break; case FILE_ACTION_CREATEDIR: create_target_dir(entry->path); break; } } if (dstfd != -1) close_target_file(); }
/* * Fetch all changed blocks from remote source data directory. */ void libpq_executeFileMap(filemap_t *map) { file_entry_t *entry; const char *sql; PGresult *res; int i; /* * First create a temporary table, and load it with the blocks that we * need to fetch. */ sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int8, len int4);"; res = PQexec(conn, sql); if (PQresultStatus(res) != PGRES_COMMAND_OK) pg_fatal("could not create temporary table: %s", PQresultErrorMessage(res)); PQclear(res); sql = "COPY fetchchunks FROM STDIN"; res = PQexec(conn, sql); if (PQresultStatus(res) != PGRES_COPY_IN) pg_fatal("could not send file list: %s", PQresultErrorMessage(res)); PQclear(res); for (i = 0; i < map->narray; i++) { entry = map->array[i]; /* If this is a relation file, copy the modified blocks */ execute_pagemap(&entry->pagemap, entry->path); switch (entry->action) { case FILE_ACTION_NONE: /* nothing else to do */ break; case FILE_ACTION_COPY: /* Truncate the old file out of the way, if any */ open_target_file(entry->path, true); fetch_file_range(entry->path, 0, entry->newsize); break; case FILE_ACTION_TRUNCATE: truncate_target_file(entry->path, entry->newsize); break; case FILE_ACTION_COPY_TAIL: fetch_file_range(entry->path, entry->oldsize, entry->newsize); break; case FILE_ACTION_REMOVE: remove_target(entry); break; case FILE_ACTION_CREATE: create_target(entry); break; } } if (PQputCopyEnd(conn, NULL) != 1) pg_fatal("could not send end-of-COPY: %s", PQerrorMessage(conn)); while ((res = PQgetResult(conn)) != NULL) { if (PQresultStatus(res) != PGRES_COMMAND_OK) pg_fatal("unexpected result while sending file list: %s", PQresultErrorMessage(res)); PQclear(res); } /* * We've now copied the list of file ranges that we need to fetch to the * temporary table. Now, actually fetch all of those ranges. */ sql = "SELECT path, begin, \n" " pg_read_binary_file(path, begin, len, true) AS chunk\n" "FROM fetchchunks\n"; receiveFileChunks(sql); }
/* * Fetch all changed blocks from remote source data directory. */ void libpq_executeFileMap(filemap_t *map) { file_entry_t *entry; const char *sql; PGresult *res; /* * First create a temporary table, and load it with the blocks that * we need to fetch. */ sql = "create temporary table fetchchunks(path text, begin int4, len int4);"; res = PQexec(conn, sql); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "error creating temporary table: %s\n", PQresultErrorMessage(res)); exit(1); } sql = "copy fetchchunks from stdin"; res = PQexec(conn, sql); if (PQresultStatus(res) != PGRES_COPY_IN) { fprintf(stderr, "unexpected result while sending file list: %s\n", PQresultErrorMessage(res)); exit(1); } for (entry = map->first; entry != NULL; entry = entry->next) { execute_pagemap(&entry->pagemap, entry->path); switch (entry->action) { case FILE_ACTION_NONE: /* ok, do nothing.. */ break; case FILE_ACTION_COPY: /* Truncate the old file out of the way, if any */ open_target_file(entry->path, true); copy_file_range(entry->path, 0, entry->newsize); break; case FILE_ACTION_REMOVE: remove_target_file(entry->path); break; case FILE_ACTION_TRUNCATE: truncate_target_file(entry->path, entry->newsize); break; case FILE_ACTION_COPY_TAIL: copy_file_range(entry->path, entry->oldsize, entry->newsize); break; case FILE_ACTION_CREATEDIR: create_target_dir(entry->path); break; case FILE_ACTION_REMOVEDIR: remove_target_dir(entry->path); break; } } if (PQputCopyEnd(conn, NULL) != 1) { fprintf(stderr, "error sending end-of-COPY: %s\n", PQerrorMessage(conn)); exit(1); } while ((res = PQgetResult(conn)) != NULL) { if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "unexpected result while sending file list: %s\n", PQresultErrorMessage(res)); exit(1); } } /* Ok, we've sent the file list. Now receive the files */ sql = "-- fetch all the blocks listed in the temp table.\n" "select path, begin, \n" " pg_read_binary_file(path, begin, len) as chunk\n" "from fetchchunks\n"; receiveFileChunks(sql); }