Skip to content

Commit 40b9c27

Browse files
committed
pg_restore cleanups
. remove unnecessary oid_string list stuff . use pg_get_line_buf() instead of open-coding it . cleaner parsing of map.dat lines Reverts 2b69afb add new list type simple_oid_string_list to fe-utils/simple_list Author: Álvaro Herrera <alvherre@kurilemu.de> Author: Andrew Dunstan <andrew@dunslane.net> Discussion: https://postgr.es/m/202504141220.343fmoxfsbj4@alvherre.pgsql
1 parent 3b35f9a commit 40b9c27

File tree

4 files changed

+65
-100
lines changed

4 files changed

+65
-100
lines changed

src/bin/pg_dump/pg_restore.c

Lines changed: 64 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,20 @@ static int process_global_sql_commands(PGconn *conn, const char *dumpdirpath,
6767
const char *outfile);
6868
static void copy_or_print_global_file(const char *outfile, FILE *pfile);
6969
static int get_dbnames_list_to_restore(PGconn *conn,
70-
SimpleOidStringList *dbname_oid_list,
70+
SimplePtrList *dbname_oid_list,
7171
SimpleStringList db_exclude_patterns);
7272
static int get_dbname_oid_list_from_mfile(const char *dumpdirpath,
73-
SimpleOidStringList *dbname_oid_list);
73+
SimplePtrList *dbname_oid_list);
74+
75+
/*
76+
* Stores a database OID and the corresponding name.
77+
*/
78+
typedef struct DbOidName
79+
{
80+
Oid oid;
81+
char str[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string here */
82+
} DbOidName;
83+
7484

7585
int
7686
main(int argc, char **argv)
@@ -927,7 +937,7 @@ read_one_statement(StringInfo inBuf, FILE *pfile)
927937
*/
928938
static int
929939
get_dbnames_list_to_restore(PGconn *conn,
930-
SimpleOidStringList *dbname_oid_list,
940+
SimplePtrList *dbname_oid_list,
931941
SimpleStringList db_exclude_patterns)
932942
{
933943
int count_db = 0;
@@ -943,21 +953,22 @@ get_dbnames_list_to_restore(PGconn *conn,
943953
* Process one by one all dbnames and if specified to skip restoring, then
944954
* remove dbname from list.
945955
*/
946-
for (SimpleOidStringListCell * db_cell = dbname_oid_list->head;
956+
for (SimplePtrListCell *db_cell = dbname_oid_list->head;
947957
db_cell; db_cell = db_cell->next)
948958
{
959+
DbOidName *dbidname = (DbOidName *) db_cell->ptr;
949960
bool skip_db_restore = false;
950961
PQExpBuffer db_lit = createPQExpBuffer();
951962

952-
appendStringLiteralConn(db_lit, db_cell->str, conn);
963+
appendStringLiteralConn(db_lit, dbidname->str, conn);
953964

954965
for (SimpleStringListCell *pat_cell = db_exclude_patterns.head; pat_cell; pat_cell = pat_cell->next)
955966
{
956967
/*
957968
* If there is an exact match then we don't need to try a pattern
958969
* match
959970
*/
960-
if (pg_strcasecmp(db_cell->str, pat_cell->val) == 0)
971+
if (pg_strcasecmp(dbidname->str, pat_cell->val) == 0)
961972
skip_db_restore = true;
962973
/* Otherwise, try a pattern match if there is a connection */
963974
else if (conn)
@@ -972,7 +983,7 @@ get_dbnames_list_to_restore(PGconn *conn,
972983
if (dotcnt > 0)
973984
{
974985
pg_log_error("improper qualified name (too many dotted names): %s",
975-
db_cell->str);
986+
dbidname->str);
976987
PQfinish(conn);
977988
exit_nicely(1);
978989
}
@@ -982,7 +993,7 @@ get_dbnames_list_to_restore(PGconn *conn,
982993
if ((PQresultStatus(res) == PGRES_TUPLES_OK) && PQntuples(res))
983994
{
984995
skip_db_restore = true;
985-
pg_log_info("database \"%s\" matches exclude pattern: \"%s\"", db_cell->str, pat_cell->val);
996+
pg_log_info("database \"%s\" matches exclude pattern: \"%s\"", dbidname->str, pat_cell->val);
986997
}
987998

988999
PQclear(res);
@@ -1001,8 +1012,8 @@ get_dbnames_list_to_restore(PGconn *conn,
10011012
*/
10021013
if (skip_db_restore)
10031014
{
1004-
pg_log_info("excluding database \"%s\"", db_cell->str);
1005-
db_cell->oid = InvalidOid;
1015+
pg_log_info("excluding database \"%s\"", dbidname->str);
1016+
dbidname->oid = InvalidOid;
10061017
}
10071018
else
10081019
{
@@ -1024,13 +1035,14 @@ get_dbnames_list_to_restore(PGconn *conn,
10241035
* Returns, total number of database names in map.dat file.
10251036
*/
10261037
static int
1027-
get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleOidStringList *dbname_oid_list)
1038+
get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimplePtrList *dbname_oid_list)
10281039
{
1040+
StringInfoData linebuf;
10291041
FILE *pfile;
10301042
char map_file_path[MAXPGPATH];
1031-
char line[MAXPGPATH];
10321043
int count = 0;
10331044

1045+
10341046
/*
10351047
* If there is only global.dat file in dump, then return from here as
10361048
* there is no database to restore.
@@ -1049,32 +1061,43 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleOidStringList *dbn
10491061
if (pfile == NULL)
10501062
pg_fatal("could not open \"%s\": %m", map_file_path);
10511063

1064+
initStringInfo(&linebuf);
1065+
10521066
/* Append all the dbname/db_oid combinations to the list. */
1053-
while ((fgets(line, MAXPGPATH, pfile)) != NULL)
1067+
while (pg_get_line_buf(pfile, &linebuf))
10541068
{
10551069
Oid db_oid = InvalidOid;
1056-
char db_oid_str[MAXPGPATH + 1] = "";
10571070
char *dbname;
1071+
DbOidName *dbidname;
1072+
int namelen;
1073+
char *p = linebuf.data;
10581074

10591075
/* Extract dboid. */
1060-
sscanf(line, "%u", &db_oid);
1061-
sscanf(line, "%20s", db_oid_str);
1076+
while (isdigit(*p))
1077+
p++;
1078+
if (p > linebuf.data && *p == ' ')
1079+
{
1080+
sscanf(linebuf.data, "%u", &db_oid);
1081+
p++;
1082+
}
10621083

10631084
/* dbname is the rest of the line */
1064-
dbname = line + strlen(db_oid_str) + 1;
1085+
dbname = p;
1086+
namelen = strlen(dbname);
10651087

1066-
/* Remove \n from dbname. */
1067-
dbname[strlen(dbname) - 1] = '\0';
1088+
/* Report error and exit if the file has any corrupted data. */
1089+
if (!OidIsValid(db_oid) || namelen <= 1)
1090+
pg_fatal("invalid entry in \"%s\" at line: %d", map_file_path,
1091+
count + 1);
10681092

10691093
pg_log_info("found database \"%s\" (OID: %u) in \"%s\"",
10701094
dbname, db_oid, map_file_path);
10711095

1072-
/* Report error and exit if the file has any corrupted data. */
1073-
if (!OidIsValid(db_oid) || strlen(dbname) == 0)
1074-
pg_fatal("invalid entry in \"%s\" at line : %d", map_file_path,
1075-
count + 1);
1096+
dbidname = pg_malloc(offsetof(DbOidName, str) + namelen + 1);
1097+
dbidname->oid = db_oid;
1098+
strlcpy(dbidname->str, dbname, namelen);
10761099

1077-
simple_oid_string_list_append(dbname_oid_list, db_oid, dbname);
1100+
simple_ptr_list_append(dbname_oid_list, dbidname);
10781101
count++;
10791102
}
10801103

@@ -1100,7 +1123,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11001123
SimpleStringList db_exclude_patterns, RestoreOptions *opts,
11011124
int numWorkers)
11021125
{
1103-
SimpleOidStringList dbname_oid_list = {NULL, NULL};
1126+
SimplePtrList dbname_oid_list = {NULL, NULL};
11041127
int num_db_restore = 0;
11051128
int num_total_db;
11061129
int n_errors_total;
@@ -1116,7 +1139,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11161139

11171140
num_total_db = get_dbname_oid_list_from_mfile(dumpdirpath, &dbname_oid_list);
11181141

1119-
/* If map.dat has no entry, return after processing global.dat */
1142+
/* If map.dat has no entries, return after processing global.dat */
11201143
if (dbname_oid_list.head == NULL)
11211144
return process_global_sql_commands(conn, dumpdirpath, opts->filename);
11221145

@@ -1164,20 +1187,20 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11641187
pg_log_info("need to restore %d databases out of %d databases", num_db_restore, num_total_db);
11651188

11661189
/*
1167-
* Till now, we made a list of databases, those needs to be restored after
1168-
* skipping names of exclude-database. Now we can launch parallel workers
1169-
* to restore these databases.
1190+
* We have a list of databases to restore after processing the
1191+
* exclude-database switch(es). Now we can restore them one by one.
11701192
*/
1171-
for (SimpleOidStringListCell * db_cell = dbname_oid_list.head;
1193+
for (SimplePtrListCell *db_cell = dbname_oid_list.head;
11721194
db_cell; db_cell = db_cell->next)
11731195
{
1196+
DbOidName *dbidname = (DbOidName *) db_cell->ptr;
11741197
char subdirpath[MAXPGPATH];
11751198
char subdirdbpath[MAXPGPATH];
11761199
char dbfilename[MAXPGPATH];
11771200
int n_errors;
11781201

11791202
/* ignore dbs marked for skipping */
1180-
if (db_cell->oid == InvalidOid)
1203+
if (dbidname->oid == InvalidOid)
11811204
continue;
11821205

11831206
/*
@@ -1197,27 +1220,27 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
11971220
* {oid}.dmp file, use it. Otherwise try to use a directory called
11981221
* {oid}
11991222
*/
1200-
snprintf(dbfilename, MAXPGPATH, "%u.tar", db_cell->oid);
1223+
snprintf(dbfilename, MAXPGPATH, "%u.tar", dbidname->oid);
12011224
if (file_exists_in_directory(subdirdbpath, dbfilename))
1202-
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u.tar", dumpdirpath, db_cell->oid);
1225+
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u.tar", dumpdirpath, dbidname->oid);
12031226
else
12041227
{
1205-
snprintf(dbfilename, MAXPGPATH, "%u.dmp", db_cell->oid);
1228+
snprintf(dbfilename, MAXPGPATH, "%u.dmp", dbidname->oid);
12061229

12071230
if (file_exists_in_directory(subdirdbpath, dbfilename))
1208-
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u.dmp", dumpdirpath, db_cell->oid);
1231+
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u.dmp", dumpdirpath, dbidname->oid);
12091232
else
1210-
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u", dumpdirpath, db_cell->oid);
1233+
snprintf(subdirpath, MAXPGPATH, "%s/databases/%u", dumpdirpath, dbidname->oid);
12111234
}
12121235

1213-
pg_log_info("restoring database \"%s\"", db_cell->str);
1236+
pg_log_info("restoring database \"%s\"", dbidname->str);
12141237

12151238
/* If database is already created, then don't set createDB flag. */
12161239
if (opts->cparams.dbname)
12171240
{
12181241
PGconn *test_conn;
12191242

1220-
test_conn = ConnectDatabase(db_cell->str, NULL, opts->cparams.pghost,
1243+
test_conn = ConnectDatabase(dbidname->str, NULL, opts->cparams.pghost,
12211244
opts->cparams.pgport, opts->cparams.username, TRI_DEFAULT,
12221245
false, progname, NULL, NULL, NULL, NULL);
12231246
if (test_conn)
@@ -1226,7 +1249,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12261249

12271250
/* Use already created database for connection. */
12281251
opts->createDB = 0;
1229-
opts->cparams.dbname = db_cell->str;
1252+
opts->cparams.dbname = dbidname->str;
12301253
}
12311254
else
12321255
{
@@ -1251,7 +1274,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12511274
if (n_errors)
12521275
{
12531276
n_errors_total += n_errors;
1254-
pg_log_warning("errors ignored on database \"%s\" restore: %d", db_cell->str, n_errors);
1277+
pg_log_warning("errors ignored on database \"%s\" restore: %d", dbidname->str, n_errors);
12551278
}
12561279

12571280
count++;
@@ -1261,7 +1284,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
12611284
pg_log_info("number of restored databases is %d", num_db_restore);
12621285

12631286
/* Free dbname and dboid list. */
1264-
simple_oid_string_list_destroy(&dbname_oid_list);
1287+
simple_ptr_list_destroy(&dbname_oid_list);
12651288

12661289
return n_errors_total;
12671290
}

src/fe_utils/simple_list.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -192,44 +192,3 @@ simple_ptr_list_destroy(SimplePtrList *list)
192192
cell = next;
193193
}
194194
}
195-
196-
/*
197-
* Add to an oid_string list
198-
*/
199-
void
200-
simple_oid_string_list_append(SimpleOidStringList *list, Oid oid, const char *str)
201-
{
202-
SimpleOidStringListCell *cell;
203-
204-
cell = (SimpleOidStringListCell *)
205-
pg_malloc(offsetof(SimpleOidStringListCell, str) + strlen(str) + 1);
206-
207-
cell->next = NULL;
208-
cell->oid = oid;
209-
strcpy(cell->str, str);
210-
211-
if (list->tail)
212-
list->tail->next = cell;
213-
else
214-
list->head = cell;
215-
list->tail = cell;
216-
}
217-
218-
/*
219-
* Destroy an oid_string list
220-
*/
221-
void
222-
simple_oid_string_list_destroy(SimpleOidStringList *list)
223-
{
224-
SimpleOidStringListCell *cell;
225-
226-
cell = list->head;
227-
while (cell != NULL)
228-
{
229-
SimpleOidStringListCell *next;
230-
231-
next = cell->next;
232-
pg_free(cell);
233-
cell = next;
234-
}
235-
}

src/include/fe_utils/simple_list.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,6 @@ typedef struct SimplePtrList
5555
SimplePtrListCell *tail;
5656
} SimplePtrList;
5757

58-
typedef struct SimpleOidStringListCell
59-
{
60-
struct SimpleOidStringListCell *next;
61-
Oid oid;
62-
char str[FLEXIBLE_ARRAY_MEMBER]; /* null-terminated string here */
63-
} SimpleOidStringListCell;
64-
65-
typedef struct SimpleOidStringList
66-
{
67-
SimpleOidStringListCell *head;
68-
SimpleOidStringListCell *tail;
69-
} SimpleOidStringList;
70-
7158
extern void simple_oid_list_append(SimpleOidList *list, Oid val);
7259
extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
7360
extern void simple_oid_list_destroy(SimpleOidList *list);
@@ -81,7 +68,4 @@ extern const char *simple_string_list_not_touched(SimpleStringList *list);
8168
extern void simple_ptr_list_append(SimplePtrList *list, void *ptr);
8269
extern void simple_ptr_list_destroy(SimplePtrList *list);
8370

84-
extern void simple_oid_string_list_append(SimpleOidStringList *list, Oid oid, const char *str);
85-
extern void simple_oid_string_list_destroy(SimpleOidStringList *list);
86-
8771
#endif /* SIMPLE_LIST_H */

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ DatumTupleFields
615615
DbInfo
616616
DbInfoArr
617617
DbLocaleInfo
618+
DbOidName
618619
DeClonePtrType
619620
DeadLockState
620621
DeallocateStmt
@@ -2756,8 +2757,6 @@ SimpleActionListCell
27562757
SimpleEcontextStackEntry
27572758
SimpleOidList
27582759
SimpleOidListCell
2759-
SimpleOidStringList
2760-
SimpleOidListStringCell
27612760
SimplePtrList
27622761
SimplePtrListCell
27632762
SimpleStats

0 commit comments

Comments
 (0)