pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andres Freund <af@cybertec.de>
To: pgsql-hackers@postgresql.org
Cc: Simon Riggs <simon@2ndquadrant.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alvaro Herrera <alvherre@commandprompt.com>
Subject: Re: Small Bug in GetConflictingVirtualXIDs
Date: Sun, 27 Dec 2009 20:11:26 +0100
Message-ID: <200912272011.27003.af@cybertec.de> (raw)
In-Reply-To: <1261478551.7442.4332.camel@ebony>
References: <200912210402.37850.andres@anarazel.de>
	<200912220319.10264.af@cybertec.de>
	<1261478551.7442.4332.camel@ebony>

On Tuesday 22 December 2009 11:42:30 Simon Riggs wrote:
> On Tue, 2009-12-22 at 03:19 +0100, Andres Freund wrote:
> > On Monday 21 December 2009 16:48:52 Simon Riggs wrote:
> > > Giving the drop database a snapshot is not the answer. I expect Andres
> > > to be able to fix this with a simple patch that would not effect the
> > > case of normal running.
> >
> > Actually its less simply than I had thought at first - I don't think the
> > code ever handled that correctly.
> > I might be wrong there, my knowledge of the involved code is a bit
> > sparse... The whole conflict resolution builds on the concept of waiting
> > for an VXid, but an idle backend does not have a valid vxid. Thats
> > correct, right?
> I don't see any mileage in making Startup process wait for an idle
> session, so no real reason to wait for others either.
So here is a small patch implementing that behaviour.

Andres

Attachments:

0001-Fix-the-bug-in-HS-that-it-is-possible-to-stay-connec.patch (text/x-patch, 3.6K) download From 36f57e6f6b1d25d7433d9706682e53cc79b45a61 Mon Sep 17 00:00:00 2001 From: Andres Freund <andres@anarazel.de> Date: Sun, 27 Dec 2009 19:14:21 +0100 Subject: [PATCH] Fix the bug in HS that it is possible to stay connected to a database on a slave after it has been deleted. Instead immediately kill sessions using such a database - it is unlikely that those sessions will quit and its unlikely as well that its a significant issue to get thrown of a database which is dropped on the master. --- src/backend/commands/dbcommands.c | 22 ++++++++-------------- src/backend/storage/ipc/procarray.c | 25 +++++++++++++++++++++++++ src/include/storage/procarray.h | 1 + 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 316222f..85d1d64 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -1945,22 +1945,16 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record) if (InHotStandby) { - VirtualTransactionId *database_users; - /* - * Find all users connected to this database and ask them - * politely to immediately kill their sessions before processing - * the drop database record, after the usual grace period. - * We don't wait for commit because drop database is - * non-transactional. + * We dont do the usual GetConflictingVirtualXIDs/ + * ResolveRecoveryConflictWithVirutalXIDs dance here because we are + * not only conflicting against concurrently running transactions + * but against concurrently running backends using this database. + * + * We do not wait for those sessions to exit by free will because + * quite likely that will never happen. So force them. */ - database_users = GetConflictingVirtualXIDs(InvalidTransactionId, - xlrec->db_id, - false); - - ResolveRecoveryConflictWithVirtualXIDs(database_users, - "drop database", - CONFLICT_MODE_FATAL); + CancelDBBackends(xlrec->db_id); } /* Drop pages for this database that are in the shared buffer cache */ diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 8e2de35..07c7899 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1827,6 +1827,31 @@ CountDBBackends(Oid databaseid) } /* + * CancelDBBackends --- cancel backends that are using specified database + */ +void +CancelDBBackends(Oid databaseid) +{ + ProcArrayStruct *arrayP = procArray; + int index; + + /* tell all backends to die */ + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + for (index = 0; index < arrayP->numProcs; index++) + { + volatile PGPROC *proc = arrayP->procs[index]; + + if (proc->databaseId == databaseid){ + if (proc->recoveryConflictMode < CONFLICT_MODE_FATAL){ + proc->recoveryConflictMode = CONFLICT_MODE_FATAL; + } + kill(proc->pid, SIGINT); + } + } + LWLockRelease(ProcArrayLock); +} + +/* * CountUserBackends --- count backends that are used by specified user */ int diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 1cee639..707396b 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -63,6 +63,7 @@ extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, extern int CountActiveBackends(void); extern int CountDBBackends(Oid databaseid); +extern void CancelDBBackends(Oid databaseid); extern int CountUserBackends(Oid roleid); extern bool CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared); -- 1.6.5.12.gd65df24

view thread (14+ messages)  latest in thread

Message-ID: <200912272011.27003.af@cybertec.de>
Permalink:  ../200912272011.27003.af@cybertec.de/
Also on:    postgresql.org/message-id/200912272011.27003.af@cybertec.de

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: af@cybertec.de, simon@2ndquadrant.com, tgl@sss.pgh.pa.us, alvherre@commandprompt.com
  Subject: Re: Small Bug in GetConflictingVirtualXIDs
  In-Reply-To: <200912272011.27003.af@cybertec.de>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox