Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n9lBQ-0001Ab-Sj for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Jan 2022 09:53:45 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1n9lBO-0007A5-EH for pgsql-hackers@arkaria.postgresql.org; Tue, 18 Jan 2022 09:53:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1n9lBO-00079w-3C for pgsql-hackers@lists.postgresql.org; Tue, 18 Jan 2022 09:53:42 +0000 Received: from mail-pg1-x52b.google.com ([2607:f8b0:4864:20::52b]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1n9lBL-0004qt-A9 for pgsql-hackers@postgresql.org; Tue, 18 Jan 2022 09:53:41 +0000 Received: by mail-pg1-x52b.google.com with SMTP id e9so2938726pgb.3 for ; Tue, 18 Jan 2022 01:53:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=A93Qtz1mTprT3dXzcqeKwUxcYf9pnJ+wCYbkshCJf8g=; b=HPswu4R1CfUoutX0+6IKieO0Rdv6+nf4M3HW+x00F1SARatj6n3PEVBLsPx5j1SqsO uvmgEoIGTDQbg7sTX+EHcuiNHBHZ4/mv3p2u1isKgPGxFSp5Cf6BUR+mwGjXCBb2xyG/ dSu+zkEsEiIlOLS9eLDSX+b20yOvoEXb50YUCaPF7pfsJlyocEmRBp1Ku8Q61Kofn6IN Z9I8JjbmIQht619Ce8lHoN6IQ230VL9HhgDRijq0uMaxc7EikXwTiGunLGms036HCdeF 4KxWR7AnG2B8mW8k+9mW/QfmbmKtgfar4PCca1Ljk4kn9RLtLUYNgSFdDJNwReG5qchc 4XFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=A93Qtz1mTprT3dXzcqeKwUxcYf9pnJ+wCYbkshCJf8g=; b=DV1UcR2n9kt2vsbJo6sMC0pP7Tiio18vpULdBm2GdC+xK0Z7DyuhMDKmCBCF9iDSa3 br6QSvR4dC/XBZK2oCyHu9pzXmQZweir5EQ6Ca0uLD3ZNJgkRRorINTd71no+Guani1n xnzS/wejEO3yohZAGU3duqLjwqhJ53phmwA/N0ofsUOsjJageBhWI6h/xjxOPzJSbLAo HhUfEsmSnN29eYQyGhgnt8CvHxoDM1dIGZA6ilnD62azF/6f5avwDItuDvbM91iKyzts f02zHm5/XO/63r+5ZULet1RXSCr4wyt+tyGZjkMlnHjXB/oOTjNTA1cpf9BY02rxBlBh M69Q== X-Gm-Message-State: AOAM5328o1HD0u/Zt2Jif3tBfCywFfxBowVRf5ivYhOhptG53uqhyJTu 3t8Sun9XPDUoLkswVBPVEpA= X-Google-Smtp-Source: ABdhPJwJn+9yk/ihzAvAbUqabzm7I40KmnaukMrQzs+6ihHukhDAUrsqR8VSysClRaMhetJxDZDgXw== X-Received: by 2002:a63:ce4c:: with SMTP id r12mr22708111pgi.21.1642499617137; Tue, 18 Jan 2022 01:53:37 -0800 (PST) Received: from jrouhaud (1-171-184-213.dynamic-ip.hinet.net. [1.171.184.213]) by smtp.gmail.com with ESMTPSA id ob12sm2607875pjb.17.2022.01.18.01.53.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 18 Jan 2022 01:53:36 -0800 (PST) Date: Tue, 18 Jan 2022 17:53:32 +0800 From: Julien Rouhaud To: Jeff Davis Cc: pgsql-hackers@postgresql.org, Andres Freund , Amit Kapila , Tom Lane , Simon Riggs Subject: Re: Extensible Rmgr for Table AMs Message-ID: <20220118095332.6xtlcjoyxobv6cbk@jrouhaud> References: <8a1b1ab033342433b1f827fee04ee562231fdb80.camel@j-davis.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <8a1b1ab033342433b1f827fee04ee562231fdb80.camel@j-davis.com> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, On Mon, Jan 17, 2022 at 12:42:06AM -0800, Jeff Davis wrote: > On Mon, 2021-11-08 at 15:36 -0800, Jeff Davis wrote: > > The attached patch (against v14, so it's easier to test columnar) is > > somewhat like a simplified version of [3] combined with refactoring > > to > > make decoding a part of the rmgr. > > New patches attached (v3). Essentially the content as v2, but split > into 3 patches and rebased. > > Review on patch 0001 would be helpful. It makes decoding just another > method of rmgr, which makes a lot of sense to me from a code > organization standpoint regardless of the other patches. Is there any > reason not to do that? I think that it's a clean and sensible approach, so +1 for me. There's a bit of 0003 present in 002: diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 35029cf97d..612b1b3723 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -738,7 +738,7 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, (uint32) SizeOfXLogRecord, record->xl_tot_len); return false; } - if (record->xl_rmid > RM_MAX_ID) + if (record->xl_rmid > RM_MAX_ID && record->xl_rmid < RM_CUSTOM_MIN_ID) { > > The other patches then make rmgr extensible, which in turn makes > decoding extensible and solves the logical replication problem for > custom table AMs. The most obvious way to make rmgr extensible would be > to expand the rmgr table, but I was concerned about making that dynamic > (right now the structure is entirely constant and perhaps that's > important for some optimizations?). So, at the cost of complexity I > made a separate, dynamic rmgr table to hold the custom entries. I'm not sure about performance overhead, but allowing extension to access the main table directly seems a bit scary. We definitely accepted some overhead with the various extensible support, and this new GetRmgr() doesn't look like it's going to cost a lot for the builtin case, especially compared to the cost of any of the code associated with the rmgr. Also, to answer your initial email I think it's a better way to go compared to your previous approach, given the limitations and performance of the generic xlog infrastructure, and hopefully index AMs should be able to rely on this too. A few random comments on 0003: #define RM_MAX_ID (RM_NEXT_ID - 1) +#define RM_CUSTOM_MIN_ID 128 +#define RM_CUSTOM_MAX_ID UINT8_MAX It would be a good idea to add a StaticAssertStmt here to make sure that there's no overlap in the ranges. + +/* + * RmgrId to use for extensions that require an RmgrId, but are still in + * development and have not reserved their own unique RmgrId yet. See: + * https://wiki.postgresql.org/wiki/ExtensibleRmgr + */ +#define RM_EXPERIMENTAL_ID 128 I'm a bit dubious about the whole "register your ID in the Wiki" approach. It might not be a problem since there probably won't be hundreds of users, and I don't have any better suggestion since it has to be consistent across nodes. + elog(LOG, "registering customer rmgr \"%s\" with ID %d", + rmgr->rm_name, rmid); Should it be a DEBUG message instead? Also s/customer/custom/ +RmgrData +GetCustomRmgr(RmgrId rmid) +{ + if (rmid < RM_CUSTOM_MIN_ID || rmid > RM_CUSTOM_MAX_ID) + elog(PANIC, "custom rmgr id %d out of range", rmid); Should this be an assert? +#define GetBuiltinRmgr(rmid) RmgrTable[(rmid)] +#define GetRmgr(rmid) ((rmid < RM_CUSTOM_MIN_ID) ? \ + GetBuiltinRmgr(rmid) : GetCustomRmgr(rmid)) rmid should be protected in the macro. > The custom rmgr API would probably be marked "experimental" for a > while, and I don't expect lots of people to use it given the challenges > of a production-quality table AM. But it's still important, because > without it a table AM has no chance to participate in logical > replication. How you plan to mark it experimental?