Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eBpHZ-0006pU-Ik for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Nov 2017 21:50:13 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1eBpHZ-0003er-45 for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Nov 2017 21:50:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eBpHY-0003eX-K9 for pgsql-hackers@postgresql.org; Mon, 06 Nov 2017 21:50:12 +0000 Received: from mail-pg0-x22c.google.com ([2607:f8b0:400e:c05::22c]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84_2) (envelope-from ) id 1eBpHU-0000F2-U4 for pgsql-hackers@postgresql.org; Mon, 06 Nov 2017 21:50:12 +0000 Received: by mail-pg0-x22c.google.com with SMTP id g6so9302483pgn.6 for ; Mon, 06 Nov 2017 13:50:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bowt-ie.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=2HLUh9K+caGKnRJ9Muqq9AUkug0znR4z9mgjSORtFU0=; b=E9X/have6bLSvG3jwbnLRunYMjsvrgIeeN9bwC0rsJQH0JDO6V2XoOAqC1t9g3va0K hOlz7JQfVhfvOMTZytFn5P/TF3oNwseSmNzkujo6GZrsUdNtZAShu3YMEG4NgwezEfK8 qpnugDMyLqkmenV4346CNcXlqwRslPWJ+fVhIyk63+DER0stHJgrYZu25UDKRtQVPm15 Y+cNJbDRFhj1CY9J1KC2I+H/4/H/E2L6fkdlqb8EYHMjqczcGvgHoLyRYVTxUgn0NH+e HqGJHYhxikVU69nTP5T0Noa6p29G39mb+5e5H0u3WhLF4imLa3ZsOHOdbRuBuiNbm60D o2nQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=2HLUh9K+caGKnRJ9Muqq9AUkug0znR4z9mgjSORtFU0=; b=KEBAZgsLQDQQVRbzE6eWYUkSgnqFmKRm5hVHNUrGV1TtReNlNsJq22OnF6VpTuXDi6 HhG4Lz7uhciIvl04dqpsly5VsQ2KRPYYb7Xhbu0utpJLZ4/SjfQCuu8dmN5h631Pge+5 B5Nc0nhj9+9IBgxgleGzoz7cvAoDm+gtJPanD0wN8ipJDV7ZC3rRYYpE5FVf3VdqlyZ1 SvXCGa+EDHEW1g92lFk9mLTpZCTCGPax+B1vmN9dMI7hajPTCBQLQMtYlhUDfdVW7yA1 +xMzcAuteHYHb3+2kv3KLwQfyze7NlGACRD1J1HERNuVwgg1SdNoYxJb4J1qX4hjUqPk z9ag== X-Gm-Message-State: AMCzsaUarRzkVDKtHy3DT0ckApaJLhPguRoO6/NOq+2Yw8mg3bfBsool mAiVZXz8BkOb8Le2S1pubypZlg== X-Google-Smtp-Source: ABhQp+RCcM3HR+GbvbQMTwjQDod/v/rGEh4qQE3fHFLNCH1zr0rKujC81YhItY5Ujc5gEJ6HRdaWpQ== X-Received: by 10.84.245.150 with SMTP id j22mr16196932pll.324.1510005006048; Mon, 06 Nov 2017 13:50:06 -0800 (PST) Received: from marmot ([162.217.72.7]) by smtp.gmail.com with ESMTPSA id a70sm23238719pfa.94.2017.11.06.13.50.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 06 Nov 2017 13:50:05 -0800 (PST) Date: Mon, 6 Nov 2017 13:50:03 -0800 From: Peter Geoghegan To: Simon Riggs Cc: Robert Haas , Stephen Frost , Michael Paquier , PostgreSQL-development Subject: Re: MERGE SQL Statement for PG11 Message-ID: <20171106215003.GA30357@marmot> References: <20171030185511.GJ4628@tamriel.snowman.net> <20171103163539.GA17026@marmot> <20171106183537.GA22811@marmot> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org Simon Riggs wrote: >In step 3 we discover that an entry exists in the index for a committed row. > >Since we have a unique index we use it to locate the row we know >exists and UPDATE that. > >We don't use a new MVCC snapshot, we do what EPQ does. EPQ is already >violating MVCC for UPDATEs, so why does it matter if we do it for >INSERTs also? Before I go on to say why I think that this approach is problematic, I want to point out a few things that I think we actually agree on: * EPQ is fairly arbitrary as a behavior for READ COMMITTED UPDATE conflict handling. It has more to do with how VACUUM works than about some platonic ideal that everyone agrees on. * We can imagine other alternatives, such as the behavior in Oracle (statement level rollback + optimistic retry). * Those alternatives are probably better in some ways but worse in other ways. * EPQ violates snapshot consistency, even though that's not inherently necessary to avoid "READ COMMITTED serialization errors". * ON CONFLICT also violates snapshot consistency, in rather a different way. (Whether or not this is necessary is more debatable.) I actually think that other MVCC systems don't actually copy Oracle here, either, and for similar pragmatic reasons. It's a mixed bag. >Where hides the problem? The problem is violating MVCC is something that can be done in different ways, and by meaningful degrees: * EPQ semantics are believed to be fine because we don't get complaints about it. I think that that's because it's specialized to UPDATEs and UPDATE-like operations, where we walk an UPDATE chain specifically, and only use a dirty snapshot for the chain's newer tuples. * ON CONFLICT doesn't care about UPDATE chains. Unlike EPQ, it makes no distinction between a concurrent UPDATE, and a concurrent DELETE + fresh INSERT. It's specialized to CONFLICTs. This might seem abstract, but it has real, practical implications. Certain contradictions exist when you start with MVCC semantics, then fall back to EPQ semantics, then finally fall back to ON CONFLICT semantics. Questions about mixing these two things: * What do we do if someone concurrently UPDATEs in a way that makes the qual not pass during EPQ traversal? Should we INSERT when that happens? * If so, what about the case when the MERGE join qual/unique index values didn't change (just some other attributes that do not pass the additional WHEN MATCHED qual)? * What about when there was a concurrent DELETE -- should we INSERT then? ON CONFLICT goes from a CONFLICT, and then applies its own qual. That's hugely different to doing it the other way around: starting from your own MVCC snapshot qual, and going to a CONFLICT. This is because evaluating the DO UPDATE's WHERE clause is just one little extra step after the one and only latest row for that value has been locked. You could theoretically go this way with 2PL, I think, because that's a bit like locking every row that the predicate touches, but of course that isn't at all practical. I should stop trying to make a watertight case against this, even though I still think that's possible. For now, instead, I'll just say that this is *extremely* complicated, and still has unresolved questions about semantics. -- Peter Geoghegan -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers