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

Commitcab9a06

Browse files
committed
Make TRUNCATE do truncate-in-place when processing a relation that was created
or previously truncated in the current (sub)transaction. This is safe sinceif the (sub)transaction later rolls back, we'd just discard the rel's currentphysical file anyway. This avoids unreasonable growth in the number oftransient files when a relation is repeatedly truncated. Per a performancegripe a couple weeks ago from Todd Cook.
1 parentc38b759 commitcab9a06

File tree

3 files changed

+85
-41
lines changed

3 files changed

+85
-41
lines changed

‎src/backend/catalog/heap.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.357 2009/08/02 22:14:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.358 2009/08/23 19:23:40 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2342,18 +2342,9 @@ heap_truncate(List *relids)
23422342
{
23432343
Oidrid=lfirst_oid(cell);
23442344
Relationrel;
2345-
Oidtoastrelid;
23462345

23472346
rel=heap_open(rid,AccessExclusiveLock);
23482347
relations=lappend(relations,rel);
2349-
2350-
/* If there is a toast table, add it to the list too */
2351-
toastrelid=rel->rd_rel->reltoastrelid;
2352-
if (OidIsValid(toastrelid))
2353-
{
2354-
rel=heap_open(toastrelid,AccessExclusiveLock);
2355-
relations=lappend(relations,rel);
2356-
}
23572348
}
23582349

23592350
/* Don't allow truncate on tables that are referenced by foreign keys */
@@ -2364,19 +2355,47 @@ heap_truncate(List *relids)
23642355
{
23652356
Relationrel=lfirst(cell);
23662357

2367-
/* Truncate theactual file (and discard buffers) */
2368-
RelationTruncate(rel,0);
2358+
/* Truncate therelation */
2359+
heap_truncate_one_rel(rel);
23692360

2370-
/* If this relation has indexes, truncate the indexes too */
2371-
RelationTruncateIndexes(rel);
2372-
2373-
/*
2374-
* Close the relation, but keep exclusive lock on it until commit.
2375-
*/
2361+
/* Close the relation, but keep exclusive lock on it until commit */
23762362
heap_close(rel,NoLock);
23772363
}
23782364
}
23792365

2366+
/*
2367+
* heap_truncate_one_rel
2368+
*
2369+
* This routine deletes all data within the specified relation.
2370+
*
2371+
* This is not transaction-safe, because the truncation is done immediately
2372+
* and cannot be rolled back later. Caller is responsible for having
2373+
* checked permissions etc, and must have obtained AccessExclusiveLock.
2374+
*/
2375+
void
2376+
heap_truncate_one_rel(Relationrel)
2377+
{
2378+
Oidtoastrelid;
2379+
2380+
/* Truncate the actual file (and discard buffers) */
2381+
RelationTruncate(rel,0);
2382+
2383+
/* If the relation has indexes, truncate the indexes too */
2384+
RelationTruncateIndexes(rel);
2385+
2386+
/* If there is a toast table, truncate that too */
2387+
toastrelid=rel->rd_rel->reltoastrelid;
2388+
if (OidIsValid(toastrelid))
2389+
{
2390+
Relationtoastrel=heap_open(toastrelid,AccessExclusiveLock);
2391+
2392+
RelationTruncate(toastrel,0);
2393+
RelationTruncateIndexes(toastrel);
2394+
/* keep the lock... */
2395+
heap_close(toastrel,NoLock);
2396+
}
2397+
}
2398+
23802399
/*
23812400
* heap_truncate_check_FKs
23822401
*Check for foreign keys referencing a list of relations that

‎src/backend/commands/tablecmds.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.297 2009/08/1223:00:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.298 2009/08/23 19:23:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -775,6 +775,7 @@ ExecuteTruncate(TruncateStmt *stmt)
775775
EState*estate;
776776
ResultRelInfo*resultRelInfos;
777777
ResultRelInfo*resultRelInfo;
778+
SubTransactionIdmySubid;
778779
ListCell*cell;
779780

780781
/*
@@ -944,36 +945,58 @@ ExecuteTruncate(TruncateStmt *stmt)
944945
/*
945946
* OK, truncate each table.
946947
*/
948+
mySubid=GetCurrentSubTransactionId();
949+
947950
foreach(cell,rels)
948951
{
949952
Relationrel= (Relation)lfirst(cell);
950-
Oidheap_relid;
951-
Oidtoast_relid;
952953

953954
/*
954-
* Create a new empty storage file for the relation, and assign it as
955-
* the relfilenode value.The old storage file is scheduled for
956-
* deletion at commit.
955+
* Normally, we need a transaction-safe truncation here. However,
956+
* if the table was either created in the current (sub)transaction
957+
* or has a new relfilenode in the current (sub)transaction, then
958+
* we can just truncate it in-place, because a rollback would
959+
* cause the whole table or the current physical file to be
960+
* thrown away anyway.
957961
*/
958-
setNewRelfilenode(rel,RecentXmin);
959-
960-
heap_relid=RelationGetRelid(rel);
961-
toast_relid=rel->rd_rel->reltoastrelid;
962-
963-
/*
964-
* The same for the toast table, if any.
965-
*/
966-
if (OidIsValid(toast_relid))
962+
if (rel->rd_createSubid==mySubid||
963+
rel->rd_newRelfilenodeSubid==mySubid)
967964
{
968-
rel=relation_open(toast_relid,AccessExclusiveLock);
969-
setNewRelfilenode(rel,RecentXmin);
970-
heap_close(rel,NoLock);
965+
/* Immediate, non-rollbackable truncation is OK */
966+
heap_truncate_one_rel(rel);
971967
}
968+
else
969+
{
970+
Oidheap_relid;
971+
Oidtoast_relid;
972972

973-
/*
974-
* Reconstruct the indexes to match, and we're done.
975-
*/
976-
reindex_relation(heap_relid, true);
973+
/*
974+
* Need the full transaction-safe pushups.
975+
*
976+
* Create a new empty storage file for the relation, and assign it
977+
* as the relfilenode value. The old storage file is scheduled for
978+
* deletion at commit.
979+
*/
980+
setNewRelfilenode(rel,RecentXmin);
981+
982+
heap_relid=RelationGetRelid(rel);
983+
toast_relid=rel->rd_rel->reltoastrelid;
984+
985+
/*
986+
* The same for the toast table, if any.
987+
*/
988+
if (OidIsValid(toast_relid))
989+
{
990+
rel=relation_open(toast_relid,AccessExclusiveLock);
991+
setNewRelfilenode(rel,RecentXmin);
992+
heap_close(rel,NoLock);
993+
}
994+
995+
/*
996+
* Reconstruct the indexes to match, and we're done.
997+
*/
998+
reindex_relation(heap_relid, true);
999+
}
9771000
}
9781001

9791002
/*

‎src/include/catalog/heap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.91 2009/06/11 14:49:09 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.92 2009/08/23 19:23:41 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -62,6 +62,8 @@ extern void heap_drop_with_catalog(Oid relid);
6262

6363
externvoidheap_truncate(List*relids);
6464

65+
externvoidheap_truncate_one_rel(Relationrel);
66+
6567
externvoidheap_truncate_check_FKs(List*relations,booltempTables);
6668

6769
externList*heap_truncate_find_FKs(List*relationIds);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp