Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vq0vl-002nVU-0D for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Feb 2026 03:30:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vq0vj-002DIL-0d for pgsql-hackers@arkaria.postgresql.org; Wed, 11 Feb 2026 03:30:20 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vq0vi-002DIC-2V for pgsql-hackers@lists.postgresql.org; Wed, 11 Feb 2026 03:30:19 +0000 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vq0vh-000000005VT-1VF9 for pgsql-hackers@lists.postgresql.org; Wed, 11 Feb 2026 03:30:19 +0000 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-2a963f49234so16320645ad.1 for ; Tue, 10 Feb 2026 19:30:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1770780615; cv=none; d=google.com; s=arc-20240605; b=enn1JlNjROeB0CqsS5w6Da8eqwqzZLexouorVhixWVJmJiVu6cFCkHIzH2P/9uLtQ8 CMDC0QhBEtfHDN4fXmjHckCpIgZAQz5XACe0dzdevrAmSJIsAiG8FqHDQ0qfTrz99dci FLi9xZoUS7aDkdl0VPysttTDoe/8TIqyCDzWG4xkz3e6cSAi+zoAQ1Ue+P3G421SfFQf J6zytNV0k96IoTkLBU23KWFGr3YcuTTdpvmXaL7ugqQ8hV0zW7dhIXHQn5Xw9rIu5AbE nCDS07kYBoPKZ3qhWVMaavPpbzeUyKHepQ7GQ8MyyNg3oiJyQq+XHwcnSWAQ+SGxikFM RGHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=a+JMzbL3U2dwLXQodtGL9Cy2x4PZmJ2yfX7GCUXanDQ=; fh=r9w9PsUtvtMRJQYuw+d2X3ogW396LTBPq014jPXw08Y=; b=XiQiShyaYl7IkCqXJ+mAdMzeaGhqw1dZLCfHVVgfh2w/Ic9Wbnq/2HV9rGGcmZMuof FglA/zoQ8PkF7g79PV7UTX3CpvngNyZpp/UikqrOl6nXGqCK2U55GsO0CNQKXzCOzI+7 fAVjRnUe0VtKlf7wnASGZ5a9BtYteAhyBTYbnbjDNt1uzLue0qFTk692sFKaBSQJEIM3 u7uhZWs0fre6KbrGiBnZmtS5p5RZSm1Q0yDVE5OswUtLy7LFqkr5bDafiXdZzxELgw7l 3U0XvTnV9/RXG8u3BkvSTlQwzINyQLagBYzUcCghHwJ11rugez9UuUq3osPc2RGSgGja Cg+g==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770780615; x=1771385415; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=a+JMzbL3U2dwLXQodtGL9Cy2x4PZmJ2yfX7GCUXanDQ=; b=EnZsUX//YpE+H1iazU1rFeFIY/3HT1MaisZJkeT8f/qg4ZE2hvFz5sxvLAsLmoSaAp Qw/G1Ej2kFvfh3O02EqNkgBfrd9RXj+9CGwideyPBEGKhQ7ok60SC0xzOCsk0YsDdCXk HGMNcBduuVCdiaPbTXzBqS6mTlsHqo+LlURo/YCcZt16Evbowyi2JTGYJwMbb/xh7Z0s cmU7mtTF6KRWsz/dxJwiiiok8LMjsRckQ2A9Q+q8G0LbX3xcClXO8IYywHJBImEYF6Ml qhwMLzNu2ZkYMBkrqYkMSZMpOdm5qc0Uyh2S3M7MJeoxOA853WUWMcqy+gLdn6aryrlh wFRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770780615; x=1771385415; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=a+JMzbL3U2dwLXQodtGL9Cy2x4PZmJ2yfX7GCUXanDQ=; b=d2HuUYiXw+7JCHptJ82pZKu8yAHPmcfe7VbsMV9B8DG+3/d5RvQ/HUGmCVQtX1oQwd h4LCnOoItDLx9IIb1V36DwWv/NyIw/QJEAI+whzIAHu0fmTiCN1ogKYykbEnOAQ675Ow HdBYY0sLrdFPrQAOwYHCCh+A2Y5iwQ0YazMnRkbeRB7zQNL00x6YObSITasZuXNpj1HT b4ruwPhmwthQ20lDu1AqvRvK0e0qSj4vQsMXcNYudmfif9cm6QzLOmrBZwCsA0vUCa1A uFn9tDhYgNMSAFnvPbobyF2Npj9NEh0FgGUYUZZLip+mmTUznte/xGwv6uo0EmUwnsHE Xl/A== X-Gm-Message-State: AOJu0YzOo3ZarkBx5mms/OHw4t5LnRvkVGIaoS+TF80ZNtBd8aWlDFH4 B5bCpX5g2/rw4kZR4pd0tt7KwcPXr5+nYWFzhauD4PIlJ38D4cwxxP+EVDTovq9qn6H2NfuSBKR rs/Afnm7GJhh+XLfTkrifuTxq74+WdVA= X-Gm-Gg: AZuq6aKXLK2TX0bpsYjnEw7YYvk5on5ybzfu76kfFwwlJa8Lrw8iEPFq+q0MbSoK9T+ t/RqUP9cXuFU4Au2qud/1KgreEJvBNH2g7RYMMcOHH6yxRYBug8Jz5LC62Mn/VPN3DvfBA+TWC+ 27RTefyWvv8HDR9pVsgqsOst7HkIBSt4xM96BeyLv0thooDkA/QoVF3zD+iyDShXCQ0wD2oN+df x8NEfjLilPh3SSamODsMF/glDhZumjawl1cdoIf7uyMYYN42SfPD1/BXvzNL73KmHdMPDMWW5VW jMGDj//hgPl12vxIlxJLRbhmL44ZFAinwT1JVedyTSs4ZYtakLV0xQ== X-Received: by 2002:a17:902:e787:b0:2a7:5171:9221 with SMTP id d9443c01a7336-2ab10a01cc8mr40241045ad.42.1770780615016; Tue, 10 Feb 2026 19:30:15 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: shveta malik Date: Wed, 11 Feb 2026 09:00:02 +0530 X-Gm-Features: AZwV_Qh2BeBvnbNb_02lzjpehQ8JGFLUUDbux2rqdRxToNmtpga2xOMCPaBaaZg Message-ID: Subject: Re: [PATCH] Support automatic sequence replication To: Ajin Cherian Cc: PostgreSQL Hackers , shveta malik Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri, Feb 6, 2026 at 2:47=E2=80=AFPM shveta malik wrote: > > On Fri, Feb 6, 2026 at 2:45=E2=80=AFPM shveta malik wrote: > > > > On Thu, Feb 5, 2026 at 10:33=E2=80=AFAM Ajin Cherian wrote: > > > > > > On Tue, Feb 3, 2026 at 9:22=E2=80=AFPM shveta malik wrote: > > > > > > > > On Tue, Feb 3, 2026 at 9:18=E2=80=AFAM Ajin Cherian wrote: > > > > Thanks for the patch. > > > > > > > > +1 for the overall idea of patch that once a subscription is create= d > > > > which subscribes to sequences, a sequence sync worker is started wh= ich > > > > continuously syncs the sequences. This makes usage of REFRESH > > > > SEQUENCES redundant and thus it is removed. I am still reviewing th= e > > > > design choice here, and will post my comments soon (if any). > > > > > > > > > > Thanks! > > > > > > > By quick validation, few issues in current implementation: > > > > > > > > 1) > > > > If the sequence sync worker exits due to some issue (or killed or > > > > server restarts), sequence-sync worker is not started again by appl= y > > > > worker unless there is a sequence in INIT state i.e. synchronizatio= n > > > > of sequences in READY state stops. IIUC, the logic of > > > > ProcessSequencesForSync() needs to change to start seq sync worker > > > > irrespective of state of sequences. > > > > > > > > > > Yes, I fixed this. I've changed FetchRelationStates to fetch sequence= s > > > in ANY state and not just ones in NON READY state. > > > > > > > 2) > > > > There is some issue in how LOGs (DEBUGs) are getting generated. > > > > > > > > a) Even if there is no drift, it still keeps on dumping: > > > > "logical replication sequence synchronization for subscription "sub= 1" > > > > - total unsynchronized: 3" > > > > > > > > > > Removed this. > > > > > > > b) > > > > When there is a drift in say single sequence, it puts rest (which a= re > > > > in sync) to "missing" section: > > > > "logical replication sequence synchronization for subscription "sub= 1" > > > > - batch #1 =3D 3 attempted, 1 succeeded, 0 mismatched, 0 insufficie= nt > > > > permission, 2 missing from publisher, 0 skipped" > > > > > > > > > > Fixed, and added a new section called "no drift". Also now this debug > > > message is printed every time the worker attempts to synchronize > > > sequences. also mentioning the state of the sequences being synced. > > > > > > > 3) > > > > If a sequence sync worker is taking a nap, and subscription is > > > > disabled or the server is stopped just before upgrade, how is the u= ser > > > > supposed to know that sequences are synced at the end? > > > > > > Well, one way is to wait for a debug message that says that all the > > > attempted sequences are in the "no drift" state. Also remote > > > sequence's LSN is updated in pg_subscription_rel for each sequence. > > > Let me know if you have anything more in mind. One option is to leave > > > the ALTER SUBSCRIPTION..REFRESH SEQUENCE in place, that will change > > > the state of all the sequences to the INIT state, and the user can > > > then wait for the sequences to change state to READY. > > > > I think this point needs more analysis. I am analyzing and discussing > > it further. > > > > > Attaching patch v3 addressing the above comments. > > > > > > > Thank You for the patch. I haven=E2=80=99t reviewed the details yet, bu= t it > > would be good to evaluate whether we really need to start the sequence > > sync worker so deep inside the apply worker. Currently, the caller of > > ProcessSequencesForSync(), namely ProcessSyncingRelations() is invoked > > for every apply message to process possible state-changes of relation > > and start worker (tablesync/sequence-sync etc). Since monitoring > > state-change behavior is no longer required for sequences, should we > > consider moving this logic to the main loop of the apply worker, > > possibly within LogicalRepApplyLoop()? There, we could check whether > > the table has any sequences and, if a worker is not already running, > > start one. Thoughts? > > Correction to last line: > There, we could check whether *the current susbcription* has any > sequences and, if a worker is not already running,start one. > Few more comments: 1) + /* Run sync for sequences in READY state */ + sequence_copied |=3D LogicalRepSyncSequences(LogRepWorkerWalRcvConn, SUBREL_STATE_READY); + + /* Call initial sync for sequences in INIT state */ + sequence_copied |=3D LogicalRepSyncSequences(LogRepWorkerWalRcvConn, SUBREL_STATE_INIT); Above logic means we ping primary twice for one seq-sync cycle? Is it possible to do it in below way: Get all sequences from the publisher in one go. If local-seq's state is INIT, copy those sequences, move the state to READY= . If local-seq's state is READY, check the drift and proceed accordingly. i.e, there should be a single call to LogicalRepSyncSequences() and relstate shouldn't even be an argument. 2) GetSequence: + /* Open and lock the sequence relation */ + seqrel =3D table_open(relid, AccessShareLock); GetSequence is called from check_sequence_drift and check_sequence_drift() from copy_sequences(). In copy_sequences(), we already open the seq's (localrelid) table in get_and_validate_seq_info() and give it as output (see sequence_rel). Same can be passed to this instead of trying opening the table again. 3) + /* Verify it's actually a sequence */ + if (seqrel->rd_rel->relkind !=3D RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + RelationGetRelationName(seqrel)))); Do we need this check? IIUC, sequence_rel is opened using RowExclusiveLock in get_and_validate_seq_info() and thus should not hit this case so that it becomes non-sequence later on. If required, we can have Assert. I can review further once these and previous comments are addressed. thanks Shveta