1. Run all pg_dump queries in single serializable transaction.
authorVadim B. Mikheev
Sat, 29 May 1999 10:25:33 +0000 (10:25 +0000)
committerVadim B. Mikheev
Sat, 29 May 1999 10:25:33 +0000 (10:25 +0000)
2. Get rid of locking when updating statistics in vacuum.
3. Use QuerySnapshot in COPY TO and call SetQuerySnashot
   in main tcop loop before FETCH and COPY TO.

src/backend/commands/copy.c
src/backend/commands/vacuum.c
src/backend/tcop/postgres.c
src/bin/pg_dump/pg_dump.c

index f6ac3709387fd91a5a510d448dc9f5bde95484db..c450b20b26a6aa1b292b00ed9ab57675cf4ca43c 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.78 1999/05/26 12:55:10 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.79 1999/05/29 10:25:29 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -381,7 +381,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
    int32       ntuples;
    TupleDesc   tupDesc;
 
-   scandesc = heap_beginscan(rel, 0, SnapshotNow, 0, NULL);
+   scandesc = heap_beginscan(rel, 0, QuerySnapshot, 0, NULL);
 
    attr_count = rel->rd_att->natts;
    attr = rel->rd_att->attrs;
@@ -1363,7 +1363,7 @@ CountTuples(Relation relation)
 
    int         i;
 
-   scandesc = heap_beginscan(relation, 0, SnapshotNow, 0, NULL);
+   scandesc = heap_beginscan(relation, 0, QuerySnapshot, 0, NULL);
 
    i = 0;
    while (HeapTupleIsValid(tuple = heap_getnext(scandesc, 0)))
index 8c929678b35b3dd85c4110bb2ab113392955c62c..7fe014eaf21fb40d358ae83b4ae7ec0c31a89e99 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.104 1999/05/25 16:08:27 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.105 1999/05/29 10:25:30 vadim Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -93,7 +93,6 @@ static void vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple tupl
 static void vc_bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int16 *bucket_len);
 static void vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats);
 static void vc_delhilowstats(Oid relid, int attcnt, int *attnums);
-static void vc_setpagelock(Relation rel, BlockNumber blkno);
 static VPageDescr vc_tidreapped(ItemPointer itemptr, VPageList vpl);
 static void vc_reappage(VPageList vpl, VPageDescr vpc);
 static void vc_vpinsert(VPageList vpl, VPageDescr vpnew);
@@ -2221,7 +2220,8 @@ vc_bucketcpy(Form_pg_attribute attr, Datum value, Datum *bucket, int16 *bucket_l
  *     tuple that's already on the page.  The reason for this is that if
  *     we updated these tuples in the usual way, then every tuple in pg_class
  *     would be replaced every day.  This would make planning and executing
- *     historical queries very expensive.
+ *     historical queries very expensive. Note that we also don't use
+ *     any locking while doing updation.
  */
 static void
 vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *vacrelstats)
@@ -2257,7 +2257,6 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
    pfree(ctup);
 
    /* overwrite the existing statistics in the tuple */
-   vc_setpagelock(rd, ItemPointerGetBlockNumber(&(rtup.t_self)));
    pgcform = (Form_pg_class) GETSTRUCT(&rtup);
    pgcform->reltuples = num_tuples;
    pgcform->relpages = num_pages;
@@ -2301,11 +2300,6 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
            /* overwrite the existing statistics in the tuple */
            if (VacAttrStatsEqValid(stats))
            {
-               Buffer      abuffer = scan->rs_cbuf;
-
-               vc_setpagelock(ad, ItemPointerGetBlockNumber(&atup->t_self));
-               attp = (Form_pg_attribute) GETSTRUCT(atup);
-
                if (stats->nonnull_cnt + stats->null_cnt == 0 ||
                    (stats->null_cnt <= 1 && stats->best_cnt == 1))
                    selratio = 0;
@@ -2338,7 +2332,7 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
                 * Invalidate the cache for the tuple and write the buffer
                 */
                RelationInvalidateHeapTuple(ad, atup);
-               WriteNoReleaseBuffer(abuffer);
+               WriteNoReleaseBuffer(scan->rs_cbuf);
 
                /* DO PG_STATISTIC INSERTS */
 
@@ -2396,9 +2390,7 @@ vc_updstats(Oid relid, int num_pages, int num_tuples, bool hasindex, VRelStats *
     */
    RelationInvalidateHeapTuple(rd, &rtup);
 
-   WriteNoReleaseBuffer(buffer);
-
-   ReleaseBuffer(buffer);
+   WriteBuffer(buffer);
 
    heap_close(rd);
 }
@@ -2449,12 +2441,6 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
    heap_close(pgstatistic);
 }
 
