Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaa01051

Browse files
committed
pg_upgrade: Preserve database OIDs.
Commit9a974cb arranged to preserverelfilenodes and tablespace OIDs. For similar reasons, also arrangeto preserve database OIDs.One problem is that, up until now, the OIDs assigned to the template0and postgres databases have not been fixed. This could be a problemwhen upgrading, because pg_upgrade might try to migrate a databasefrom the old cluster to the new cluster while keeping the OID and finda different database with that OID, resulting in a failure. If it findsa database with the same name and the same OID that's OK: it will bedropped and recreated. But the same OID and a different name is aproblem.To prevent that, fix the OIDs for postgres and template0 to specificvalues less than 16384. To avoid running afoul of this rule, thesevalues should not be changed in future releases. It's not a problemthat these OIDs aren't fixed in existing releases, because the OIDsthat we're assigning here weren't used for either of these databasesin any previous release. Thus, there's no chance that an upgrade ofa cluster from any previous release will collide with the OIDs we'reassigning here. And going forward, the OIDs will always be fixed, sothe only potential collision is with a system database having thesame name and the same OID, which is OK.This patch lets users assign a specific OID to a database as well,provided however that it can't be less than 16384. I (rhaas) thoughtit might be better not to expose this capability to users, but theconsensus was otherwise, so the syntax is documented. Letting usersassign OIDs below 16384 would not be OK, though, because auser-created database with a low-numbered OID might collide with asystem-created database in a future release. We therefore prohibitthat.Shruthi KC, based on an earlier patch from Antonin Houska, reviewedand with some adjustments by me.Discussion:http://postgr.es/m/CA+TgmoYgTwYcUmB=e8+hRHOFA0kkS6Kde85+UNdon6q7bt1niQ@mail.gmail.comDiscussion:http://postgr.es/m/CAASxf_Mnwm1Dh2vd5FAhVX6S1nwNSZUB1z12VddYtM++H2+p7w@mail.gmail.com
1 parent4f0bcc7 commitaa01051

File tree

11 files changed

+120
-22
lines changed

11 files changed

+120
-22
lines changed

‎doc/src/sgml/ref/create_database.sgml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
3131
[ TABLESPACE [=] <replaceable class="parameter">tablespace_name</replaceable> ]
3232
[ ALLOW_CONNECTIONS [=] <replaceable class="parameter">allowconn</replaceable> ]
3333
[ CONNECTION LIMIT [=] <replaceable class="parameter">connlimit</replaceable> ]
34-
[ IS_TEMPLATE [=] <replaceable class="parameter">istemplate</replaceable> ] ]
34+
[ IS_TEMPLATE [=] <replaceable class="parameter">istemplate</replaceable> ]
35+
[ OID [=] <replaceable class="parameter">oid</replaceable> ] ]
3536
</synopsis>
3637
</refsynopsisdiv>
3738

@@ -203,6 +204,21 @@ CREATE DATABASE <replaceable class="parameter">name</replaceable>
203204
</para>
204205
</listitem>
205206
</varlistentry>
207+
208+
<varlistentry>
209+
<term><replaceable class="parameter">oid</replaceable></term>
210+
<listitem>
211+
<para>
212+
The object identifier to be used for the new database. If this
213+
parameter is not specified, the database will choose a suitable
214+
OID automatically. This parameter is primarily intended for internal
215+
use by <application>pg_upgrade</application>, and only
216+
<application>pg_upgrade</application> can specify a value less
217+
than 16384.
218+
</para>
219+
</listitem>
220+
</varlistentry>
221+
206222
</variablelist>
207223

208224
<para>

‎src/backend/commands/dbcommands.c

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
115115
HeapTupletuple;
116116
Datumnew_record[Natts_pg_database];
117117
boolnew_record_nulls[Natts_pg_database];
118-
Oiddboid;
118+
Oiddboid=InvalidOid;
119119
Oiddatdba;
120120
ListCell*option;
121121
DefElem*dtablespacename=NULL;
@@ -215,6 +215,30 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
215215
errhint("Consider using tablespaces instead."),
216216
parser_errposition(pstate,defel->location)));
217217
}
218+
elseif (strcmp(defel->defname,"oid")==0)
219+
{
220+
dboid=defGetInt32(defel);
221+
222+
/*
223+
* We don't normally permit new databases to be created with
224+
* system-assigned OIDs. pg_upgrade tries to preserve database
225+
* OIDs, so we can't allow any database to be created with an
226+
* OID that might be in use in a freshly-initialized cluster
227+
* created by some future version. We assume all such OIDs will
228+
* be from the system-managed OID range.
229+
*
230+
* As an exception, however, we permit any OID to be assigned when
231+
* allow_system_table_mods=on (so that initdb can assign system
232+
* OIDs to template0 and postgres) or when performing a binary
233+
* upgrade (so that pg_upgrade can preserve whatever OIDs it finds
234+
* in the source cluster).
235+
*/
236+
if (dboid<FirstNormalObjectId&&
237+
!allowSystemTableMods&& !IsBinaryUpgrade)
238+
ereport(ERROR,
239+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
240+
errmsg("OIDs less than %u are reserved for system objects",FirstNormalObjectId));
241+
}
218242
else
219243
ereport(ERROR,
220244
(errcode(ERRCODE_SYNTAX_ERROR),
@@ -502,11 +526,34 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
502526
*/
503527
pg_database_rel=table_open(DatabaseRelationId,RowExclusiveLock);
504528

505-
do
529+
/*
530+
* If database OID is configured, check if the OID is already in use or
531+
* data directory already exists.
532+
*/
533+
if (OidIsValid(dboid))
506534
{
507-
dboid=GetNewOidWithIndex(pg_database_rel,DatabaseOidIndexId,
508-
Anum_pg_database_oid);
509-
}while (check_db_file_conflict(dboid));
535+
char*existing_dbname=get_database_name(dboid);
536+
537+
if (existing_dbname!=NULL)
538+
ereport(ERROR,
539+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
540+
errmsg("database OID %u is already in use by database \"%s\"",
541+
dboid,existing_dbname));
542+
543+
if (check_db_file_conflict(dboid))
544+
ereport(ERROR,
545+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
546+
errmsg("data directory with the specified OID %u already exists",dboid));
547+
}
548+
else
549+
{
550+
/* Select an OID for the new database if is not explicitly configured. */
551+
do
552+
{
553+
dboid=GetNewOidWithIndex(pg_database_rel,DatabaseOidIndexId,
554+
Anum_pg_database_oid);
555+
}while (check_db_file_conflict(dboid));
556+
}
510557

511558
/*
512559
* Insert a new tuple into pg_database. This establishes our ownership of

‎src/bin/initdb/initdb.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include"sys/mman.h"
6060
#endif
6161

62+
#include"access/transam.h"
6263
#include"access/xlog_internal.h"
6364
#include"catalog/pg_authid_d.h"
6465
#include"catalog/pg_class_d.h"/* pgrminclude ignore */
@@ -1838,8 +1839,23 @@ static void
18381839
make_template0(FILE*cmdfd)
18391840
{
18401841
constchar*const*line;
1842+
1843+
/*
1844+
* pg_upgrade tries to preserve database OIDs across upgrades. It's smart
1845+
* enough to drop and recreate a conflicting database with the same name,
1846+
* but if the same OID were used for one system-created database in the
1847+
* old cluster and a different system-created database in the new cluster,
1848+
* it would fail. To avoid that, assign a fixed OID to template0 rather
1849+
* than letting the server choose one.
1850+
*
1851+
* (Note that, while the user could have dropped and recreated these
1852+
* objects in the old cluster, the problem scenario only exists if the OID
1853+
* that is in use in the old cluster is also used in the new cluster - and
1854+
* the new cluster should be the result of a fresh initdb.)
1855+
*/
18411856
staticconstchar*consttemplate0_setup[]= {
1842-
"CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n\n",
1857+
"CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false OID = "
1858+
CppAsString2(Template0ObjectId)";\n\n",
18431859

18441860
/*
18451861
* Explicitly revoke public create-schema and create-temp-table
@@ -1869,8 +1885,10 @@ static void
18691885
make_postgres(FILE*cmdfd)
18701886
{
18711887
constchar*const*line;
1888+
1889+
/* Assign a fixed OID to postgres, for the same reasons as template0 */
18721890
staticconstchar*constpostgres_setup[]= {
1873-
"CREATE DATABASE postgres;\n\n",
1891+
"CREATE DATABASE postgres OID = "CppAsString2(PostgresObjectId)";\n\n",
18741892
"COMMENT ON DATABASE postgres IS 'default administrative connection database';\n\n",
18751893
NULL
18761894
};

‎src/bin/pg_dump/pg_dump.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,8 +2838,16 @@ dumpDatabase(Archive *fout)
28382838
* are left to the DATABASE PROPERTIES entry, so that they can be applied
28392839
* after reconnecting to the target DB.
28402840
*/
2841-
appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
2842-
qdatname);
2841+
if (dopt->binary_upgrade)
2842+
{
2843+
appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0 OID = %u",
2844+
qdatname, dbCatId.oid);
2845+
}
2846+
else
2847+
{
2848+
appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
2849+
qdatname);
2850+
}
28432851
if (strlen(encoding) > 0)
28442852
{
28452853
appendPQExpBufferStr(creaQry, " ENCODING = ");

‎src/bin/pg_upgrade/IMPLEMENTATION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ by pg_dumpall --- this script effectively creates the complete
8686
user-defined metadata from the old cluster to the new cluster. It
8787
preserves the relfilenode numbers so TOAST and other references
8888
to relfilenodes in user data is preserved. (See binary-upgrade usage
89-
in pg_dump).
89+
in pg_dump). We choose to preserve tablespace and database OIDs as well.
9090

