Content-Length: 1109228 | pFad | http://github.com/tonybelloni/postgres/commit/82eed4dba254b8fda71d429b29d222ffb4e93fca

4D Arrange to put TOAST tables belonging to temporary tables into specia… · tonybelloni/postgres@82eed4d · GitHub
Skip to content

Commit 82eed4d

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 temp tables themselves. This allows low-level code such as the relcache to recognize that these tables are indeed temporary, which enables various optimizations such as not WAL-logging changes and using local rather than shared buffers for access. Aside from obvious performance benefits, this provides a solution to bug #3483, in which other backends unexpectedly held open file references to temporary tables. The scheme preserves the property that 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 parent fdb5b69 commit 82eed4d

File tree

11 files changed

+148
-56
lines changed

11 files changed

+148
-56
lines changed

contrib/oid2name/oid2name.c

+5-4
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

+8-5
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/25 19:45:14 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.71 2007/07/25 22: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(Oid namespaceId)
206208
{
207-
return namespaceId == PG_TOAST_NAMESPACE;
209+
return (namespaceId == PG_TOAST_NAMESPACE) ||
210+
isTempToastNamespace(namespaceId);
208211
}
209212

210213

src/backend/catalog/namespace.c

+73-7
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
static Oid myTempNamespace = InvalidOid;
163166

167+
static Oid myTempToastNamespace = InvalidOid;
168+
164169
static SubTransactionId myTempNamespaceSubID = 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(Oid namespaceId)
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(Oid namespaceId)
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(Oid namespaceId)
16081639
{
16091640
bool result;
16101641
char *nspname;
16111642

1612-
/* If the namespace name starts with "pg_temp_", say "true" */
1643+
/* True if the 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
return result;
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(Oid namespaceId)
16271659
{
16281660
/* If it's my own temp namespace, say "false" */
1629-
if (isTempNamespace(namespaceId))
1661+
if (isTempOrToastNamespace(namespaceId))
16301662
return false;
1631-
/* Else, if the namespace name starts with "pg_temp_", say "true" */
1663+
/* Else, if it's any temp namespace, say "true" */
16321664
return isAnyTempNamespace(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+
return myTempToastNamespace;
1677+
}
1678+
16351679

16361680
/*
16371681
* GetOverrideSearchPath - fetch current search path definition in form
@@ -2006,6 +2050,7 @@ InitTempTableNamespace(void)
20062050
{
20072051
char namespaceName[NAMEDATALEN];
20082052
Oid namespaceId;
2053+
Oid toastspaceId;
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

+21-11
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
CREATE VIEW pg_roles AS
@@ -221,11 +221,13 @@ CREATE VIEW pg_stat_all_tables AS
221221

222222
CREATE VIEW pg_stat_sys_tables AS
223223
SELECT * FROM pg_stat_all_tables
224-
WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
224+
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
225+
schemaname ~ '^pg_toast';
225226

226227
CREATE VIEW pg_stat_user_tables AS
227228
SELECT * FROM pg_stat_all_tables
228-
WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
229+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
230+
schemaname !~ '^pg_toast';
229231

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

255257
CREATE VIEW pg_statio_sys_tables AS
256258
SELECT * FROM pg_statio_all_tables
257-
WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
259+
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
260+
schemaname ~ '^pg_toast';
258261

259262
CREATE VIEW pg_statio_user_tables AS
260263
SELECT * FROM pg_statio_all_tables
261-
WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
264+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
265+
schemaname !~ '^pg_toast';
262266

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

279283
CREATE VIEW pg_stat_sys_indexes AS
280284
SELECT * FROM pg_stat_all_indexes
281-
WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
285+
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
286+
schemaname ~ '^pg_toast';
282287

283288
CREATE VIEW pg_stat_user_indexes AS
284289
SELECT * FROM pg_stat_all_indexes
285-
WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
290+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
291+
schemaname !~ '^pg_toast';
286292

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

303309
CREATE VIEW pg_statio_sys_indexes AS
304310
SELECT * FROM pg_statio_all_indexes
305-
WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
311+
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
312+
schemaname ~ '^pg_toast';
306313

307314
CREATE VIEW pg_statio_user_indexes AS
308315
SELECT * FROM pg_statio_all_indexes
309-
WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
316+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
317+
schemaname !~ '^pg_toast';
310318

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

323331
CREATE VIEW pg_statio_sys_sequences AS
324332
SELECT * FROM pg_statio_all_sequences
325-
WHERE schemaname IN ('pg_catalog', 'pg_toast', 'information_schema');
333+
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
334+
schemaname ~ '^pg_toast';
326335

327336
CREATE VIEW pg_statio_user_sequences AS
328337
SELECT * FROM pg_statio_all_sequences
329-
WHERE schemaname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');
338+
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
339+
schemaname !~ '^pg_toast';
330340

331341
CREATE VIEW pg_stat_activity AS
332342
SELECT

src/backend/catalog/toasting.c

+14-8
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
Relation class_rel;
109110
Oid toast_relid;
110111
Oid toast_idxid;
112+
Oid namespaceid;
111113
char toast_relname[NAMEDATALEN];
112114
char toast_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

+2-2
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
case LOCKTAG_TRANSACTION:

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tonybelloni/postgres/commit/82eed4dba254b8fda71d429b29d222ffb4e93fca

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy