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

Commitc66eb00

Browse files
committed
Allow ANALYZE to run in a transaction.
1 parentdeec3cb commitc66eb00

File tree

2 files changed

+93
-96
lines changed

2 files changed

+93
-96
lines changed

‎src/backend/commands/analyze.c

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.35 2002/05/24 18:57:55 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.36 2002/06/13 19:52:02 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -155,15 +155,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
155155
else
156156
elevel=DEBUG1;
157157

158-
/*
159-
* Begin a transaction for analyzing this relation.
160-
*
161-
* Note: All memory allocated during ANALYZE will live in
162-
* TransactionCommandContext or a subcontext thereof, so it will all
163-
* be released by transaction commit at the end of this routine.
164-
*/
165-
StartTransactionCommand();
166-
167158
/*
168159
* Check for user-requested abort.Note we want this to be inside a
169160
* transaction, so xact.c doesn't issue useless WARNING.
@@ -177,10 +168,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
177168
if (!SearchSysCacheExists(RELOID,
178169
ObjectIdGetDatum(relid),
179170
0,0,0))
180-
{
181-
CommitTransactionCommand();
182171
return;
183-
}
184172

185173
/*
186174
* Open the class, getting only a read lock on it, and check
@@ -196,7 +184,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
196184
elog(WARNING,"Skipping \"%s\" --- only table or database owner can ANALYZE it",
197185
RelationGetRelationName(onerel));
198186
relation_close(onerel,AccessShareLock);
199-
CommitTransactionCommand();
200187
return;
201188
}
202189

@@ -211,7 +198,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
211198
elog(WARNING,"Skipping \"%s\" --- can not process indexes, views or special system tables",
212199
RelationGetRelationName(onerel));
213200
relation_close(onerel,AccessShareLock);
214-
CommitTransactionCommand();
215201
return;
216202
}
217203

@@ -222,7 +208,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
222208
strcmp(RelationGetRelationName(onerel),StatisticRelationName)==0)
223209
{
224210
relation_close(onerel,AccessShareLock);
225-
CommitTransactionCommand();
226211
return;
227212
}
228213

@@ -283,7 +268,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
283268
if (attr_cnt <=0)
284269
{
285270
relation_close(onerel,NoLock);
286-
CommitTransactionCommand();
287271
return;
288272
}
289273

@@ -370,9 +354,6 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
370354
* entries we made in pg_statistic.)
371355
*/
372356
relation_close(onerel,NoLock);
373-
374-
/* Commit and release working memory */
375-
CommitTransactionCommand();
376357
}
377358

