Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ik757-0001dp-Ps for pgsql-hackers@arkaria.postgresql.org; Wed, 25 Dec 2019 13:52:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1ik756-0000a9-FZ for pgsql-hackers@arkaria.postgresql.org; Wed, 25 Dec 2019 13:52:08 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ik755-0000a0-Uq for pgsql-hackers@lists.postgresql.org; Wed, 25 Dec 2019 13:52:08 +0000 Received: from cyclops.postgrespro.ru ([93.174.131.138] helo=mail.postgrespro.ru) by makus.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1ik74x-0006NP-QE for pgsql-hackers@postgresql.org; Wed, 25 Dec 2019 13:52:06 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id 985B721C2448; Wed, 25 Dec 2019 16:51:57 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=x tagged_above=-99 required=4 WHITELISTED tests=[] autolearn=unavailable Received: from [192.168.27.223] (gw.postgrespro.ru [93.174.131.141]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mail.postgrespro.ru (Postfix) with ESMTPSA id 366E021C227B; Wed, 25 Dec 2019 16:51:57 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1577281917; bh=Zoj5Am+sz4nK4RusbuP90Mf3HM0/9zptB5SlXvSz2SA=; h=Subject:To:Cc:References:From:Date:In-Reply-To; b=qAFIQ5LNpvGvBySwS8MW6e4xuGd26rC4f+ey/ldFGH/W4EEpUVLH2krAFeM1Dt+TW 2zNOd6kbCeSZfsMqBoSxyaE3axmEOw2xPQLVnwOC3xnmn/sEPLr5bVNdJmlkGMIIll K6QXBRy1CqIdwgiq6JNMYz2qb0SrnmyGsvt9TZZU= Subject: Re: Physical replication slot advance is not persistent To: Kyotaro Horiguchi Cc: pgsql-hackers@postgresql.org, michael@paquier.xyz, simon@2ndquadrant.com References: <059cc53a-8b14-653a-a24d-5f867503b0ee@postgrespro.ru> <20191225.130337.442597881772691026.horikyota.ntt@gmail.com> From: Alexey Kondratov Message-ID: Date: Wed, 25 Dec 2019 16:51:57 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 In-Reply-To: <20191225.130337.442597881772691026.horikyota.ntt@gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 25.12.2019 07:03, Kyotaro Horiguchi wrote: > At Tue, 24 Dec 2019 20:12:32 +0300, Alexey Kondratov wrote in >> I dig into the code and it happens because of this if statement: >> >>     /* Update the on disk state when lsn was updated. */ >>     if (XLogRecPtrIsInvalid(endlsn)) >>     { >>         ReplicationSlotMarkDirty(); >>         ReplicationSlotsComputeRequiredXmin(false); >>         ReplicationSlotsComputeRequiredLSN(); >>         ReplicationSlotSave(); >>     } > Yes, it seems just broken. > >> Attached is a small patch, which fixes this bug. I have tried to >> stick to the same logic in this 'if (XLogRecPtrIsInvalid(endlsn))' >> and now pg_logical_replication_slot_advance and >> pg_physical_replication_slot_advance return InvalidXLogRecPtr if >> no-op. >> >> What do you think? > I think we shoudn't change the definition of > pg_*_replication_slot_advance since the result is user-facing. Yes, that was my main concern too. OK. > The functions return a invalid value only when the slot had the > invalid value and failed to move the position. I think that happens > only for uninitalized slots. > > Anyway what we should do there is dirtying the slot when the operation > can be assumed to have been succeeded. > > As the result I think what is needed there is just checking if the > returned lsn is equal or larger than moveto. Doen't the following > change work? > > - if (XLogRecPtrIsInvalid(endlsn)) > + if (moveto <= endlsn) Yep, it helps with physical replication slot persistence after advance, but the whole validation (moveto <= endlsn) does not make sense for me. The value of moveto should be >= than minlsn == confirmed_flush / restart_lsn, while endlsn == retlsn is also always initialized with confirmed_flush / restart_lsn. Thus, your condition seems to be true in any case, even if it was no-op one, which we were intended to catch. Actually, if we do not want to change pg_*_replication_slot_advance, we can just add straightforward validation that either confirmed_flush, or restart_lsn changed after slot advance guts execution. It will be a little bit bulky, but much more clear and will never be affected by pg_*_replication_slot_advance logic change. Another weird part I have found is this assignment inside pg_logical_replication_slot_advance: /* Initialize our return value in case we don't do anything */ retlsn = MyReplicationSlot->data.confirmed_flush; It looks redundant, since later we do the same assignment, which should be reachable in any case. I will recheck everything again and try to come up with something during this week. Regards -- Alexey Kondratov Postgres Professional https://www.postgrespro.com Russian Postgres Company