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

Commit82eed4d

Browse files
committed
Arrange to put TOAST tables belonging to temporary tables into special schemas
named pg_toast_temp_nnn, alongside the pg_temp_nnn schemas used for the temptables themselves. This allows low-level code such as the relcache torecognize that these tables are indeed temporary, which enables variousoptimizations such as not WAL-logging changes and using local rather thanshared buffers for access. Aside from obvious performance benefits, thisprovides a solution to bug #3483, in which other backends unexpectedly heldopen file references to temporary tables. The scheme preserves the propertythat TOAST tables are not in any schema that's normally in the search path,so they don't conflict with user table names.initdb forced because of changes in system view definitions.
1 parentfdb5b69 commit82eed4d

File tree

11 files changed

+148
-56
lines changed

11 files changed

+148
-56
lines changed

‎contrib/oid2name/oid2name.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Originally by
66
* B. Palmer, bpalmer@crimelabs.net 1-17-2001
7-
* $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.31 2007/07/15 22:54:20 tgl Exp $
7+
* $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.32 2007/07/25 22:16:17 tgl Exp $
88
*/
99
#include"postgres_fe.h"
1010

@@ -411,16 +411,17 @@ sql_exec_dumpalltables(PGconn *conn, struct options * opts)
411411
"LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
412412
"LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),"
413413
"pg_catalog.pg_tablespace t "
414-
"WHERE relkind IN ('r'%s) AND "
414+
"WHERE relkind IN ('r'%s%s) AND "
415415
"%s"
416416
"t.oid = CASE"
417417
"WHEN reltablespace <> 0 THEN reltablespace"
418418
"ELSE dattablespace"
419419
"END "
420420
"ORDER BY relname",
421421
opts->extended ?addfields :"",
422-
opts->indexes ?", 'i', 'S', 't'" :"",
423-
opts->systables ?"" :"n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema') AND");
422+
opts->indexes ?", 'i', 'S'" :"",
423+
opts->systables ?", 't'" :"",
424+
opts->systables ?"" :"n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname !~ '^pg_toast' AND");
424425

425426
sql_exec(conn,todo,opts->quiet);
426427
}

‎src/backend/catalog/catalog.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.70 2007/03/2519:45:14 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.71 2007/07/2522:16:18 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -24,6 +24,7 @@
2424
#include"access/transam.h"
2525
#include"catalog/catalog.h"
2626
#include"catalog/indexing.h"
27+
#include"catalog/namespace.h"
2728
#include"catalog/pg_auth_members.h"
2829
#include"catalog/pg_authid.h"
2930
#include"catalog/pg_database.h"
@@ -196,15 +197,17 @@ IsSystemNamespace(Oid namespaceId)
196197

197198
/*
198199
* IsToastNamespace
199-
*True iff namespace is pg_toast.
200+
*True iff namespace is pg_toast or my temporary-toast-table namespace.
200201
*
201-
* NOTE: the reason this isn't a macro is to avoid having to include
202-
* catalog/pg_namespace.h in a lot of places.
202+
* Note: this will return false for temporary-toast-table namespaces belonging
203+
* to other backends. Those are treated the same as other backends' regular
204+
* temp table namespaces, and access is prevented where appropriate.
203205
*/
204206
bool
205207
IsToastNamespace(OidnamespaceId)
206208
{
207-
returnnamespaceId==PG_TOAST_NAMESPACE;
209+
return (namespaceId==PG_TOAST_NAMESPACE)||
210+
isTempToastNamespace(namespaceId);
208211
}
209212

210213

‎src/backend/catalog/namespace.c

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.96 2007/04/20 02:37:37 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.97 2007/07/25 22:16:18 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -152,6 +152,9 @@ static List *overrideStack = NIL;
152152
* in a particular backend session (this happens when a CREATE TEMP TABLE
153153
* command is first executed).Thereafter it's the OID of the temp namespace.
154154
*
155+
* myTempToastNamespace is the OID of the namespace for my temp tables' toast
156+
* tables. It is set when myTempNamespace is, and is InvalidOid before that.
157+
*
155158
* myTempNamespaceSubID shows whether we've created the TEMP namespace in the
156159
* current subtransaction.The flag propagates up the subtransaction tree,
157160
* so the main transaction will correctly recognize the flag if all
@@ -161,6 +164,8 @@ static List *overrideStack = NIL;
161164
*/
162165
staticOidmyTempNamespace=InvalidOid;
163166

167+
staticOidmyTempToastNamespace=InvalidOid;
168+
164169
staticSubTransactionIdmyTempNamespaceSubID=InvalidSubTransactionId;
165170

166171
/*
@@ -1599,39 +1604,78 @@ isTempNamespace(Oid namespaceId)
15991604
return false;
16001605
}
16011606

1607+
/*
1608+
* isTempToastNamespace - is the given namespace my temporary-toast-table
1609+
*namespace?
1610+
*/
1611+
bool
1612+
isTempToastNamespace(OidnamespaceId)
1613+
{
1614+
if (OidIsValid(myTempToastNamespace)&&myTempToastNamespace==namespaceId)
1615+
return true;
1616+
return false;
1617+
}
1618+
1619+
/*
1620+
* isTempOrToastNamespace - is the given namespace my temporary-table
1621+
*namespace or my temporary-toast-table namespace?
1622+
*/
1623+
bool
1624+
isTempOrToastNamespace(OidnamespaceId)
1625+
{
1626+
if (OidIsValid(myTempNamespace)&&
1627+
(myTempNamespace==namespaceId||myTempToastNamespace==namespaceId))
1628+
return true;
1629+
return false;
1630+
}
1631+
16021632
/*
16031633
* isAnyTempNamespace - is the given namespace a temporary-table namespace
1604-
* (either my own, or another backend's)?
1634+
* (either my own, or another backend's)? Temporary-toast-table namespaces
1635+
* are included, too.
16051636
*/
16061637
bool
16071638
isAnyTempNamespace(OidnamespaceId)
16081639
{
16091640
boolresult;
16101641
char*nspname;
16111642

1612-
/*Ifthe namespace name starts with "pg_temp_", say "true" */
1643+
/*True ifthe namespace name starts with "pg_temp_" or "pg_toast_temp_" */
16131644
nspname=get_namespace_name(namespaceId);
16141645
if (!nspname)
16151646
return false;/* no such namespace? */
1616-
result= (strncmp(nspname,"pg_temp_",8)==0);
1647+
result= (strncmp(nspname,"pg_temp_",8)==0)||
1648+
(strncmp(nspname,"pg_toast_temp_",14)==0);
16171649
pfree(nspname);
16181650
returnresult;
16191651
}
16201652

16211653
/*
16221654
* isOtherTempNamespace - is the given namespace some other backend's
1623-
* temporary-table namespace?
1655+
* temporary-table namespace (including temporary-toast-table namespaces)?
16241656
*/
16251657
bool
16261658
isOtherTempNamespace(OidnamespaceId)
16271659
{
16281660
/* If it's my own temp namespace, say "false" */
1629-
if (isTempNamespace(namespaceId))
1661+
if (isTempOrToastNamespace(namespaceId))
16301662
return false;
1631-
/* Else, ifthe namespace name starts with "pg_temp_", say "true" */
1663+
/* Else, ifit's any temp namespace, say "true" */
16321664
returnisAnyTempNamespace(namespaceId);
16331665
}
16341666

1667+
/*
1668+
* GetTempToastNamespace - get the OID of my temporary-toast-table namespace,
1669+
* which must already be assigned. (This is only used when creating a toast
1670+
* table for a temp table, so we must have already done InitTempTableNamespace)
1671+
*/
1672+
Oid
1673+
GetTempToastNamespace(void)
1674+
{
1675+
Assert(OidIsValid(myTempToastNamespace));
1676+
returnmyTempToastNamespace;
1677+
}
1678+
16351679

16361680
/*
16371681
* GetOverrideSearchPath - fetch current search path definition in form
@@ -2006,6 +2050,7 @@ InitTempTableNamespace(void)
20062050
{
20072051
charnamespaceName[NAMEDATALEN];
20082052
OidnamespaceId;
2053+
OidtoastspaceId;
20092054

20102055
Assert(!OidIsValid(myTempNamespace));
20112056

@@ -2054,12 +2099,31 @@ InitTempTableNamespace(void)
20542099
RemoveTempRelations(namespaceId);
20552100
}
20562101

2102+
/*
2103+
* If the corresponding temp-table namespace doesn't exist yet, create it.
2104+
* (We assume there is no need to clean it out if it does exist, since
2105+
* dropping a parent table should make its toast table go away.)
2106+
*/
2107+
snprintf(namespaceName,sizeof(namespaceName),"pg_toast_temp_%d",
2108+
MyBackendId);
2109+
2110+
toastspaceId=GetSysCacheOid(NAMESPACENAME,
2111+
CStringGetDatum(namespaceName),
2112+
0,0,0);
2113+
if (!OidIsValid(toastspaceId))
2114+
{
2115+
toastspaceId=NamespaceCreate(namespaceName,BOOTSTRAP_SUPERUSERID);
2116+
/* Advance command counter to make namespace visible */
2117+
CommandCounterIncrement();
2118+
}
2119+
20572120
/*
20582121
* Okay, we've prepared the temp namespace ... but it's not committed yet,
20592122
* so all our work could be undone by transaction rollback. Set flag for
20602123
* AtEOXact_Namespace to know what to do.
20612124
*/
20622125
myTempNamespace=namespaceId;
2126+
myTempToastNamespace=toastspaceId;
20632127

20642128
/* It should not be done already. */
20652129
AssertState(myTempNamespaceSubID==InvalidSubTransactionId);
@@ -2089,6 +2153,7 @@ AtEOXact_Namespace(bool isCommit)
20892153
else
20902154
{
20912155
myTempNamespace=InvalidOid;
2156+
myTempToastNamespace=InvalidOid;
20922157
baseSearchPathValid= false;/* need to rebuild list */
20932158
}
20942159
myTempNamespaceSubID=InvalidSubTransactionId;
@@ -2140,6 +2205,7 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
21402205
myTempNamespaceSubID=InvalidSubTransactionId;
21412206
/* TEMP namespace creation failed, so reset state */
21422207
myTempNamespace=InvalidOid;
2208+
myTempToastNamespace=InvalidOid;
21432209
baseSearchPathValid= false;/* need to rebuild list */
21442210
}
21452211
}

‎src/backend/catalog/system_views.sql

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
55
*
6-
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.38 2007/06/28 00:02:37 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.39 2007/07/25 22:16:18 tgl Exp $
77
*/
88

99
CREATEVIEWpg_rolesAS
@@ -221,11 +221,13 @@ CREATE VIEW pg_stat_all_tables AS
221221

222222
CREATEVIEWpg_stat_sys_tablesAS
223223
SELECT*FROM pg_stat_all_tables
224-
WHERE schemanameIN ('pg_catalog','pg_toast','information_schema');
224+
WHERE schemanameIN ('pg_catalog','information_schema')OR
225+
schemaname ~'^pg_toast';
225226

226227
CREATEVIEWpg_stat_user_tablesAS
227228
SELECT*FROM pg_stat_all_tables
228-
WHERE schemaname NOTIN ('pg_catalog','pg_toast','information_schema');
229+
WHERE schemaname NOTIN ('pg_catalog','information_schema')AND
230+
schemaname !~'^pg_toast';
229231

230232
CREATEVIEWpg_statio_all_tablesAS
231233
SELECT
@@ -254,11 +256,13 @@ CREATE VIEW pg_statio_all_tables AS
254256

255257
CREATEVIEWpg_statio_sys_tablesAS
256258
SELECT*FROM pg_statio_all_tables
257-
WHERE schemanameIN ('pg_catalog','pg_toast','information_schema');
259+
WHERE schemanameIN ('pg_catalog','information_schema')OR
260+
schemaname ~'^pg_toast';
258261

259262
CREATEVIEWpg_statio_user_tablesAS
260263
SELECT*FROM pg_statio_all_tables
261-
WHERE schemaname NOTIN ('pg_catalog','pg_toast','information_schema');
264+
WHERE schemaname NOTIN ('pg_catalog','information_schema')AND
265+
schemaname !~'^pg_toast';
262266

263267
CREATEVIEWpg_stat_all_indexesAS
264268
SELECT
@@ -278,11 +282,13 @@ CREATE VIEW pg_stat_all_indexes AS
278282

279283
CREATEVIEWpg_stat_sys_indexesAS
280284
SELECT*FROM pg_stat_all_indexes
281-
WHERE schemanameIN ('pg_catalog','pg_toast','information_schema');
285+
WHERE schemanameIN ('pg_catalog','information_schema')OR
286+
schemaname ~'^pg_toast';
282287

283288
CREATEVIEWpg_stat_user_indexesAS
284289
SELECT*FROM pg_stat_all_indexes
285-
WHERE schemaname NOTIN ('pg_catalog','pg_toast','information_schema');
290+
WHERE schemaname NOTIN ('pg_catalog','information_schema')AND
291+
schemaname !~'^pg_toast';
286292

287293
CREATEVIEWpg_statio_all_indexesAS
288294
SELECT
@@ -302,11 +308,13 @@ CREATE VIEW pg_statio_all_indexes AS
302308

303309
CREATEVIEWpg_statio_sys_indexesAS
304310
SELECT*FROM pg_statio_all_indexes
305-
WHERE schemanameIN ('pg_catalog','pg_toast','information_schema');
311+
WHERE schemanameIN ('pg_catalog','information_schema')OR
312+
schemaname ~'^pg_toast';
306313

307314
CREATEVIEWpg_statio_user_indexesAS
308315
SELECT*FROM pg_statio_all_indexes
309-
WHERE schemaname NOTIN ('pg_catalog','pg_toast','information_schema');
316+
WHERE schemaname NOTIN ('pg_catalog','information_schema')AND
317+
schemaname !~'^pg_toast';
310318

311319
CREATEVIEWpg_statio_all_sequencesAS
312320
SELECT
@@ -322,11 +330,13 @@ CREATE VIEW pg_statio_all_sequences AS
322330

323331
CREATEVIEWpg_statio_sys_sequencesAS
324332
SELECT*FROM pg_statio_all_sequences
325-
WHERE schemanameIN ('pg_catalog','pg_toast','information_schema');
333+
WHERE schemanameIN ('pg_catalog','information_schema')OR
334+
schemaname ~'^pg_toast';
326335

327336
CREATEVIEWpg_statio_user_sequencesAS
328337
SELECT*FROM pg_statio_all_sequences
329-
WHERE schemaname NOTIN ('pg_catalog','pg_toast','information_schema');
338+
WHERE schemaname NOTIN ('pg_catalog','information_schema')AND
339+
schemaname !~'^pg_toast';
330340

331341
CREATEVIEWpg_stat_activityAS
332342
SELECT

‎src/backend/catalog/toasting.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.6 2007/04/06 04:21:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.7 2007/07/25 22:16:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -21,6 +21,7 @@
2121
#include"catalog/heap.h"
2222
#include"catalog/index.h"
2323
#include"catalog/indexing.h"
24+
#include"catalog/namespace.h"
2425
#include"catalog/pg_namespace.h"
2526
#include"catalog/pg_opclass.h"
2627
#include"catalog/pg_type.h"
@@ -108,6 +109,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
108109
Relationclass_rel;
109110
Oidtoast_relid;
110111
Oidtoast_idxid;
112+
Oidnamespaceid;
111113
chartoast_relname[NAMEDATALEN];
112114
chartoast_idxname[NAMEDATALEN];
113115
IndexInfo*indexInfo;
@@ -173,16 +175,20 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
173175
tupdesc->attrs[2]->attstorage='p';
174176

175177
/*
176-
* Note: the toast relation is placed in the regular pg_toast namespace
177-
* even if its master relation is a temp table. There cannot be any
178-
* naming collision, and the toast rel will be destroyed when its master
179-
* is, so there's no need to handle the toast rel as temp.
180-
*
178+
* Toast tables for regular relations go in pg_toast; those for temp
179+
* relations go into the per-backend temp-toast-table namespace.
180+
*/
181+
if (rel->rd_istemp)
182+
namespaceid=GetTempToastNamespace();
183+
else
184+
namespaceid=PG_TOAST_NAMESPACE;
185+
186+
/*
181187
* XXX would it make sense to apply the master's reloptions to the toast
182-
* table?
188+
* table? Or maybe some toast-specific reloptions?
183189
*/
184190
toast_relid=heap_create_with_catalog(toast_relname,
185-
PG_TOAST_NAMESPACE,
191+
namespaceid,
186192
rel->rd_rel->reltablespace,
187193
toastOid,
188194
rel->rd_rel->relowner,

‎src/backend/storage/lmgr/lmgr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.91 2007/06/19 20:13:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.92 2007/07/25 22:16:18 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -619,7 +619,7 @@ LockTagIsTemp(const LOCKTAG *tag)
619619
/* field1 is dboid, field2 is reloid for all of these */
620620
if ((Oid)tag->locktag_field1==InvalidOid)
621621
return false;/* shared, so not temp */
622-
if (isTempNamespace(get_rel_namespace((Oid)tag->locktag_field2)))
622+
if (isTempOrToastNamespace(get_rel_namespace((Oid)tag->locktag_field2)))
623623
return true;
624624
break;
625625
caseLOCKTAG_TRANSACTION:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp