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

Commitd13bbfa

Browse files
committed
Fix pg_dump handling of extension config tables
Since 9.1, we've provided extensions with a way to denote"configuration" tables- tables created by an extension which the usermay modify. By marking these as "configuration" tables, the extensionis asking for the data in these tables to be pg_dump'd (tables whichare not marked in this way are assumed to be entirely handled duringCREATE EXTENSION and are not included at all in a pg_dump).Unfortunately, pg_dump neglected to consider foreign key relationshipsbetween extension configuration tables and therefore could end uptrying to reload the data in an order which would cause FK violations.This patch teaches pg_dump about these dependencies, so that the datadumped out is done so in the best order possible. Note that there's noway to handle circular dependencies, but those have yet to be seen inthe wild.The release notes for this should include a caution to users thatexisting pg_dump-based backups may be invalid due to this issue. Thedata is all there, but restoring from it will require extracting thedata for the configuration tables and then loading them in the correctorder by hand.Discussed initially back in bug #6738, more recently brought up byGilles Darold, who provided an initial patch which was further reworkedby Michael Paquier. Further modifications and documentation updatesby me.Back-patch to 9.1 where we added the concept of extension configurationtables.
1 parentc3b0baf commitd13bbfa

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

‎doc/src/sgml/extend.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,17 @@ SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entr
721721
a table as no longer a configuration table is to dissociate it from the
722722
extension with <command>ALTER EXTENSION ... DROP TABLE</>.
723723
</para>
724+
725+
<para>
726+
Note that foreign key relationships between these tables will dictate the
727+
order in which the tables are dumped out by pg_dump. Specifically, pg_dump
728+
will attempt to dump the referenced-by table before the referencing table.
729+
As the foreign key relationships are set up at CREATE EXTENSION time (prior
730+
to data being loaded into the tables) circular dependencies are not
731+
supported. When circular dependencies exist, the data will still be dumped
732+
out but the dump will not be able to be restored directly and user
733+
intervention will be required.
734+
</para>
724735
</sect2>
725736

726737
<sect2>

‎src/bin/pg_dump/pg_dump.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13886,6 +13886,33 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
1388613886

1388713887
/*
1388813888
* getExtensionMembership --- obtain extension membership data
13889+
*
13890+
* There are three main parts to this process:
13891+
*
13892+
* 1. Identify objects which are members of extensions
13893+
*
13894+
* Generally speaking, this is to mark them as *not* being dumped, as most
13895+
* extension objects are created by the single CREATE EXTENSION command.
13896+
* The one exception is binary upgrades with pg_upgrade will still dump the
13897+
* non-table objects.
13898+
*
13899+
* 2. Identify and create dump records for extension configuration tables.
13900+
*
13901+
* Extensions can mark tables as "configuration", which means that the user
13902+
* is able and expected to modify those tables after the extension has been
13903+
* loaded. For these tables, we dump out only the data- the structure is
13904+
* expected to be handled at CREATE EXTENSION time, including any indexes or
13905+
* foriegn keys, which brings us to-
13906+
*
13907+
* 3. Record FK dependencies between configuration tables.
13908+
*
13909+
* Due to the FKs being created at CREATE EXTENSION time and therefore before
13910+
* the data is loaded, we have to work out what the best order for reloading
13911+
* the data is, to avoid FK violations when the tables are restored. This is
13912+
* not perfect- we can't handle circular dependencies and if any exist they
13913+
* will cause an invalid dump to be produced (though at least all of the data
13914+
* is included for a user to manually restore). This is currently documented
13915+
* but perhaps we can provide a better solution in the future.
1388913916
*/
1389013917
void
1389113918
getExtensionMembership(Archive*fout,ExtensionInfoextinfo[],
@@ -13898,7 +13925,9 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
1389813925
inti_classid,
1389913926
i_objid,
1390013927
i_refclassid,
13901-
i_refobjid;
13928+
i_refobjid,
13929+
i_conrelid,
13930+
i_confrelid;
1390213931
DumpableObject*dobj,
1390313932
*refdobj;
1390413933

@@ -14079,6 +14108,53 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
1407914108
free(extconditionarray);
1408014109
}
1408114110

14111+
/*
14112+
* Now that all the TableInfoData objects have been created for all
14113+
* the extensions, check their FK dependencies and register them to
14114+
* try and dump the data out in an order which they can be restored
14115+
* in.
14116+
*
14117+
* Note that this is not a problem for user tables as their FKs are
14118+
* recreated after the data has been loaded.
14119+
*/
14120+
printfPQExpBuffer(query,
14121+
"SELECT conrelid, confrelid "
14122+
"FROM pg_constraint "
14123+
"JOIN pg_depend ON (objid = confrelid) "
14124+
"WHERE contype = 'f' "
14125+
"AND refclassid = 'pg_extension'::regclass "
14126+
"AND classid = 'pg_class'::regclass;");
14127+
14128+
res=ExecuteSqlQuery(fout,query->data,PGRES_TUPLES_OK);
14129+
ntups=PQntuples(res);
14130+
14131+
i_conrelid=PQfnumber(res,"conrelid");
14132+
i_confrelid=PQfnumber(res,"confrelid");
14133+
14134+
/* Now get the dependencies and register them */
14135+
for (i=0;i<ntups;i++)
14136+
{
14137+
Oidconrelid,confrelid;
14138+
TableInfo*reftable,*contable;
14139+
14140+
conrelid=atooid(PQgetvalue(res,i,i_conrelid));
14141+
confrelid=atooid(PQgetvalue(res,i,i_confrelid));
14142+
contable=findTableByOid(conrelid);
14143+
reftable=findTableByOid(confrelid);
14144+
14145+
if (reftable==NULL||
14146+
reftable->dataObj==NULL||
14147+
contable==NULL||
14148+
contable->dataObj==NULL)
14149+
continue;
14150+
14151+
/*
14152+
* Make referencing TABLE_DATA object depend on the
14153+
* referenced table's TABLE_DATA object.
14154+
*/
14155+
addObjectDependency(&contable->dataObj->dobj,
14156+
reftable->dataObj->dobj.dumpId);
14157+
}
1408214158
destroyPQExpBuffer(query);
1408314159
}
1408414160

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp