mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Report progress of CREATE INDEX operations
This uses the progress reporting infrastructure added by c16dc1aca5
,
adding support for CREATE INDEX and CREATE INDEX CONCURRENTLY.
There are two pieces to this: one is index-AM-agnostic, and the other is
AM-specific. The latter is fairly elaborate for btrees, including
reportage for parallel index builds and the separate phases that btree
index creation uses; other index AMs, which are much simpler in their
building procedures, have simplistic reporting only, but that seems
sufficient, at least for non-concurrent builds.
The index-AM-agnostic part is fairly complete, providing insight into
the CONCURRENTLY wait phases as well as block-based progress during the
index validation table scan. (The index validation index scan requires
patching each AM, which has not been included here.)
Reviewers: Rahila Syed, Pavan Deolasee, Tatsuro Yamada
Discussion: https://postgr.es/m/20181220220022.mg63bhk26zdpvmcj@alvherre.pgsql
This commit is contained in:
@@ -19,9 +19,12 @@
|
||||
#include "access/transam.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "commands/progress.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/sinvaladt.h"
|
||||
#include "utils/inval.h"
|
||||
|
||||
|
||||
@@ -857,10 +860,12 @@ XactLockTableWaitErrorCb(void *arg)
|
||||
* after we obtained our initial list of lockers, we will not wait for them.
|
||||
*/
|
||||
void
|
||||
WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
|
||||
WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
|
||||
{
|
||||
List *holders = NIL;
|
||||
ListCell *lc;
|
||||
int total = 0;
|
||||
int done = 0;
|
||||
|
||||
/* Done if no locks to wait for */
|
||||
if (list_length(locktags) == 0)
|
||||
@@ -870,10 +875,17 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
|
||||
foreach(lc, locktags)
|
||||
{
|
||||
LOCKTAG *locktag = lfirst(lc);
|
||||
int count;
|
||||
|
||||
holders = lappend(holders, GetLockConflicts(locktag, lockmode));
|
||||
holders = lappend(holders,
|
||||
GetLockConflicts(locktag, lockmode,
|
||||
progress ? &count : NULL));
|
||||
total += count;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
pgstat_progress_update_param(PROGRESS_WAITFOR_TOTAL, total);
|
||||
|
||||
/*
|
||||
* Note: GetLockConflicts() never reports our own xid, hence we need not
|
||||
* check for that. Also, prepared xacts are not reported, which is fine
|
||||
@@ -887,10 +899,36 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
|
||||
|
||||
while (VirtualTransactionIdIsValid(*lockholders))
|
||||
{
|
||||
/*
|
||||
* If requested, publish who we're going to wait for. This is not
|
||||
* 100% accurate if they're already gone, but we don't care.
|
||||
*/
|
||||
if (progress)
|
||||
{
|
||||
PGPROC *holder = BackendIdGetProc(lockholders->backendId);
|
||||
|
||||
pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID,
|
||||
holder->pid);
|
||||
}
|
||||
VirtualXactLock(*lockholders, true);
|
||||
lockholders++;
|
||||
|
||||
if (progress)
|
||||
pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, ++done);
|
||||
}
|
||||
}
|
||||
if (progress)
|
||||
{
|
||||
const int index[] = {
|
||||
PROGRESS_WAITFOR_TOTAL,
|
||||
PROGRESS_WAITFOR_DONE,
|
||||
PROGRESS_WAITFOR_CURRENT_PID
|
||||
};
|
||||
const int64 values[] = {
|
||||
0, 0, 0
|
||||
};
|
||||
pgstat_progress_update_multi_param(3, index, values);
|
||||
}
|
||||
|
||||
list_free_deep(holders);
|
||||
}
|
||||
@@ -901,12 +939,12 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode)
|
||||
* Same as WaitForLockersMultiple, for a single lock tag.
|
||||
*/
|
||||
void
|
||||
WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode)
|
||||
WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress)
|
||||
{
|
||||
List *l;
|
||||
|
||||
l = list_make1(&heaplocktag);
|
||||
WaitForLockersMultiple(l, lockmode);
|
||||
WaitForLockersMultiple(l, lockmode, progress);
|
||||
list_free(l);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user