diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index f345df7cc1..ac5c15491c 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.98 2000/11/30 18:38:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.99 2000/12/03 10:27:25 vadim Exp $ * * * INTERFACE ROUTINES @@ -1358,6 +1358,7 @@ heap_insert(Relation relation, HeapTuple tup) buffer = RelationGetBufferForTuple(relation, tup->t_len); /* NO ELOG(ERROR) from here till changes are logged */ + START_CRIT_CODE; RelationPutHeapTuple(relation, buffer, tup); /* XLOG stuff */ @@ -1381,6 +1382,7 @@ heap_insert(Relation relation, HeapTuple tup) PageSetLSN(BufferGetPage(buffer), recptr); PageSetSUI(BufferGetPage(buffer), ThisStartUpID); } + END_CRIT_CODE; LockBuffer(buffer, BUFFER_LOCK_UNLOCK); WriteBuffer(buffer); @@ -1474,6 +1476,7 @@ l1: } /* XLOG stuff */ + START_CRIT_CODE; { xl_heap_delete xlrec; XLogRecPtr recptr; @@ -1493,6 +1496,7 @@ l1: tp.t_data->t_cmax = GetCurrentCommandId(); tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); + END_CRIT_CODE; #ifdef TUPLE_TOASTER_ACTIVE /* ---------- @@ -1648,10 +1652,9 @@ l2: } /* NO ELOG(ERROR) from here till changes are logged */ + START_CRIT_CODE; - /* insert new tuple */ - RelationPutHeapTuple(relation, newbuf, newtup); - + RelationPutHeapTuple(relation, newbuf, newtup); /* insert new tuple */ if (buffer == newbuf) { TransactionIdStore(GetCurrentTransactionId(), &(oldtup.t_data->t_xmax)); @@ -1681,6 +1684,7 @@ l2: PageSetLSN(BufferGetPage(buffer), recptr); PageSetSUI(BufferGetPage(buffer), ThisStartUpID); } + END_CRIT_CODE; if (newbuf != buffer) { diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index f00b1e7918..0aa4947524 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.69 2000/11/30 08:46:21 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.70 2000/12/03 10:27:26 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -772,6 +772,7 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright, * NO ELOG(ERROR) till right sibling is updated. * */ + START_CRIT_CODE; { char xlbuf[sizeof(xl_btree_split) + sizeof(CommandId) + sizeof(RelFileNode) + BLCKSZ]; @@ -870,6 +871,7 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright, /* write and release the old right sibling */ _bt_wrtbuf(rel, sbuf); } + END_CRIT_CODE; /* split's done */ return rbuf; @@ -1162,6 +1164,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) metabuf = _bt_getbuf(rel, BTREE_METAPAGE,BT_WRITE); /* NO ELOG(ERROR) from here till newroot op is logged */ + START_CRIT_CODE; /* set btree special data */ rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); @@ -1248,6 +1251,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) _bt_wrtbuf(rel, metabuf); } + END_CRIT_CODE; /* write and let go of the new root buffer */ _bt_wrtbuf(rel, rootbuf); diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index fe9036d111..613b141b67 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.42 2000/11/30 08:46:21 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.43 2000/12/03 10:27:26 vadim Exp $ * * NOTES * Postgres btree pages look like ordinary relation pages. The opaque @@ -165,6 +165,7 @@ _bt_getroot(Relation rel, int access) rootpage = BufferGetPage(rootbuf); /* NO ELOG(ERROR) till meta is updated */ + START_CRIT_CODE; _bt_pageinit(rootpage, BufferGetPageSize(rootbuf)); rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); @@ -186,6 +187,7 @@ _bt_getroot(Relation rel, int access) PageSetLSN(metapg, recptr); PageSetSUI(metapg, ThisStartUpID); } + END_CRIT_CODE; metad->btm_root = rootblkno; metad->btm_level = 1; @@ -402,6 +404,7 @@ _bt_pagedel(Relation rel, ItemPointer tid) page = BufferGetPage(buf); /* XLOG stuff */ + START_CRIT_CODE; { xl_btree_delete xlrec; XLogRecPtr recptr; @@ -416,6 +419,7 @@ _bt_pagedel(Relation rel, ItemPointer tid) } PageIndexTupleDelete(page, offno); + END_CRIT_CODE; /* write the buffer and release the lock */ _bt_wrtbuf(rel, buf); diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index b9ba82b63b..129c0e263a 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.86 2000/11/30 08:46:22 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.87 2000/12/03 10:27:26 vadim Exp $ * * NOTES * Transaction aborts can now occur two ways: @@ -672,6 +672,7 @@ RecordTransactionCommit() BufmgrCommit(); xlrec.xtime = time(NULL); + START_CRIT_CODE; /* * SHOULD SAVE ARRAY OF RELFILENODE-s TO DROP */ @@ -691,6 +692,7 @@ RecordTransactionCommit() TransactionIdCommit(xid); MyProc->logRec.xrecoff = 0; + END_CRIT_CODE; } if (leak) @@ -787,11 +789,13 @@ RecordTransactionAbort(void) XLogRecPtr recptr; xlrec.xtime = time(NULL); + START_CRIT_CODE; recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT, (char*) &xlrec, SizeOfXactAbort, NULL, 0); TransactionIdAbort(xid); MyProc->logRec.xrecoff = 0; + END_CRIT_CODE; } /* diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 70be51695d..e1a8ef97d1 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.38 2000/11/30 08:46:22 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.39 2000/12/03 10:27:26 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -40,7 +40,7 @@ int XLOGbuffers = 8; XLogRecPtr MyLastRecPtr = {0, 0}; -bool StopIfError = false; +uint32 StopIfError = 0; bool InRecovery = false; StartUpID ThisStartUpID = 0; @@ -270,6 +270,8 @@ XLogInsert(RmgrId rmid, uint8 info, char *hdr, uint32 hdrlen, char *buf, uint32 return (RecPtr); } + START_CRIT_CODE; + /* obtain xlog insert lock */ if (TAS(&(XLogCtl->insert_lck))) /* busy */ { @@ -496,6 +498,7 @@ nbuf: } } + END_CRIT_CODE; return (RecPtr); } @@ -523,6 +526,9 @@ XLogFlush(XLogRecPtr record) return; if (XLByteLE(record, LgwrResult.Flush)) return; + + START_CRIT_CODE; + WriteRqst = LgwrRqst.Write; for (;;) { @@ -533,6 +539,7 @@ XLogFlush(XLogRecPtr record) if (XLByteLE(record, LgwrResult.Flush)) { S_UNLOCK(&(XLogCtl->info_lck)); + END_CRIT_CODE; return; } if (XLByteLT(XLogCtl->LgwrRqst.Flush, record)) @@ -578,6 +585,7 @@ XLogFlush(XLogRecPtr record) if (XLByteLE(record, LgwrResult.Flush)) { S_UNLOCK(&(XLogCtl->lgwr_lck)); + END_CRIT_CODE; return; } if (XLByteLT(LgwrResult.Write, WriteRqst)) @@ -587,6 +595,7 @@ XLogFlush(XLogRecPtr record) S_UNLOCK(&(XLogCtl->lgwr_lck)); if (XLByteLT(LgwrResult.Flush, record)) elog(STOP, "XLogFlush: request is not satisfied"); + END_CRIT_CODE; return; } break; @@ -632,6 +641,8 @@ XLogFlush(XLogRecPtr record) XLogCtl->Write.LgwrResult = LgwrResult; S_UNLOCK(&(XLogCtl->lgwr_lck)); + + END_CRIT_CODE; return; } @@ -1519,9 +1530,9 @@ StartupXLOG() LastRec; XLogRecord *record; char buffer[MAXLOGRECSZ + SizeOfXLogRecord]; - bool sie_saved = false; elog(LOG, "starting up"); + StopIfError++; XLogCtl->xlblocks = (XLogRecPtr *) (((char *) XLogCtl) + sizeof(XLogCtlData)); XLogCtl->pages = ((char *) XLogCtl->xlblocks + sizeof(XLogRecPtr) * XLOGbuffers); @@ -1628,9 +1639,6 @@ StartupXLOG() ControlFile->time = time(NULL); UpdateControlFile(); - sie_saved = StopIfError; - StopIfError = true; - XLogOpenLogRelation(); /* open pg_log */ XLogInitRelationCache(); @@ -1729,7 +1737,6 @@ StartupXLOG() if (InRecovery) { CreateCheckPoint(true); - StopIfError = sie_saved; XLogCloseRelationCache(); } InRecovery = false; @@ -1742,6 +1749,7 @@ StartupXLOG() XLogCtl->ThisStartUpID = ThisStartUpID; elog(LOG, "database system is in production state"); + StopIfError--; return; } @@ -1764,8 +1772,10 @@ ShutdownXLOG() { elog(LOG, "shutting down"); + StopIfError++; CreateDummyCaches(); CreateCheckPoint(true); + StopIfError--; elog(LOG, "database system is shut down"); } @@ -1787,6 +1797,7 @@ CreateCheckPoint(bool shutdown) if (MyLastRecPtr.xrecoff != 0) elog(ERROR, "CreateCheckPoint: cannot be called inside transaction block"); + START_CRIT_CODE; while (TAS(&(XLogCtl->chkp_lck))) { struct timeval delay = {2, 0}; @@ -1917,6 +1928,7 @@ CreateCheckPoint(bool shutdown) S_UNLOCK(&(XLogCtl->chkp_lck)); MyLastRecPtr.xrecoff = 0; /* to avoid commit record */ + END_CRIT_CODE; return; } diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 210657cdf0..e8944f8d98 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -295,6 +295,7 @@ nextval(PG_FUNCTION_ARGS) elm->last = result; /* last returned number */ elm->cached = last; /* last fetched number */ + START_CRIT_CODE; if (logit) { xl_seq_rec xlrec; @@ -318,6 +319,7 @@ nextval(PG_FUNCTION_ARGS) Assert(log >= 0); seq->log_cnt = log; /* how much is logged */ seq->is_called = 't'; + END_CRIT_CODE; LockBuffer(buf, BUFFER_LOCK_UNLOCK); @@ -386,6 +388,7 @@ do_setval(char *seqname, int32 next, bool iscalled) elm->cached = next; /* last cached number */ /* save info in sequence relation */ + START_CRIT_CODE; seq->last_value = next; /* last fetched number */ seq->is_called = iscalled ? 't' : 'f'; seq->log_cnt = (iscalled) ? 0 : 1; @@ -403,6 +406,7 @@ do_setval(char *seqname, int32 next, bool iscalled) PageSetLSN(BufferGetPage(buf), recptr); PageSetSUI(BufferGetPage(buf), ThisStartUpID); } + END_CRIT_CODE; LockBuffer(buf, BUFFER_LOCK_UNLOCK); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index d42417b050..254509a330 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.175 2000/12/02 19:38:34 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.176 2000/12/03 10:27:27 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -1418,6 +1418,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, Cpage = BufferGetPage(Cbuf); /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */ + START_CRIT_CODE; Citemid = PageGetItemId(Cpage, ItemPointerGetOffsetNumber(&(tuple.t_self))); @@ -1501,6 +1502,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, PageSetLSN(ToPage, recptr); PageSetSUI(ToPage, ThisStartUpID); } + END_CRIT_CODE; if (((int) destvacpage->blkno) > last_move_dest_block) last_move_dest_block = destvacpage->blkno; @@ -1624,12 +1626,15 @@ repair_frag(VRelStats *vacrelstats, Relation onerel, ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_OFF); newtup.t_data->t_infomask |= HEAP_MOVED_IN; + /* NO ELOG(ERROR) TILL CHANGES ARE LOGGED */ + START_CRIT_CODE; + /* add tuple to the page */ newoff = PageAddItem(ToPage, (Item) newtup.t_data, tuple_len, InvalidOffsetNumber, LP_USED); if (newoff == InvalidOffsetNumber) { - elog(ERROR, "\ + elog(STOP, "\ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)", (unsigned long)tuple_len, cur_page->blkno, (unsigned long)cur_page->free, cur_page->offsets_used, cur_page->offsets_free); @@ -1659,6 +1664,7 @@ failed to add item with len = %lu to page %u (free space %lu, nusd %u, noff %u)" PageSetLSN(ToPage, recptr); PageSetSUI(ToPage, ThisStartUpID); } + END_CRIT_CODE; cur_page->offsets_used++; num_moved++; diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 9b1728a9df..3d74d187ff 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.193 2000/11/30 01:27:19 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.194 2000/12/03 10:27:27 vadim Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -921,6 +921,11 @@ finish_xact_command(void) void handle_warn(SIGNAL_ARGS) { + if (StopIfError) + { + QueryCancel = true; + return; + } siglongjmp(Warn_restart, 1); } @@ -953,14 +958,14 @@ die(SIGNAL_ARGS) { PG_SETMASK(&BlockSig); - /* - * If ERROR/FATAL is in progress... - */ - if (InError) + ExitAfterAbort = true; + if (StopIfError) { - ExitAfterAbort = true; + QueryCancel = true; return; } + if (InError) /* If ERROR/FATAL is in progress... */ + return; elog(FATAL, "The system is shutting down"); } @@ -1631,7 +1636,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.193 $ $Date: 2000/11/30 01:27:19 $\n"); + puts("$Revision: 1.194 $ $Date: 2000/12/03 10:27:27 $\n"); } /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index e6c19b246e..3ce9434d68 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.70 2000/12/01 19:52:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.71 2000/12/03 10:27:28 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -33,7 +33,6 @@ #include "commands/copy.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" -#include "miscadmin.h" #include "storage/proc.h" #include "tcop/tcopprot.h" #include "utils/memutils.h" @@ -159,6 +158,8 @@ elog(int lev, const char *fmt, ...) /* this is probably redundant... */ if (IsInitProcessingMode()) lev = FATAL; + if (StopIfError) + lev = STOP; } /* choose message prefix and indent level */ diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 785ac94c9b..269315dc78 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -3,7 +3,7 @@ * * PostgreSQL transaction log manager * - * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.12 2000/11/30 01:47:32 vadim Exp $ + * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.13 2000/12/03 10:27:28 vadim Exp $ */ #ifndef XLOG_H #define XLOG_H @@ -88,6 +88,7 @@ typedef XLogPageHeaderData *XLogPageHeader; extern StartUpID ThisStartUpID; /* current SUI */ extern bool InRecovery; extern XLogRecPtr MyLastRecPtr; +extern uint32 StopIfError; typedef struct RmgrData { diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 062a581840..0b97397d7c 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: tcopprot.h,v 1.35 2000/10/07 00:58:23 tgl Exp $ + * $Id: tcopprot.h,v 1.36 2000/12/03 10:27:29 vadim Exp $ * * OLD COMMENTS * This file was created so that other c files could get the two @@ -25,7 +25,6 @@ extern DLLIMPORT sigjmp_buf Warn_restart; extern bool Warn_restart_ready; extern bool InError; -extern bool ExitAfterAbort; extern bool HostnameLookup; extern bool ShowPortNumber; diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 5fba756f39..ad1643b690 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -7,13 +7,15 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: elog.h,v 1.18 2000/06/04 15:06:34 petere Exp $ + * $Id: elog.h,v 1.19 2000/12/03 10:27:29 vadim Exp $ * *------------------------------------------------------------------------- */ #ifndef ELOG_H #define ELOG_H +#include "miscadmin.h" + #define NOTICE 0 /* random info - no special action */ #define ERROR (-1) /* user error - return to known state */ #define FATAL 1 /* fatal error - abort process */ @@ -27,6 +29,25 @@ extern int Use_syslog; #endif +/* + * If StopIfError > 0 signal handlers don't do + * elog(ERROR|FATAL) but remember what action was + * required with QueryCancel & ExitAfterAbort + */ +extern bool ExitAfterAbort; +#define START_CRIT_CODE StopIfError++ +#define END_CRIT_CODE \ + if (!StopIfError)\ + elog(STOP, "Not in critical section");\ + StopIfError--;\ + if (!StopIfError && QueryCancel)\ + {\ + if (ExitAfterAbort)\ + elog(FATAL, "The system is shutting down");\ + else\ + elog(ERROR, "Query was cancelled.");\ + } + extern bool Log_timestamp; extern bool Log_pid;