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.94.2) (envelope-from ) id 1rS8Bv-00BbYY-FD for pgsql-hackers@arkaria.postgresql.org; Tue, 23 Jan 2024 04:15:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1rS8Bu-009FJr-ME for pgsql-hackers@arkaria.postgresql.org; Tue, 23 Jan 2024 04:15:14 +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.94.2) (envelope-from ) id 1rS8Bu-009FJf-Bk for pgsql-hackers@lists.postgresql.org; Tue, 23 Jan 2024 04:15:14 +0000 Received: from mail-lj1-x22b.google.com ([2a00:1450:4864:20::22b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rS8Br-003EoU-7c for pgsql-hackers@postgresql.org; Tue, 23 Jan 2024 04:15:13 +0000 Received: by mail-lj1-x22b.google.com with SMTP id 38308e7fff4ca-2ccae380df2so38399191fa.1 for ; Mon, 22 Jan 2024 20:15:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705983310; x=1706588110; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=llyf3HMdVjV9Wl3XILl5qnjKWiAfQMI0g9oA+F3PEbE=; b=eEyBBEncUFegHI6pl82gzQTXEkT1mFHuks5mU4t2U7Hi1QoGR9ulgeAgH87kF+WCwp 16CiEt7ZvGUnkWvA5b3YoB/AWQITGJ77YXv5uErmIqNFdObzHw5FGL2e5ZBZacaRU6LA 9auSH6gxz0F9KDjaG0pih7KAPl+V28y64IY6X0Tq2XUy665BjccihY9Mtq/urf7bLBpV e1sgN8plU3Da1ILE/Quf/OVT5fse9Qe9JnquTN2hq0xpZ1T99ShXBVlDxMHgIjaHf7O7 voRNPjQc8wzc4Xn8lEd8UJ9IDCJj+eQGy9VHLE879CI/tRQbH7qwY1QAhPry6tnnoFza Orug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705983310; x=1706588110; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=llyf3HMdVjV9Wl3XILl5qnjKWiAfQMI0g9oA+F3PEbE=; b=hTgxNjzPASUheyWY67TG19EHuMHjBrO1stfdYlr7E3izK7RwA9gJV/lm0nQAloEuUa JYFiPk/ym2eG+P04gtSIKUa7pUWLEznZW9UXnaDDDjL1QtbcwBoKZj+h1nOisUjPhwic MQm3/mENgUEJRB4fnOLkPn23z/UL33wMlyYTrmV77AcEZqU40p/BcoYWxaw2PxxpZgip +aPcmi8ciu2WqviPgCBEqanrSd+IdLaRMFX8nkn4PFjv+PXQ83wS7IgJvKcjnmSNxelH 6YLFI1Rp6V78g/+ncktMzYazkfAZoKY4DYXRxa5Bk4aRydFBbQOsmmB+8BxE1EDVNRK7 BTuA== X-Gm-Message-State: AOJu0YxoHP58FJ/8MbpX8baGsJX6OcpGCrD8SWAK1EXRfZx7AmqcnM+l J+iFHDMiC+Qf+4knX3snXvzwYfQTiLohgCdTxtYbEBvZYTo8SeaQCEi7iQO62iYCPsZCPblJeJp EBo7BKnOd++vDc3rIAgImXzNE/P8= X-Google-Smtp-Source: AGHT+IGoeXSxn8fLzon1sNSEPIVGKIgelHLmIGDdJtJAceIOvv6RbNqCX0bZ3EAw3M7aIbhWkJ+RxXzR54/3hCILSMA= X-Received: by 2002:a2e:b8c4:0:b0:2cf:150a:e0d2 with SMTP id s4-20020a2eb8c4000000b002cf150ae0d2mr58034ljp.38.1705983310035; Mon, 22 Jan 2024 20:15:10 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Peter Smith Date: Tue, 23 Jan 2024 15:14:42 +1100 Message-ID: Subject: Re: Synchronizing slots from primary to standby To: shveta malik Cc: Amit Kapila , Bertrand Drouvot , Masahiko Sawada , "Zhijie Hou (Fujitsu)" , Dilip Kumar , Nisha Moond , "Hayato Kuroda (Fujitsu)" , Bharath Rupireddy , Peter Eisentraut , Bruce Momjian , Ashutosh Sharma , Andres Freund , pgsql-hackers , Ajin Cherian , Alvaro Herrera Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Here are some review comments for v65-0002 ====== 0. General - GUCs in messages I think it would be better for the GUC names to all be quoted. It's not a rule (yet), but OTOH it seems to be the consensus most people want. See [1]. This might impact the following messages: 0.1 + ereport(ERROR, + errmsg("could not fetch primary_slot_name \"%s\" info from the" + " primary server: %s", PrimarySlotName, res->err)); SUGGESTION errmsg("could not fetch primary server slot \"%s\" info from the primary server: %s", ...) errhint("Check if \"primary_slot_name\" is configured correctly."); ~~~ 0.2 + if (!tuplestore_gettupleslot(res->tuplestore, true, false, tupslot)) + elog(ERROR, "failed to fetch primary_slot_name tuple"); SUGGESTION elog(ERROR, "failed to fetch tuple for the primary server slot specified by \"primary_slot_name\""); ~~~ 0.3 + ereport(ERROR, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("exiting from slot synchronization due to bad configuration"), + /* translator: second %s is a GUC variable name */ + errdetail("The primary server slot \"%s\" specified by %s is not valid.", + PrimarySlotName, "primary_slot_name")); /specified by %s/specified by \"%s\"/ ~~~ 0.4 + ereport(ERROR, + /* translator: %s is a GUC variable name */ + errmsg("exiting from slot synchronization due to bad configuration"), + errhint("%s must be defined.", "primary_slot_name")); /%s must be defined./\"%s\" must be defined./ ~~~ 0.5 + ereport(ERROR, + /* translator: %s is a GUC variable name */ + errmsg("exiting from slot synchronization due to bad configuration"), + errhint("%s must be enabled.", "hot_standby_feedback")); /%s must be enabled./\"%s\" must be enabled./ ~~~ 0.6 + ereport(ERROR, + /* translator: %s is a GUC variable name */ + errmsg("exiting from slot synchronization due to bad configuration"), + errhint("wal_level must be >= logical.")); errhint("\"wal_level\" must be >= logical.")) ~~~ 0.7 + if (PrimaryConnInfo == NULL || strcmp(PrimaryConnInfo, "") == 0) + ereport(ERROR, + /* translator: %s is a GUC variable name */ + errmsg("exiting from slot synchronization due to bad configuration"), + errhint("%s must be defined.", "primary_conninfo")); /%s must be defined./\"%s\" must be defined./ ~~~ 0.8 + ereport(ERROR, + + /* + * translator: 'dbname' is a specific option; %s is a GUC variable + * name + */ + errmsg("exiting from slot synchronization due to bad configuration"), + errhint("'dbname' must be specified in %s.", "primary_conninfo")); /must be specified in %s./must be specified in \"%s\"./ ~~~ 0.9 + ereport(LOG, + errmsg("skipping slot synchronization"), + errdetail("enable_syncslot is disabled.")); errdetail("\"enable_syncslot\" is disabled.")); ====== src/backend/replication/logical/slotsync.c 1. +/* Min and Max sleep time for slot sync worker */ +#define MIN_WORKER_NAPTIME_MS 200 +#define MAX_WORKER_NAPTIME_MS 30000 /* 30s */ + +/* + * Sleep time in ms between slot-sync cycles. + * See wait_for_slot_activity() for how we adjust this + */ +static long sleep_ms = MIN_WORKER_NAPTIME_MS; These all belong together, so I think they share a combined comment like: SUGGESTION The sleep time (ms) between slot-sync cycles varies dynamically (within a MIN/MAX range) according to slot activity. See wait_for_slot_activity() for details. ~~~ 2. update_and_persist_slot + /* First time slot update, the function must return true */ + if(!local_slot_update(remote_slot)) + elog(ERROR, "failed to update slot"); Missing whitespace after 'if' ~~~ 3. synchronize_one_slot + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("exiting from slot synchronization because same" + " name slot \"%s\" already exists on standby", + remote_slot->name), + errdetail("A user-created slot with the same name as" + " failover slot already exists on the standby.")); 3a. /on standby/on the standby/ ~ 3b. Now the errmsg is changed, the errdetail doesn't seem so useful. Isn't it repeating pretty much the same information as in the errmsg? ====== src/backend/replication/walsender.c 4. GetStandbyFlushRecPtr /* - * Returns the latest point in WAL that has been safely flushed to disk, and - * can be sent to the standby. This should only be called when in recovery, - * ie. we're streaming to a cascaded standby. + * Returns the latest point in WAL that has been safely flushed to disk. + * This should only be called when in recovery. + * Since it says "This should only be called when in recovery", should there also be a check for that (e.g. RecoveryInProgress) in the added Assert? ====== src/include/replication/walreceiver.h 5. typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn, TimeLineID *primary_tli); +/* + * walrcv_get_dbname_from_conninfo_fn + * + * Returns the dbid from the primary_conninfo + */ +typedef char *(*walrcv_get_dbname_from_conninfo_fn) (const char *conninfo); It looks like a blank line that previously existed has been lost. ====== [1] https://www.postgresql.org/message-id/CAHut%2BPsf3NewXbsFKY88Qn1ON1_dMD6343MuWdMiiM2Ds9a_wA%40mail.gmail.com Kind Regards, Peter Smith. Fujitsu Australia