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 1tnGgH-003iVq-BV for pgsql-general@arkaria.postgresql.org; Wed, 26 Feb 2025 12:38:29 +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 1tnGgG-0050wR-Bc for pgsql-general@arkaria.postgresql.org; Wed, 26 Feb 2025 12:38:28 +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 1tnGgF-0050uX-Up for pgsql-general@lists.postgresql.org; Wed, 26 Feb 2025 12:38:27 +0000 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tnGgC-000CPv-2n for pgsql-general@postgresql.org; Wed, 26 Feb 2025 12:38:27 +0000 Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-38dcac27bcbso546857f8f.0 for ; Wed, 26 Feb 2025 04:38:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740573504; x=1741178304; darn=postgresql.org; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=TJa48zTRvofsY2K2oYR50u1uf7x9mxRn5I2L5GVHPKo=; b=KYHgUBPPgba3eOHli4VDJ1gT8USnS0k4qEy2FGLEArJYt78AUQGx2zjtHhE/geB4BY Su+seihHc2SMecoem/3yHrRUnJ3bU4LL7bTZ8aJHYiPMDda/8qpTz+HK87ZI8M7Uek2B pRlyJZC7LC4evc1p4TvdePOPvZ3wy8mBWynDhYZj5tMNmNAK6ShaEeFcv5sJFACj7P0n psg+40WPOAWlpoxjB3+Uj8HpkvCbxUhjJiMwUnzzIEYKQXxjOMOSaQPitYSBL1lGvvOu Cj7T1U4jNHx6c2jOpvj0pRlAWGLFmWLk2MwxNOIH4s3g+B0IUPYQ1+R0ojz4Jku3DnMo pw8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740573504; x=1741178304; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=TJa48zTRvofsY2K2oYR50u1uf7x9mxRn5I2L5GVHPKo=; b=sewt4LxCodqQMnugcxEDPw+9tneHgRdrodoeZ2WwUQXHupOObPTG7ugzIc+M9r6J7W xe2aPTU2ATWCpptbkIESnuDYQJIorJ3IMVL+bUg3xu9u7g59q6ivsMArld4pY664UJue iNCxC9GcBQ7i2cgsU3vQYUvMDYOebEdTT++5si9VVwU/sYtbcu8Lqx+QHTUZQgOfls2A BXbWSnikzrddv7+xUKipQgsjFWgzqnuc7dEv5tDDXe0czmK3+mbPNmskBP8y+HOtrw1f o8WkIJO1OVuYv9rYk6MzAPft9UfA1/bw8iA+qhXCrLIL5WvaDkqoLexpPz29tfPimxoZ g+dw== X-Gm-Message-State: AOJu0YxDgBKyZZJAZU1IHcrOJ1qZD/PkzSFJjaGdiGLuubUeG3pFNTcS fnfBFdd0YgtLF+lS46jmjb6I2t//Z28h76JGbQDSWuKD7XOzubFrs+TfUg== X-Gm-Gg: ASbGnctkNBI8PKhjPI6+KGEu4uf8O/pMw0hKSy1VYuygpT1e3sQNYcXiUEtt6v07dW6 Z2MOsYnGOVol+nuynn6c3BpwXFR2Sjo3oLv3zPZ8FodgD6yfwIC7nqEiGUD/bc1reLQzyKKWbLQ ygjtlFE+UU32IyteBnT1vt445f0qzuc1ROujAT4gRQFhb9eAR9BpSg4PGT9ZwSWHG8nhVAEhF8U dy7FZMjqKYiE8wODiHg4iHCPmrV9zGhMquHM5C9iNJw6GQcoerFfRfl0dKGkTsFOfpyN9IC20no DQfWoLpADD32Jgd8z8tyK3JuKz4cSoer04O/Gef95IPkBSejGTLhThXlg/js6pN1cmQdgS8wDai TFfYSJbNA3h9+Jw== X-Google-Smtp-Source: AGHT+IGnJF5mCzrAWb8w7zq2xWATkMGXYqNUqvL3ksg4nR9JmrQYc1bqgJXhjBDmjjChwZtjgkAjMg== X-Received: by 2002:a5d:59ac:0:b0:38d:d8f7:8f75 with SMTP id ffacd0b85a97d-38f6160f9a0mr21514894f8f.17.1740573503893; Wed, 26 Feb 2025 04:38:23 -0800 (PST) Received: from [192.168.0.1] (lfbn-idf2-1-89-142.w83-202.abo.wanadoo.fr. [83.202.178.142]) by smtp.googlemail.com with ESMTPSA id 5b1f17b1804b1-43aba5442c0sm19797135e9.32.2025.02.26.04.38.23 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 26 Feb 2025 04:38:23 -0800 (PST) Message-ID: <8f745b7e-24a4-41e4-b331-6344a33ac89a@gmail.com> Date: Wed, 26 Feb 2025 13:38:22 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: =?UTF-8?Q?Fran=C3=A7ois_Lafont?= Subject: PG16 and replication, ensure a clean switchover after a stop of the primary server To: pgsql-general@postgresql.org Content-Language: fr, en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, First, I have put all details of this post in this gist https://gist.github.com/flaf/ccedf78d0290d231e79581077fd92dbc (with a little video/demo to see with your eyes ;)). I have 2 PostgreSQL servers version 16.8 on RedHat 8.10, with physical streaming async replication: * postgres-1 the primary server, * postgres-2 the warm standby server. It's a detail but on these servers, PGDATA=/pg_data/pginc and the UniX account and superuser is "pginc". There is continuous WAL archiving via the /pg_archives/pginc/ NFS share mounted on postgres-1 and postgres-2. My goal is to stop nicely the PostgreSQL daemon on the primary server and then ensure that the standby server is well synchronized (ie it contains *exactly* the same data as the stopped primary server). To check that, I use this command on the primary and on the standby: ~$ pg_controldata /pg_data/pginc/ | grep REDO -C 6 Here an example of output on the primary when PostgreSQL has been stopped: ------------------------------------------------------------------- Catalog version number: 202307071 Database system identifier: 7470764453209630447 Database cluster state: shut down pg_control last modified: Tue 25 Feb 2025 03:51:34 PM CET Latest checkpoint location: 0/6F000028 Latest checkpoint's REDO location: 0/6F000028 Latest checkpoint's REDO WAL file: 00000001000000000000006F Latest checkpoint's TimeLineID: 1 Latest checkpoint's PrevTimeLineID: 1 Latest checkpoint's full_page_writes: on Latest checkpoint's NextXID: 0:4349 Latest checkpoint's NextOID: 18418 ------------------------------------------------------------------- To check if the standby server is well synchronized I compare the value of "Latest checkpoint's REDO location" on primary and on standby (but is it a reliable check? <= it's my question 4). Here are my questions. 1. When I stop nicely PostgreSQL on the primary server (postgres-1) with `systemctl stop postgresql.service` and then I run the `CHECKPOINT;` query on the secondary server (postgres-2), the latest checkpoint's REDO location are not the same on postgres-1 and postgres-2, except from time to time (rather rarely) in a rather random way. Why? I thought that walsender on the primary server would delay the PostgreSQL shutdown request until confirming all sent data are flushed on remote side? Is it false? This page https://postgrespro.com/list/thread-id/2630031 seems to confirm it's well true. Note: servers are just VM for test on my desktop. There is no trafic (read/write) on the primary except some INSERTs I do manually to simulate a little traffic (see my video on my gist). 2. In fact, concerning this point (walsenders delay the shutdown request until confirming all sent data are flushed on remote side), is there official documentation? I have not found. 3. Now, I add this line in the postgresql.conf of primary server: wal_keep_size = '512MB' The value seems to be without any importance, I just set the parameter to a non zero value. I reload the configuration. Now, I'm doing exactly the same test as 1. and, at the end, I have **systematically** the same the latest checkpoint's REDO location on postgres-1 and postgres-2. Why? Is it normal? Or is the case 1. abnormal? 4. When the primary server is stopped, if have exactly the same latest checkpoint location and the same latest checkpoint's REDO location, on the primary server and the secondary server, can I be sure that the data on the secondary server is exactly the same as the data on the primary server, with the last changes made to the primary server before its PostgreSQL daemon was shutdown? Thanks for your help. Note: here is the common postgresql.conf of the two servers (but all is in my gist https://gist.github.com/flaf/ccedf78d0290d231e79581077fd92dbc): ------------------------------------------------------------------- listen_addresses = 'localhost,' port = '4900' unix_socket_directories = '/var/run/postgresql' unix_socket_permissions = 0700 max_connections = 810 superuser_reserved_connections = 10 timezone = 'Europe/Paris' lc_messages = 'en_US.UTF8' lc_monetary = 'fr_FR.UTF8' lc_numeric = 'fr_FR.UTF8' lc_time = 'fr_FR.UTF8' default_text_search_config = 'pg_catalog.french' datestyle = 'iso,dmy' log_directory = '/pg_logs/pginc' logging_collector = on log_filename = 'postgresql-%a.log' log_rotation_age = 1d log_rotation_size = 0 log_truncate_on_rotation = on log_timezone = 'Europe/Paris' log_min_duration_statement = 5000 # 5 seconds log_autovacuum_min_duration = 0 password_encryption = scram-sha-256 wal_level = replica archive_mode = on archive_command = 'cp %p /pg_archives/pginc/%f' restore_command = 'cp /pg_archives/pginc/%f %p' #wal_keep_size = '512MB' dynamic_shared_memory_type = posix max_worker_processes = 2 max_parallel_workers = 2 shared_buffers = 1420MB # ~0.25 x RAM effective_cache_size = 4260MB # ~0.75 x RAM work_mem = 10MB maintenance_work_mem = 512MB # 512 or 1024 MiB wal_buffers = 16MB min_wal_size = 1GB max_wal_size = 4GB max_standby_streaming_delay = 20min # To allow long readonly queries on the standby server. effective_io_concurrency = 200 random_page_cost = 1.1 track_activity_query_size = 8096 shared_preload_libraries = 'pg_stat_statements,auto_explain' pg_stat_statements.max = 10000 auto_explain.log_min_duration = -1 # disable auto_explain extension currently ------------------------------------------------------------------- -- François Lafont