9191
Finally, pg_upgrade links or copies each user-defined table and its
9292
supporting indexes and toast tables from the old cluster to the new

‎src/bin/pg_upgrade/info.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,8 @@ create_rel_filename_map(const char *old_data, const char *new_data,
190190
map->new_tablespace_suffix=new_cluster.tablespace_suffix;
191191
}
192192

193-
map->old_db_oid=old_db->db_oid;
194-
map->new_db_oid=new_db->db_oid;
195-
196-
/* relfilenode is preserved across old and new cluster */
193+
/* DB oid and relfilenodes are preserved between old and new cluster */
194+
map->db_oid=old_db->db_oid;
197195
map->relfilenode=old_rel->relfilenode;
198196

199197
/* used only for logging and error reporting, old/new are identical */
@@ -324,8 +322,7 @@ get_db_infos(ClusterInfo *cluster)
324322
" LEFT OUTER JOIN pg_catalog.pg_tablespace t "
325323
" ON d.dattablespace = t.oid "
326324
"WHERE d.datallowconn = true "
327-
/* we don't preserve pg_database.oid so we sort by name */
328-
"ORDER BY 2");
325+
"ORDER BY 1");
329326

330327
res=executeQueryOrDie(conn,"%s",query);
331328

‎src/bin/pg_upgrade/pg_upgrade.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ typedef struct
145145
constchar*new_tablespace;
146146
constchar*old_tablespace_suffix;
147147
constchar*new_tablespace_suffix;
148-
Oidold_db_oid;
149-
Oidnew_db_oid;
148+
Oiddb_oid;
150149
Oidrelfilenode;
151150
/* the rest are used only for logging and error reporting */
152151
char*nspname;/* namespaces */

‎src/bin/pg_upgrade/relfilenode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,14 @@ transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_fro
193193
snprintf(old_file,sizeof(old_file),"%s%s/%u/%u%s%s",
194194
map->old_tablespace,
195195
map->old_tablespace_suffix,
196-
map->old_db_oid,
196+
map->db_oid,
197197
map->relfilenode,
198198
type_suffix,
199199
extent_suffix);
200200
snprintf(new_file,sizeof(new_file),"%s%s/%u/%u%s%s",
201201
map->new_tablespace,
202202
map->new_tablespace_suffix,
203-
map->new_db_oid,
203+
map->db_oid,
204204
map->relfilenode,
205205
type_suffix,
206206
extent_suffix);

‎src/bin/psql/tab-complete.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2633,7 +2633,7 @@ psql_completion(const char *text, int start, int end)
26332633
COMPLETE_WITH("OWNER","TEMPLATE","ENCODING","TABLESPACE",
26342634
"IS_TEMPLATE",
26352635
"ALLOW_CONNECTIONS","CONNECTION LIMIT",
2636-
"LC_COLLATE","LC_CTYPE","LOCALE");
2636+
"LC_COLLATE","LC_CTYPE","LOCALE","OID");
26372637

26382638
elseif (Matches("CREATE","DATABASE",MatchAny,"TEMPLATE"))
26392639
COMPLETE_WITH_QUERY(Query_for_list_of_template_databases);

‎src/include/access/transam.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ FullTransactionIdAdvance(FullTransactionId *dest)
196196
#defineFirstUnpinnedObjectId12000
197197
#defineFirstNormalObjectId16384
198198

199+
/* OIDs of Template0 and Postgres database are fixed */
200+
#defineTemplate0ObjectId4
201+
#definePostgresObjectId5
202+
199203
/*
200204
* VariableCache is a data structure in shared memory that is used to track
201205
* OID and XID assignment state. For largely historical reasons, there is

‎src/include/catalog/unused_oids

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ my @input_files = glob("pg_*.h");
3232

3333
my$oids = Catalog::FindAllOidsFromHeaders(@input_files);
3434

35+
# Push the template0 and postgres database OIDs.
36+
my$Template0ObjectId =
37+
Catalog::FindDefinedSymbol('access/transam.h','..','Template0ObjectId');
38+
push @{$oids},$Template0ObjectId;
39+
40+
my$PostgresObjectId =
41+
Catalog::FindDefinedSymbol('access/transam.h','..','PostgresObjectId');
42+
push @{$oids},$PostgresObjectId;
43+
3544
# Also push FirstGenbkiObjectId to serve as a terminator for the last gap.
3645
my$FirstGenbkiObjectId =
3746
Catalog::FindDefinedSymbol('access/transam.h','..','FirstGenbkiObjectId');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp