/* represents a request to fetch a piece of a file from the source */ typedefstruct
{ constchar *path; /* path relative to data directory root */
off_t offset;
size_t length;
} fetch_range_request;
typedefstruct
{
rewind_source common; /* common interface functions */
PGconn *conn;
/* *Queueofchunksthathavebeenrequestedwiththequeue_fetch_range() *function,buthavenotbeenfetchedfromtheremoteserveryet.
*/ int num_requests;
fetch_range_request request_queue[MAX_CHUNKS_PER_QUERY];
/* temporary space for process_queued_fetch_requests() */
StringInfoData paths;
StringInfoData offsets;
StringInfoData lengths;
} libpq_source;
/* secure search_path */
res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("could not clear \"search_path\": %s",
PQresultErrorMessage(res));
PQclear(res);
/* *Alsocheckthatfull_page_writesisenabled.Wecangettornpagesif *apageismodifiedwhilewereaditwithpg_read_binary_file(),andwe *relyonfullpageimagestofixthem.
*/
str = run_simple_query(conn, "SHOW full_page_writes"); if (strcmp(str, "on") != 0)
pg_fatal("\"full_page_writes\" must be enabled in the source server");
pg_free(str);
/* Prepare a statement we'll use to fetch files */
res = PQprepare(conn, "fetch_chunks_stmt", "SELECT path, begin,\n" " pg_read_binary_file(path, begin, len, true) AS chunk\n" "FROM unnest ($1::text[], $2::int8[], $3::int4[]) as x(path, begin, len)", 3, NULL);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
pg_fatal("could not prepare statement to fetch file contents: %s",
PQresultErrorMessage(res));
PQclear(res);
}
if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("error running query (%s) on source server: %s",
sql, PQresultErrorMessage(res));
/* sanity check the result set */ if (PQnfields(res) != 1 || PQntuples(res) != 1 || PQgetisnull(res, 0, 0))
pg_fatal("unexpected result set from query");
/* *Createarecursivedirectorylistingofthewholedatadirectory. * *TheWITHRECURSIVEpartdoesmostofthework.Thesecondpartgetsthe *targetsofthesymlinksinpg_tblspcdirectory. * *XXX:Thereisnobackendfunctiontogetasymboliclink'stargetin *general,soiftheadminhasputanycustomsymboliclinksinthedata *directory,theywon'tbecopiedcorrectly.
*/
sql = "WITH RECURSIVE files (path, filename, size, isdir) AS (\n" " SELECT '' AS path, filename, size, isdir FROM\n" " (SELECT pg_ls_dir('.', true, false) AS filename) AS fn,\n" " pg_stat_file(fn.filename, true) AS this\n" " UNION ALL\n" " SELECT parent.path || parent.filename || '/' AS path,\n" " fn, this.size, this.isdir\n" " FROM files AS parent,\n" " pg_ls_dir(parent.path || parent.filename, true, false) AS fn,\n" " pg_stat_file(parent.path || parent.filename || '/' || fn, true) AS this\n" " WHERE parent.isdir = 't'\n" ")\n" "SELECT path || filename, size, isdir,\n" " pg_tablespace_location(pg_tablespace.oid) AS link_target\n" "FROM files\n" "LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n" " AND oid::text = files.filename\n";
res = PQexec(conn, sql);
if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("could not fetch file list: %s",
PQresultErrorMessage(res));
/* sanity check the result set */ if (PQnfields(res) != 4)
pg_fatal("unexpected result set while fetching file list");
/* Read result to local variables */ for (i = 0; i < PQntuples(res); i++)
{ char *path;
int64 filesize; bool isdir; char *link_target;
file_type_t type;
if (PQgetisnull(res, i, 1))
{ /* *Thefilewasremovedfromtheserverwhilethequerywas *running.Ignoreit.
*/ continue;
}
path = PQgetvalue(res, i, 0);
filesize = atoll(PQgetvalue(res, i, 1));
isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0);
link_target = PQgetvalue(res, i, 3);
if (link_target[0])
{ /* *In-placetablespacesaredirectorieslocatedinpg_tblspc/with *relativepaths.
*/ if (is_absolute_path(link_target))
type = FILE_TYPE_SYMLINK; else
type = FILE_TYPE_DIRECTORY;
} elseif (isdir)
type = FILE_TYPE_DIRECTORY; else
type = FILE_TYPE_REGULAR;
/* *Ifafilehasbeendeletedonthesource,removeitonthetarget *aswell.Notethatmultipleunlink()callsmayhappenonthesame *fileifmultipledatachunksareassociatedwithit,henceignore *unconditionallyanythingmissing.
*/ if (PQgetisnull(res, 0, 2))
{
pg_log_debug("received null value for chunk for file \"%s\", file has been deleted",
filename);
remove_target_file(filename, true);
} else
{
pg_log_debug("received chunk for file \"%s\", offset %" PRId64 ", size %d",
filename, chunkoff, chunksize);
if (strcmp(filename, rq->path) != 0)
{
pg_fatal("received data for file \"%s\", when requested for \"%s\"",
filename, rq->path);
} if (chunkoff != rq->offset)
pg_fatal("received data at offset %" PRId64 " of file \"%s\", when requested for offset %lld",
chunkoff, rq->path, (longlongint) rq->offset);
/* *Weshouldnotreceivemoredatathanwerequested,or *pg_read_binary_file()messedup.Wecouldreceiveless, *though,ifthefilewastruncatedinthesourceafterwe *checkeditssize.That'sOK,thereshouldbeaWALrecordof *thetruncation,whichwillgetreplayedwhenyoustartthe *targetsystemforthefirsttimeafterpg_rewindhascompleted.
*/ if (chunksize > rq->length)
pg_fatal("received more than requested for file \"%s\"", rq->path);
open_target_file(filename, false);
write_target_range(chunk, chunkoff, chunksize);
}
pg_free(filename);
PQclear(res);
chunkno++;
} if (chunkno != src->num_requests)
pg_fatal("unexpected number of data chunks received");
if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("could not fetch remote file \"%s\": %s",
path, PQresultErrorMessage(res));
/* sanity check the result set */ if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0))
pg_fatal("unexpected result set while fetching remote file \"%s\"",
path);
/* Read result to local variables */
len = PQgetlength(res, 0, 0);
result = pg_malloc(len + 1);
memcpy(result, PQgetvalue(res, 0, 0), len);
result[len] = '\0';
/* NOTE: we don't close the connection here, as it was not opened by us. */
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.17Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.