Re: LogwrtResult contended spinlock

Alvaro Herrera <alvherre@2ndquadrant.com>

From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Andres Freund <andres@anarazel.de>
Cc: pgsql-hackers@lists.postgresql.org, Jaime Casanova <jaime.casanova@2ndQuadrant.com>
Date: 2020-09-03T18:34:52Z
Lists: pgsql-hackers
Looking at patterns like this

	if (XLogCtl->LogwrtRqst.Write < EndPos)
		XLogCtl->LogwrtRqst.Write = EndPos;

It seems possible to implement with

    do {
    	XLogRecPtr	currwrite;

        currwrite = pg_atomic_read_u64(LogwrtRqst.Write);
	if (currwrite > EndPos)
            break;  // already done by somebody else
        if (pg_atomic_compare_exchange_u64(LogwrtRqst.Write,
	                                   currwrite, EndPos))
            break;  // successfully updated
    } while (true);

This assumes that LogwrtRqst.Write never goes backwards, so it doesn't
seem good material for a general routine.

This *seems* correct to me, though this is muddy territory to me.  Also,
are there better ways to go about this?

-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



Commits

  1. Remove bogus assertion in pg_atomic_monotonic_advance_u64

  2. Add XLogCtl->logInsertResult

  3. Operate XLogCtl->log{Write,Flush}Result with atomics

  4. Split XLogCtl->LogwrtResult into separate struct members

  5. Introduce atomic read/write functions with full barrier semantics.

  6. Reduce the number of GetFlushRecPtr() calls done by walsenders.

  7. Remove most volatile qualifiers from xlog.c