-static void
-vc_setpagelock(Relation rel, BlockNumber blkno)
-{
-   LockPage(rel, blkno, ExclusiveLock);
-}
-
 /*
  * vc_reappage() -- save a page on the array of reapped pages.
  *
index cbed22b8c42c1f91291505f5eae8020d9e3fa313..b89cc20af8b2138dff0f443f224b927c2870e39b 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.117 1999/05/26 12:55:55 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.118 1999/05/29 10:25:30 vadim Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -73,6 +73,8 @@
 #include "utils/rel.h"
 #include "utils/ps_status.h"
 #include "utils/temprel.h"
+#include "nodes/parsenodes.h"
+#include "../backend/parser/parse.h"
 
 #ifdef NOT_USED
 #include "nodes/relation.h"
@@ -715,6 +717,13 @@ pg_exec_query_dest(char *query_string, /* string to execute */
            else if (Verbose)
                TPRINTF(TRACE_VERBOSE, "ProcessUtility");
 
+           /*
+            * We have to set query SnapShot in the case of FETCH or COPY TO.
+            */
+           if (nodeTag(querytree->utilityStmt) == T_FetchStmt ||
+               (nodeTag(querytree->utilityStmt) == T_CopyStmt && 
+               ((CopyStmt *)(querytree->utilityStmt))->direction != FROM))
+               SetQuerySnapshot();
            ProcessUtility(querytree->utilityStmt, dest);
        }
        else
@@ -1527,7 +1536,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
    if (!IsUnderPostmaster)
    {
        puts("\nPOSTGRES backend interactive interface ");
-       puts("$Revision: 1.117 $ $Date: 1999/05/26 12:55:55 $\n");
+       puts("$Revision: 1.118 $ $Date: 1999/05/29 10:25:30 $\n");
    }
 
    /* ----------------
index 12cf2d63afa50e108dfad90bec1a7364f2804e6f..0e1aaa1fc037eccb1720c066b654a5a3282441cd 100644 (file)
@@ -21,7 +21,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.113 1999/05/27 16:29:03 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.114 1999/05/29 10:25:31 vadim Exp $
  *
  * Modifications - 6/10/96 - [email protected] - version 1.13.dhb
  *
@@ -190,15 +190,6 @@ isViewRule(char *relname)
    int         ntups;
    char        query[MAX_QUERY_SIZE];
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    sprintf(query, "select relname from pg_class, pg_rewrite "
            "where pg_class.oid = ev_class "
            "and pg_rewrite.ev_type = '1' "
@@ -214,8 +205,6 @@ isViewRule(char *relname)
 
    ntups = PQntuples(res);
 
-   PQclear(res);
-   res = PQexec(g_conn, "end");
    PQclear(res);
    return ntups > 0 ? TRUE : FALSE;
 }
@@ -722,6 +711,28 @@ main(int argc, char **argv)
        exit_nicely(g_conn);
    }
 
+   /*
+    * Start serializable transaction to dump consistent data
+    */
+   {
+       PGresult   *res;
+
+       res = PQexec(g_conn, "begin");
+       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+           fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+           exit_nicely(g_conn);
+       }
+       PQclear(res);
+       res = PQexec(g_conn, "set transaction isolation level serializable");
+       if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+           fprintf(stderr, "SET TRANSACTION command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
+           exit_nicely(g_conn);
+       }
+       PQclear(res);
+   }
+
    g_last_builtin_oid = findLastBuiltinOid();
 
    if (oids == true)
@@ -789,15 +800,6 @@ getTypes(int *numTypes)
    int         i_typbyval;
    int         i_usename;
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    /* find all base types */
 
    /*
@@ -878,9 +880,6 @@ getTypes(int *numTypes)
 
    PQclear(res);
 
-   res = PQexec(g_conn, "end");
-   PQclear(res);
-
    return tinfo;
 }
 
@@ -922,14 +921,6 @@ getOperators(int *numOprs)
     * find all operators, including builtin operators, filter out
     * system-defined operators at dump-out time
     */
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
 
    sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, "
            "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, "
@@ -983,8 +974,6 @@ getOperators(int *numOprs)
        oprinfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
    }
 
-   PQclear(res);
-   res = PQexec(g_conn, "end");
    PQclear(res);
 
    return oprinfo;
@@ -1259,15 +1248,6 @@ getAggregates(int *numAggs)
 
    /* find all user-defined aggregates */
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    sprintf(query,
            "SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, "
            "aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, "
@@ -1316,8 +1296,6 @@ getAggregates(int *numAggs)
 
    PQclear(res);
 
-   res = PQexec(g_conn, "end");
-   PQclear(res);
    return agginfo;
 }
 
@@ -1352,15 +1330,6 @@ getFuncs(int *numFuncs)
 
    /* find all user-defined funcs */
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    sprintf(query,
            "SELECT pg_proc.oid, proname, prolang, pronargs, prorettype, "
            "proretset, proargtypes, prosrc, probin, usename "
@@ -1413,8 +1382,6 @@ getFuncs(int *numFuncs)
        finfo[i].dumped = 0;
    }
 
-   PQclear(res);
-   res = PQexec(g_conn, "end");
    PQclear(res);
 
    return finfo;
@@ -1455,15 +1422,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
     * we ignore tables that start with xinv
     */
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    sprintf(query,
            "SELECT pg_class.oid, relname, relkind, relacl, usename, "
            "relchecks, reltriggers "
@@ -1759,8 +1717,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
            tblinfo[i].triggers = NULL;
    }
 
-   PQclear(res);
-   res = PQexec(g_conn, "end");
    PQclear(res);
 
    return tblinfo;
@@ -1789,14 +1745,6 @@ getInherits(int *numInherits)
    int         i_inhparent;
 
    /* find all the inheritance information */
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
 
    sprintf(query, "SELECT inhrel, inhparent from pg_inherits");
 
@@ -1823,8 +1771,6 @@ getInherits(int *numInherits)
        inhinfo[i].inhparent = strdup(PQgetvalue(res, i, i_inhparent));
    }
 
-   PQclear(res);
-   res = PQexec(g_conn, "end");
    PQclear(res);
    return inhinfo;
 }
@@ -1977,15 +1923,6 @@ getIndices(int *numIndices)
     * this is a 4-way join !!
     */
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-   PQclear(res);
-
    sprintf(query,
          "SELECT t1.relname as indexrelname, t2.relname as indrelname, "
            "i.indproc, i.indkey, i.indclass, "
@@ -2031,8 +1968,6 @@ getIndices(int *numIndices)
        indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));
    }
    PQclear(res);
-   res = PQexec(g_conn, "end");
-   PQclear(res);
    return indinfo;
 }
 
@@ -2138,14 +2073,6 @@ dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,
    int         i,
                fidx;
 
-   res = PQexec(g_conn, "begin");
-   if (!res ||
-       PQresultStatus(res) != PGRES_COMMAND_OK)
-   {
-       fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-       exit_nicely(g_conn);
-   }
-
    sprintf(query, "SELECT * FROM pg_language "
            "WHERE lanispl "
            "ORDER BY oid");
@@ -2198,8 +2125,6 @@ dumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,
 
    PQclear(res);
 
-   res = PQexec(g_conn, "end");
-   PQclear(res);
 }
 
 /*
@@ -2262,15 +2187,6 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
        int         i_lanname;
        char        query[256];
 
-       res = PQexec(g_conn, "begin");
-       if (!res ||
-           PQresultStatus(res) != PGRES_COMMAND_OK)
-       {
-           fprintf(stderr, "dumpOneFunc(): BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-           exit_nicely(g_conn);
-       }
-       PQclear(res);
-
        sprintf(query, "SELECT lanname FROM pg_language "
                "WHERE oid = %u",
                finfo[i].lang);
@@ -2296,8 +2212,6 @@ dumpOneFunc(FILE *fout, FuncInfo *finfo, int i,
 
        PQclear(res);
 
-       res = PQexec(g_conn, "end");
-       PQclear(res);
    }
 
    if (dropSchema)
@@ -3330,14 +3244,6 @@ dumpRules(FILE *fout, const char *tablename,
    {
        if (tablename && strcmp(tblinfo[t].relname, tablename))
            continue;
-       res = PQexec(g_conn, "begin");
-       if (!res ||
-           PQresultStatus(res) != PGRES_COMMAND_OK)
-       {
-           fprintf(stderr, "BEGIN command failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));
-           exit_nicely(g_conn);
-       }
-       PQclear(res);
 
        /*
         * Get all rules defined for this table
@@ -3367,9 +3273,6 @@ dumpRules(FILE *fout, const char *tablename,
            fprintf(fout, "%s\n", PQgetvalue(res, i, i_definition));
 
        PQclear(res);
-
-       res = PQexec(g_conn, "end");
-       PQclear(res);
    }
 }