378359
/*

‎src/backend/commands/vacuum.c

Lines changed: 92 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.226 2002/05/24 18:57:56 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.227 2002/06/13 19:52:02 momjian Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -110,8 +110,6 @@ static TransactionId initialFreezeLimit;
110110

111111

112112
/* non-export function prototypes */
113-
staticvoidvacuum_init(VacuumStmt*vacstmt);
114-
staticvoidvacuum_shutdown(VacuumStmt*vacstmt);
115113
staticList*getrels(constRangeVar*vacrel,constchar*stmttype);
116114
staticvoidvac_update_dbstats(Oiddbid,
117115
TransactionIdvacuumXID,
@@ -160,6 +158,8 @@ static bool enough_space(VacPage vacpage, Size len);
160158
void
161159
vacuum(VacuumStmt*vacstmt)
162160
{
161+
MemoryContextanl_context,
162+
old_context;
163163
constchar*stmttype=vacstmt->vacuum ?"VACUUM" :"ANALYZE";
164164
List*vrl,
165165
*cur;
@@ -178,13 +178,13 @@ vacuum(VacuumStmt *vacstmt)
178178
* user's transaction too, which would certainly not be the desired
179179
* behavior.
180180
*/
181-
if (IsTransactionBlock())
181+
if (vacstmt->vacuum&&IsTransactionBlock())
182182
elog(ERROR,"%s cannot run inside a BEGIN/END block",stmttype);
183183

184184
/* Running VACUUM from a function would free the function context */
185-
if (!MemoryContextContains(QueryContext,vacstmt))
185+
if (vacstmt->vacuum&&!MemoryContextContains(QueryContext,vacstmt))
186186
elog(ERROR,"%s cannot be executed from a function",stmttype);
187-
187+
188188
/*
189189
* Send info about dead objects to the statistics collector
190190
*/
@@ -203,13 +203,62 @@ vacuum(VacuumStmt *vacstmt)
203203
ALLOCSET_DEFAULT_INITSIZE,
204204
ALLOCSET_DEFAULT_MAXSIZE);
205205

206+
if (vacstmt->analyze&& !vacstmt->vacuum)
207+
anl_context=AllocSetContextCreate(QueryContext,
208+
"Analyze",
209+
ALLOCSET_DEFAULT_MINSIZE,
210+
ALLOCSET_DEFAULT_INITSIZE,
211+
ALLOCSET_DEFAULT_MAXSIZE);
212+
206213
/* Build list of relations to process (note this lives in vac_context) */
207214
vrl=getrels(vacstmt->relation,stmttype);
208215

209216
/*
210-
* Start up the vacuum cleaner.
217+
*Formerly, there was code here to prevent more than one VACUUM from
218+
*executing concurrently in the same database. However, there's no
219+
*good reason to prevent that, and manually removing lockfiles after
220+
*a vacuum crash was a pain for dbadmins. So, forget about lockfiles,
221+
*and just rely on the locks we grab on each target table
222+
*to ensure that there aren't two VACUUMs running on the same table
223+
*at the same time.
224+
*
225+
*The strangeness with committing and starting transactions in the
226+
*init and shutdown routines is due to the fact that the vacuum cleaner
227+
*is invoked via an SQL command, and so is already executing inside
228+
*a transaction.We need to leave ourselves in a predictable state
229+
*on entry and exit to the vacuum cleaner. We commit the transaction
230+
*started in PostgresMain() inside vacuum_init(), and start one in
231+
*vacuum_shutdown() to match the commit waiting for us back in
232+
*PostgresMain().
211233
*/
212-
vacuum_init(vacstmt);
234+
if (vacstmt->vacuum)
235+
{
236+
if (vacstmt->relation==NULL)
237+
{
238+
/*
239+
* Compute the initially applicable OldestXmin and FreezeLimit
240+
* XIDs, so that we can record these values at the end of the
241+
* VACUUM. Note that individual tables may well be processed with
242+
* newer values, but we can guarantee that no (non-shared)
243+
* relations are processed with older ones.
244+
*
245+
* It is okay to record non-shared values in pg_database, even though
246+
* we may vacuum shared relations with older cutoffs, because only
247+
* the minimum of the values present in pg_database matters. We
248+
* can be sure that shared relations have at some time been
249+
* vacuumed with cutoffs no worse than the global minimum; for, if
250+
* there is a backend in some other DB with xmin = OLDXMIN that's
251+
* determining the cutoff with which we vacuum shared relations,
252+
* it is not possible for that database to have a cutoff newer
253+
* than OLDXMIN recorded in pg_database.
254+
*/
255+
vacuum_set_xid_limits(vacstmt, false,
256+
&initialOldestXmin,&initialFreezeLimit);
257+
}
258+
259+
/* matches the StartTransaction in PostgresMain() */
260+
CommitTransactionCommand();
261+
}
213262

214263
/*
215264
* Process each selected relation.We are careful to process each
@@ -225,81 +274,44 @@ vacuum(VacuumStmt *vacstmt)
225274
if (vacstmt->vacuum)
226275
vacuum_rel(relid,vacstmt,RELKIND_RELATION);
227276
if (vacstmt->analyze)
277+
{
278+
/* If we vacuumed, use new transaction for analyze. */
279+
if (vacstmt->vacuum)
280+
StartTransactionCommand();
281+
else
282+
old_context=MemoryContextSwitchTo(anl_context);
283+
228284
analyze_rel(relid,vacstmt);
285+
286+
if (vacstmt->vacuum)
287+
CommitTransactionCommand();
288+
else
289+
{
290+
MemoryContextResetAndDeleteChildren(anl_context);
291+
MemoryContextSwitchTo(old_context);
292+
}
293+
}
229294
}
230295

