Visibility map page pinned for too long ?

Lists: pgsql-hackers
From: Pavan Deolasee <pavan(dot)deolasee(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Visibility map page pinned for too long ?
Date: 2012-12-03 17:37:26
Message-ID: CABOikdOqcZW5ra-uE41HUFn2_tENC8_muY5gLBWVFg1+XJf9UA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

I was looking at the code when the following tiny bit caught my attention.
In vacuumlazy.c, we release the pin on the final VM page at line number 972.

954 if (vacrelstats->num_dead_tuples > 0)
955 {
956 /* Log cleanup info before we touch indexes */
957 vacuum_log_cleanup_info(onerel, vacrelstats);
958
959 /* Remove index entries */
960 for (i = 0; i < nindexes; i++)
961 lazy_vacuum_index(Irel[i],
962 &indstats[i],
963 vacrelstats);
964 /* Remove tuples from heap */
965 lazy_vacuum_heap(onerel, vacrelstats);
966 vacrelstats->num_index_scans++;
967 }
968
969 /* Release the pin on the visibility map page */
970 if (BufferIsValid(vmbuffer))
971 {
972 ReleaseBuffer(vmbuffer);
973 vmbuffer = InvalidBuffer;
974 }

So we are holding the pin right through the index vacuuming and the second
pass over the heap; both can take a very long time. We can and should
really be releasing the pin *before* those steps. In fact, it would be
appropriate to do it right after the preceding big for-loop.

While it may or may not matter from the performance or correctness
perspective, I think we should fix that.

Thanks,
Pavan

--
Pavan Deolasee
http://www.linkedin.com/in/pavandeolasee


From: Simon Riggs <simon(at)2ndQuadrant(dot)com>
To: Pavan Deolasee <pavan(dot)deolasee(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Visibility map page pinned for too long ?
Date: 2012-12-03 18:58:45
Message-ID: CA+U5nMLA02i3KX8oJ65_70a620DviGScMy8WebsGj1V4Qd_19w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 3 December 2012 17:37, Pavan Deolasee <pavan(dot)deolasee(at)gmail(dot)com> wrote:
> I was looking at the code when the following tiny bit caught my attention.
> In vacuumlazy.c, we release the pin on the final VM page at line number 972.
>
> 954 if (vacrelstats->num_dead_tuples > 0)
> 955 {
> 956 /* Log cleanup info before we touch indexes */
> 957 vacuum_log_cleanup_info(onerel, vacrelstats);
> 958
> 959 /* Remove index entries */
> 960 for (i = 0; i < nindexes; i++)
> 961 lazy_vacuum_index(Irel[i],
> 962 &indstats[i],
> 963 vacrelstats);
> 964 /* Remove tuples from heap */
> 965 lazy_vacuum_heap(onerel, vacrelstats);
> 966 vacrelstats->num_index_scans++;
> 967 }
> 968
> 969 /* Release the pin on the visibility map page */
> 970 if (BufferIsValid(vmbuffer))
> 971 {
> 972 ReleaseBuffer(vmbuffer);
> 973 vmbuffer = InvalidBuffer;
> 974 }
>
> So we are holding the pin right through the index vacuuming and the second
> pass over the heap; both can take a very long time. We can and should really
> be releasing the pin *before* those steps. In fact, it would be appropriate
> to do it right after the preceding big for-loop.
>
> While it may or may not matter from the performance or correctness
> perspective, I think we should fix that.

Yes, its a clear bug. Patched.

--
Simon Riggs http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services