mirror of
https://github.com/postgres/postgres.git
synced 2025-10-16 17:07:43 +03:00
Matview statistics depend on matview data.
REFRESH MATERIALIZED VIEW replaces the storage, which resets statistics, so statistics must be restored afterward. If both statistics and data are being dumped for a materialized view, add a dependency from the former to the latter. Defer the statistics to SECTION_POST_DATA, and use RESTORE_PASS_POST_ACL. Reported-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://postgr.es/m/CAExHW5s47kmubpbbRJzSM-Zfe0Tj2O3GBagB7YAyE8rQ-V24Uw@mail.gmail.com
This commit is contained in:
@@ -72,7 +72,7 @@ static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
|
||||
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
|
||||
static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te);
|
||||
static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH);
|
||||
static RestorePass _tocEntryRestorePass(TocEntry *te);
|
||||
static RestorePass _tocEntryRestorePass(ArchiveHandle *AH, TocEntry *te);
|
||||
static bool _tocEntryIsACL(TocEntry *te);
|
||||
static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te);
|
||||
static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te);
|
||||
@@ -102,7 +102,8 @@ static void pending_list_append(TocEntry *l, TocEntry *te);
|
||||
static void pending_list_remove(TocEntry *te);
|
||||
static int TocEntrySizeCompareQsort(const void *p1, const void *p2);
|
||||
static int TocEntrySizeCompareBinaryheap(void *p1, void *p2, void *arg);
|
||||
static void move_to_ready_heap(TocEntry *pending_list,
|
||||
static void move_to_ready_heap(ArchiveHandle *AH,
|
||||
TocEntry *pending_list,
|
||||
binaryheap *ready_heap,
|
||||
RestorePass pass);
|
||||
static TocEntry *pop_next_work_item(binaryheap *ready_heap,
|
||||
@@ -748,7 +749,7 @@ RestoreArchive(Archive *AHX)
|
||||
if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS)) == 0)
|
||||
continue; /* ignore if not to be dumped at all */
|
||||
|
||||
switch (_tocEntryRestorePass(te))
|
||||
switch (_tocEntryRestorePass(AH, te))
|
||||
{
|
||||
case RESTORE_PASS_MAIN:
|
||||
(void) restore_toc_entry(AH, te, false);
|
||||
@@ -767,7 +768,7 @@ RestoreArchive(Archive *AHX)
|
||||
for (te = AH->toc->next; te != AH->toc; te = te->next)
|
||||
{
|
||||
if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS)) != 0 &&
|
||||
_tocEntryRestorePass(te) == RESTORE_PASS_ACL)
|
||||
_tocEntryRestorePass(AH, te) == RESTORE_PASS_ACL)
|
||||
(void) restore_toc_entry(AH, te, false);
|
||||
}
|
||||
}
|
||||
@@ -777,7 +778,7 @@ RestoreArchive(Archive *AHX)
|
||||
for (te = AH->toc->next; te != AH->toc; te = te->next)
|
||||
{
|
||||
if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS)) != 0 &&
|
||||
_tocEntryRestorePass(te) == RESTORE_PASS_POST_ACL)
|
||||
_tocEntryRestorePass(AH, te) == RESTORE_PASS_POST_ACL)
|
||||
(void) restore_toc_entry(AH, te, false);
|
||||
}
|
||||
}
|
||||
@@ -3219,7 +3220,7 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
|
||||
* See notes with the RestorePass typedef in pg_backup_archiver.h.
|
||||
*/
|
||||
static RestorePass
|
||||
_tocEntryRestorePass(TocEntry *te)
|
||||
_tocEntryRestorePass(ArchiveHandle *AH, TocEntry *te)
|
||||
{
|
||||
/* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
|
||||
if (strcmp(te->desc, "ACL") == 0 ||
|
||||
@@ -3240,6 +3241,26 @@ _tocEntryRestorePass(TocEntry *te)
|
||||
strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
|
||||
return RESTORE_PASS_POST_ACL;
|
||||
|
||||
/*
|
||||
* If statistics data is dependent on materialized view data, it must be
|
||||
* deferred to RESTORE_PASS_POST_ACL.
|
||||
*/
|
||||
if (strcmp(te->desc, "STATISTICS DATA") == 0)
|
||||
{
|
||||
for (int i = 0; i < te->nDeps; i++)
|
||||
{
|
||||
DumpId depid = te->dependencies[i];
|
||||
|
||||
if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
|
||||
{
|
||||
TocEntry *otherte = AH->tocsByDumpId[depid];
|
||||
|
||||
if (strcmp(otherte->desc, "MATERIALIZED VIEW DATA") == 0)
|
||||
return RESTORE_PASS_POST_ACL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All else can be handled in the main pass. */
|
||||
return RESTORE_PASS_MAIN;
|
||||
}
|
||||
@@ -4249,7 +4270,7 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
|
||||
* not set skipped_some in this case, since by assumption no main-pass
|
||||
* items could depend on these.
|
||||
*/
|
||||
if (_tocEntryRestorePass(next_work_item) != RESTORE_PASS_MAIN)
|
||||
if (_tocEntryRestorePass(AH, next_work_item) != RESTORE_PASS_MAIN)
|
||||
do_now = false;
|
||||
|
||||
if (do_now)
|
||||
@@ -4331,7 +4352,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate,
|
||||
* process in the current restore pass.
|
||||
*/
|
||||
AH->restorePass = RESTORE_PASS_MAIN;
|
||||
move_to_ready_heap(pending_list, ready_heap, AH->restorePass);
|
||||
move_to_ready_heap(AH, pending_list, ready_heap, AH->restorePass);
|
||||
|
||||
/*
|
||||
* main parent loop
|
||||
@@ -4380,7 +4401,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate,
|
||||
/* Advance to next restore pass */
|
||||
AH->restorePass++;
|
||||
/* That probably allows some stuff to be made ready */
|
||||
move_to_ready_heap(pending_list, ready_heap, AH->restorePass);
|
||||
move_to_ready_heap(AH, pending_list, ready_heap, AH->restorePass);
|
||||
/* Loop around to see if anything's now ready */
|
||||
continue;
|
||||
}
|
||||
@@ -4551,7 +4572,8 @@ TocEntrySizeCompareBinaryheap(void *p1, void *p2, void *arg)
|
||||
* which applies the same logic one-at-a-time.)
|
||||
*/
|
||||
static void
|
||||
move_to_ready_heap(TocEntry *pending_list,
|
||||
move_to_ready_heap(ArchiveHandle *AH,
|
||||
TocEntry *pending_list,
|
||||
binaryheap *ready_heap,
|
||||
RestorePass pass)
|
||||
{
|
||||
@@ -4564,7 +4586,7 @@ move_to_ready_heap(TocEntry *pending_list,
|
||||
next_te = te->pending_next;
|
||||
|
||||
if (te->depCount == 0 &&
|
||||
_tocEntryRestorePass(te) == pass)
|
||||
_tocEntryRestorePass(AH, te) == pass)
|
||||
{
|
||||
/* Remove it from pending_list ... */
|
||||
pending_list_remove(te);
|
||||
@@ -4958,7 +4980,7 @@ reduce_dependencies(ArchiveHandle *AH, TocEntry *te,
|
||||
* memberships changed.
|
||||
*/
|
||||
if (otherte->depCount == 0 &&
|
||||
_tocEntryRestorePass(otherte) == AH->restorePass &&
|
||||
_tocEntryRestorePass(AH, otherte) == AH->restorePass &&
|
||||
otherte->pending_prev != NULL &&
|
||||
ready_heap != NULL)
|
||||
{
|
||||
|
Reference in New Issue
Block a user