231296
/* clean up */
232-
vacuum_shutdown(vacstmt);
233-
}
234-
235-
/*
236-
*vacuum_init(), vacuum_shutdown() -- start up and shut down the vacuum cleaner.
237-
*
238-
*Formerly, there was code here to prevent more than one VACUUM from
239-
*executing concurrently in the same database. However, there's no
240-
*good reason to prevent that, and manually removing lockfiles after
241-
*a vacuum crash was a pain for dbadmins. So, forget about lockfiles,
242-
*and just rely on the locks we grab on each target table
243-
*to ensure that there aren't two VACUUMs running on the same table
244-
*at the same time.
245-
*
246-
*The strangeness with committing and starting transactions in the
247-
*init and shutdown routines is due to the fact that the vacuum cleaner
248-
*is invoked via an SQL command, and so is already executing inside
249-
*a transaction.We need to leave ourselves in a predictable state
250-
*on entry and exit to the vacuum cleaner. We commit the transaction
251-
*started in PostgresMain() inside vacuum_init(), and start one in
252-
*vacuum_shutdown() to match the commit waiting for us back in
253-
*PostgresMain().
254-
*/
255-
staticvoid
256-
vacuum_init(VacuumStmt*vacstmt)
257-
{
258-
if (vacstmt->vacuum&&vacstmt->relation==NULL)
297+
if (vacstmt->vacuum)
259298
{
260-
/*
261-
* Compute the initially applicable OldestXmin and FreezeLimit
262-
* XIDs, so that we can record these values at the end of the
263-
* VACUUM. Note that individual tables may well be processed with
264-
* newer values, but we can guarantee that no (non-shared)
265-
* relations are processed with older ones.
266-
*
267-
* It is okay to record non-shared values in pg_database, even though
268-
* we may vacuum shared relations with older cutoffs, because only
269-
* the minimum of the values present in pg_database matters. We
270-
* can be sure that shared relations have at some time been
271-
* vacuumed with cutoffs no worse than the global minimum; for, if
272-
* there is a backend in some other DB with xmin = OLDXMIN that's
273-
* determining the cutoff with which we vacuum shared relations,
274-
* it is not possible for that database to have a cutoff newer
275-
* than OLDXMIN recorded in pg_database.
276-
*/
277-
vacuum_set_xid_limits(vacstmt, false,
278-
&initialOldestXmin,&initialFreezeLimit);
279-
}
280-
281-
/* matches the StartTransaction in PostgresMain() */
282-
CommitTransactionCommand();
283-
}
284-
285-
staticvoid
286-
vacuum_shutdown(VacuumStmt*vacstmt)
287-
{
288-
/* on entry, we are not in a transaction */
299+
/* on entry, we are not in a transaction */
289300

290-
/* matches the CommitTransaction in PostgresMain() */
291-
StartTransactionCommand();
301+
/* matches the CommitTransaction in PostgresMain() */
302+
StartTransactionCommand();
292303

293-
/*
294-
* If we did a database-wide VACUUM, update the database's pg_database
295-
* row with info about the transaction IDs used, and try to truncate
296-
* pg_clog.
297-
*/
298-
if (vacstmt->vacuum&&vacstmt->relation==NULL)
299-
{
300-
vac_update_dbstats(MyDatabaseId,
301-
initialOldestXmin,initialFreezeLimit);
302-
vac_truncate_clog(initialOldestXmin,initialFreezeLimit);
304+
/*
305+
* If we did a database-wide VACUUM, update the database's pg_database
306+
* row with info about the transaction IDs used, and try to truncate
307+
* pg_clog.
308+
*/
309+
if (vacstmt->relation==NULL)
310+
{
311+
vac_update_dbstats(MyDatabaseId,
312+
initialOldestXmin,initialFreezeLimit);
313+
vac_truncate_clog(initialOldestXmin,initialFreezeLimit);
314+
}
303315
}
304316

305317
/*
@@ -309,6 +321,10 @@ vacuum_shutdown(VacuumStmt *vacstmt)
309321
*/
310322
MemoryContextDelete(vac_context);
311323
vac_context=NULL;
324+
325+
if (vacstmt->analyze&& !vacstmt->vacuum)
326+
MemoryContextDelete(anl_context);
327+
312328
}
313329

314330
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp