cbbrowne at ca.afilias.info cbbrowne
Mon Mar 7 05:04:03 PST 2005
Here's a kinda cruddy attempt at getting the earliest XID from pg_locks.

The general idea is to keep the returned value around, and each time the
cleanup thread runs, compare the latest "earliest XID" with what it was
last time.  If it hasn't changed, then there is an old transaction
lingering that will make VACUUM futile, so the cleanup runs ANALYZE
instead.

I don't trust this to work for XIDs > 2^31, unfortunately; suggestions
welcome...

static unsigned long get_earliest_xid (PGconn *dbconn) {
  unsigned long lo = 2147483647;
  unsigned long minhi = -1;
  unsigned long minlo = lo;
  unsigned long xid;
  long n,t;
  PGresult   *res;
  SlonDString query1;
  dstring_init(&query1);
  slon_mkquery(&query1, "select transaction from pg_catalog.pg_locks where
transaction is not null;");
  res = PQexec(dbconn, dstring_data(&query1));
  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
    slon_log(SLON_FATAL, "cleanupThread: could not read locks from
pg_locks!");
    PQclear(res);
    slon_abort();
    return -1;
  } else {
    n = PQntuples(res);
    for (t = 0; t < n; t++) {
      xid = atoi(PQgetvalue(res, t, 0));
      printf ("xid: %d\n", xid);
      if (xid > lo) {
        if (xid < minlo)
          minlo = xid;
      } else {
        if (xid < minhi)
          minhi = xid;
      }
    }
  }
  printf("minhi: %d minlo: %d\n", minlo, minhi);
  if ((minhi - lo) < minlo)
    return minlo;
  else
    return minhi;
}





More information about the Slony1-general mailing list