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

Commitd46f3de

Browse files
committed
Transaction safe Truncate
Rod Taylor
1 parenta2b4a70 commitd46f3de

File tree

5 files changed

+68
-29
lines changed

5 files changed

+68
-29
lines changed

‎src/backend/commands/cluster.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.95 2002/11/18 17:12:07 momjian Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.96 2002/11/23 04:05:51 momjian Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -20,12 +20,13 @@
2020
#include"access/genam.h"
2121
#include"access/heapam.h"
2222
#include"catalog/catalog.h"
23+
#include"catalog/catname.h"
2324
#include"catalog/dependency.h"
2425
#include"catalog/heap.h"
2526
#include"catalog/index.h"
2627
#include"catalog/indexing.h"
27-
#include"catalog/catname.h"
2828
#include"catalog/namespace.h"
29+
#include"catalog/pg_constraint.h"
2930
#include"commands/cluster.h"
3031
#include"commands/tablecmds.h"
3132
#include"miscadmin.h"
@@ -63,7 +64,6 @@ typedef struct
6364

6465
staticOidmake_new_heap(OidOIDOldHeap,constchar*NewName);
6566
staticvoidcopy_heap_data(OidOIDNewHeap,OidOIDOldHeap,OidOIDOldIndex);
66-
staticList*get_indexattr_list(RelationOldHeap,OidOldIndex);
6767
staticvoidrecreate_indexattr(OidOIDOldHeap,List*indexes);
6868
staticvoidswap_relfilenodes(Oidr1,Oidr2);
6969
staticvoidcluster_rel(relToCluster*rv);
@@ -92,11 +92,8 @@ static MemoryContext cluster_context = NULL;
9292
void
9393
cluster_rel(relToCluster*rvtc)
9494
{
95-
OidOIDNewHeap;
9695
RelationOldHeap,
9796
OldIndex;
98-
charNewHeapName[NAMEDATALEN];
99-
ObjectAddressobject;
10097
List*indexes;
10198

10299
/* Check for user-requested abort. */
@@ -172,6 +169,22 @@ cluster_rel(relToCluster *rvtc)
172169
index_close(OldIndex);
173170
heap_close(OldHeap,NoLock);
174171

172+
/* rebuild_rel does all the dirty work */
173+
rebuild_rel(rvtc->tableOid,rvtc->indexOid,indexes, true);
174+
}
175+
176+
void
177+
rebuild_rel(OidtableOid,OidindexOid,List*indexes,booldataCopy)
178+
{
179+
OidOIDNewHeap;
180+
charNewHeapName[NAMEDATALEN];
181+
ObjectAddressobject;
182+
183+
/*
184+
* If dataCopy is true, we assume that we will be basing the
185+
* copy off an index for cluster operations.
186+
*/
187+
Assert(!dataCopy||indexOid!=NULL);
175188
/*
176189
* Create the new heap, using a temporary name in the same namespace
177190
* as the existing table. NOTE: there is some risk of collision with
@@ -180,10 +193,9 @@ cluster_rel(relToCluster *rvtc)
180193
* namespace from the old, or we will have problems with the TEMP
181194
* status of temp tables.
182195
*/
183-
snprintf(NewHeapName,NAMEDATALEN,"pg_temp_%u",rvtc->tableOid);
184-
185-
OIDNewHeap=make_new_heap(rvtc->tableOid,NewHeapName);
196+
snprintf(NewHeapName,NAMEDATALEN,"pg_temp_%u",tableOid);
186197

198+
OIDNewHeap=make_new_heap(tableOid,NewHeapName);
187199
/*
188200
* We don't need CommandCounterIncrement() because make_new_heap did
189201
* it.
@@ -192,13 +204,14 @@ cluster_rel(relToCluster *rvtc)
192204
/*
193205
* Copy the heap data into the new table in the desired order.
194206
*/
195-
copy_heap_data(OIDNewHeap,rvtc->tableOid,rvtc->indexOid);
207+
if (dataCopy)
208+
copy_heap_data(OIDNewHeap,tableOid,indexOid);
196209

197210
/* To make the new heap's data visible (probably not needed?). */
198211
CommandCounterIncrement();
199212

200213
/* Swap the relfilenodes of the old and new heaps. */
201-
swap_relfilenodes(rvtc->tableOid,OIDNewHeap);
214+
swap_relfilenodes(tableOid,OIDNewHeap);
202215

203216
CommandCounterIncrement();
204217

@@ -219,7 +232,7 @@ cluster_rel(relToCluster *rvtc)
219232
* Recreate each index on the relation. We do not need
220233
* CommandCounterIncrement() because recreate_indexattr does it.
221234
*/
222-
recreate_indexattr(rvtc->tableOid,indexes);
235+
recreate_indexattr(tableOid,indexes);
223236
}
224237

