> 
> I'm imagining something like this:
> 
>    struct timespec delay;
>    TimestampTz end_time;
> 
>    end_time = TimestampTzPlusMilliseconds(GetCurrentTimestamp(), msec);
> 
>    do
>    {
>        long        secs;
>        int         microsecs;
> 
>        TimestampDifference(GetCurrentTimestamp(), end_time,
>                            &secs, &microsecs);
> 
>        delay.tv_sec = secs;
>        delay.tv_nsec = microsecs * 1000;
> 
>    } while (nanosleep(&delay, NULL) == -1 && errno == EINTR);
> 

I do agree that this is cleaner code, but I am not sure I like this.


1/ TimestampDifference has a dependency on gettimeofday, 
while my proposal utilizes clock_gettime. There are old discussions
that did not reach a conclusion comparing both mechanisms. 
My main conclusion from these hacker discussions [1], [2] and other 
online discussions on the topic is clock_gettime should replace
getimeofday when possible. Precision is the main reason.

2/ It no longer uses the remain time. I think the remain time
is still required here. I did a unrealistic stress test which shows 
the original proposal can handle frequent interruptions much better.

#1 in one session kicked off a vacuum

    set vacuum_cost_delay = 10;
    set vacuum_cost_limit = 1;
    set client_min_messages = log;
    update large_tbl set version = 1;
    vacuum (verbose, parallel 4) large_tbl;

#2 in another session, ran a loop to continually
interrupt the vacuum leader. This was during the
“heap scan” phase of the vacuum.

PID=< pid of vacuum leader >
while :
do
    kill -USR1 $PID
done


Using the proposed loop with the remainder, I noticed that
the actual time reported remains close to the requested
delay time.

LOG:  10.000000,10.013420
LOG:  10.000000,10.011188
LOG:  10.000000,10.010860
LOG:  10.000000,10.014839
LOG:  10.000000,10.004542
LOG:  10.000000,10.006035
LOG:  10.000000,10.012230
LOG:  10.000000,10.014535
LOG:  10.000000,10.009645
LOG:  10.000000,10.000817
LOG:  10.000000,10.002162
LOG:  10.000000,10.011721
LOG:  10.000000,10.011655

Using the approach mentioned by Nathan, there
are large differences between requested and actual time.

LOG:  10.000000,17.801778
LOG:  10.000000,12.795450
LOG:  10.000000,11.793723
LOG:  10.000000,11.796317
LOG:  10.000000,13.785993
LOG:  10.000000,11.803775
LOG:  10.000000,15.782767
LOG:  10.000000,31.783901
LOG:  10.000000,19.792440
LOG:  10.000000,21.795795
LOG:  10.000000,18.800412
LOG:  10.000000,16.782886
LOG:  10.000000,10.795197
LOG:  10.000000,14.793333
LOG:  10.000000,29.806556
LOG:  10.000000,18.810784
LOG:  10.000000,11.804956
LOG:  10.000000,24.809812
LOG:  10.000000,25.815600
LOG:  10.000000,22.809493
LOG:  10.000000,22.790908
LOG:  10.000000,19.699097
LOG:  10.000000,23.795613
LOG:  10.000000,24.797078

Let me know what you think?

[1] https://www.postgresql.org/message-id/flat/31856.1400021891%40sss.pgh.pa.us
[2] 
https://www.postgresql.org/message-id/flat/E1cO7fR-0003y0-9E%40gemulon.postgresql.org



Regards,

Sami 

Reply via email to