225238
/*
@@ -322,7 +335,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
322335
* Get the necessary info about the indexes of the relation and
323336
* return a list of IndexAttrs structures.
324337
*/
325-
staticList*
338+
List*
326339
get_indexattr_list(RelationOldHeap,OidOldIndex)
327340
{
328341
List*indexes=NIL;

‎src/backend/commands/tablecmds.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.55 2002/11/2303:59:07 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.56 2002/11/2304:05:51 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,6 +29,7 @@
2929
#include"catalog/pg_opclass.h"
3030
#include"catalog/pg_trigger.h"
3131
#include"catalog/pg_type.h"
32+
#include"commands/cluster.h"
3233
#include"commands/tablecmds.h"
3334
#include"commands/trigger.h"
3435
#include"executor/executor.h"
@@ -360,7 +361,7 @@ RemoveRelation(const RangeVar *relation, DropBehavior behavior)
360361
*Removes all the rows from a relation.
361362
*
362363
* Note: This routine only does safety and permissions checks;
363-
*heap_truncate does the actual work.
364+
*rebuild_rel in cluster.c does the actual work.
364365
*/
365366
void
366367
TruncateRelation(constRangeVar*relation)
@@ -371,6 +372,7 @@ TruncateRelation(const RangeVar *relation)
371372
RelationfkeyRel;
372373
SysScanDescfkeyScan;
373374
HeapTupletuple;
375+
List*indexes;
374376

375377
/* Grab exclusive lock in preparation for truncate */
376378
rel=heap_openrv(relation,AccessExclusiveLock);
@@ -399,16 +401,6 @@ TruncateRelation(const RangeVar *relation)
399401
if (!pg_class_ownercheck(relid,GetUserId()))
400402
aclcheck_error(ACLCHECK_NOT_OWNER,RelationGetRelationName(rel));
401403

402-
/*
403-
* Truncate within a transaction block is dangerous, because if
404-
* the transaction is later rolled back we have no way to undo
405-
* truncation of the relation's physical file. Disallow it except for
406-
* a rel created in the current xact (which would be deleted on abort,
407-
* anyway).
408-
*/
409-
if (!rel->rd_isnew)
410-
PreventTransactionChain((void*)relation,"TRUNCATE TABLE");
411-
412404
/*
413405
* Don't allow truncate on temp tables of other backends ... their
414406
* local buffer manager is not going to cope.
@@ -438,19 +430,26 @@ TruncateRelation(const RangeVar *relation)
438430
Form_pg_constraintcon= (Form_pg_constraint)GETSTRUCT(tuple);
439431

440432
if (con->contype=='f'&&con->conrelid!=relid)
441-
elog(ERROR,"TRUNCATE cannot be used as table %s references this one via foreign key constraint %s",
433+
elog(ERROR,"TRUNCATE cannot be used as table %s references "
434+
"this one via foreign key constraint %s",
442435
get_rel_name(con->conrelid),
443436
NameStr(con->conname));
444437
}
445438

446439
systable_endscan(fkeyScan);
447440
heap_close(fkeyRel,AccessShareLock);
448441

442+
/* Save the information of all indexes on the relation. */
443+
indexes=get_indexattr_list(rel,InvalidOid);
444+
449445
/* Keep the lock until transaction commit */
450446
heap_close(rel,NoLock);
451447

452-
/* Do the real work */
453-
heap_truncate(relid);
448+
/*
449+
* Do the real work using the same technique as cluster, but
450+
* without the code copy portion
451+
*/
452+
rebuild_rel(relid,NULL,indexes, false);
454453
}
455454

456455
/*----------

‎src/include/commands/cluster.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994-5, Regents of the University of California
88
*
9-
* $Id: cluster.h,v 1.16 2002/11/15 03:09:39 momjian Exp $
9+
* $Id: cluster.h,v 1.17 2002/11/23 04:05:52 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -19,4 +19,9 @@
1919
*/
2020
externvoidcluster(ClusterStmt*stmt);
2121

22+
externList*get_indexattr_list(RelationOldHeap,OidOldIndex);
23+
externvoidrebuild_rel(OidtableOid,OidindexOid,
24+
List*indexes,booldataCopy);
25+
26+
2227
#endif/* CLUSTER_H */

‎src/test/regress/expected/truncate.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,21 @@ SELECT * FROM truncate_a;
1010
2
1111
(2 rows)
1212

13+
-- Roll truncate back
14+
BEGIN;
1315
TRUNCATE truncate_a;
16+
ROLLBACK;
17+
SELECT * FROM truncate_a;
18+
col1
19+
------
20+
1
21+
2
22+
(2 rows)
23+
24+
-- Commit the truncate this time
25+
BEGIN;
26+
TRUNCATE truncate_a;
27+
COMMIT;
1428
SELECT * FROM truncate_a;
1529
col1
1630
------

‎src/test/regress/sql/truncate.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ CREATE TABLE truncate_a (col1 integer primary key);
33
INSERT INTO truncate_aVALUES (1);
44
INSERT INTO truncate_aVALUES (2);
55
SELECT*FROM truncate_a;
6+
-- Roll truncate back
7+
BEGIN;
68
TRUNCATE truncate_a;
9+
ROLLBACK;
10+
SELECT*FROM truncate_a;
11+
-- Commit the truncate this time
12+
BEGIN;
13+
TRUNCATE truncate_a;
14+
COMMIT;
715
SELECT*FROM truncate_a;
816

917
-- Test foreign constraint check

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp