You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Add PostgreSQL 14 support.
There are no code changes from PostgreSQL 13 so simply add the new version. Add CATALOG_VERSION_NO_MAX to allow the catalog version to "float" during the PostgreSQL beta/rc period so new pgBackRest versions are not required when the catalog version changes. Update the integration tests to handle new PostgreSQL startup messages.
This commit is contained in:
		| @@ -72,6 +72,17 @@ | ||||
|                 </release-bug-list> | ||||
|  | ||||
|                 <release-feature-list> | ||||
|                     <release-item> | ||||
|                         <github-pull-request id="1413"/> | ||||
|  | ||||
|                         <release-item-contributor-list> | ||||
|                             <release-item-contributor id="david.steele"/> | ||||
|                             <release-item-reviewer id="cynthia.shang"/> | ||||
|                         </release-item-contributor-list> | ||||
|  | ||||
|                         <p>Add <proper>PostgreSQL 14</proper> support.</p> | ||||
|                     </release-item> | ||||
|  | ||||
|                     <release-item> | ||||
|                         <commit subject="Use existing variable for GCS test server port."/> | ||||
|                         <commit subject="Refactor GCS token response parsing into a separate function."/> | ||||
|   | ||||
| @@ -147,6 +147,7 @@ SRCS = \ | ||||
| 	postgres/interface/v110.c \ | ||||
| 	postgres/interface/v120.c \ | ||||
| 	postgres/interface/v130.c \ | ||||
| 	postgres/interface/v140.c \ | ||||
| 	protocol/client.c \ | ||||
| 	protocol/command.c \ | ||||
| 	protocol/helper.c \ | ||||
|   | ||||
| @@ -78,6 +78,16 @@ typedef struct PgInterface | ||||
|  | ||||
| static const PgInterface pgInterface[] = | ||||
| { | ||||
|     { | ||||
|         .version = PG_VERSION_14, | ||||
|  | ||||
|         .controlIs = pgInterfaceControlIs140, | ||||
|         .control = pgInterfaceControl140, | ||||
|         .controlVersion = pgInterfaceControlVersion140, | ||||
|  | ||||
|         .walIs = pgInterfaceWalIs140, | ||||
|         .wal = pgInterfaceWal140, | ||||
|     }, | ||||
|     { | ||||
|         .version = PG_VERSION_13, | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								src/postgres/interface/v140.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/postgres/interface/v140.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| PostgreSQL 14 Interface | ||||
|  | ||||
| See postgres/interface/version.intern.h for documentation. | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "build.auto.h" | ||||
|  | ||||
| #define PG_VERSION                                                  PG_VERSION_14 | ||||
|  | ||||
| #include "postgres/interface/version.intern.h" | ||||
|  | ||||
| PG_INTERFACE(140); | ||||
| @@ -87,4 +87,10 @@ uint32_t pgInterfaceControlVersion130(void); | ||||
| bool pgInterfaceWalIs130(const unsigned char *walFile); | ||||
| PgWal pgInterfaceWal130(const unsigned char *controlFile); | ||||
|  | ||||
| bool pgInterfaceControlIs140(const unsigned char *controlFile); | ||||
| PgControl pgInterfaceControl140(const unsigned char *controlFile); | ||||
| uint32_t pgInterfaceControlVersion140(void); | ||||
| bool pgInterfaceWalIs140(const unsigned char *walFile); | ||||
| PgWal pgInterfaceWal140(const unsigned char *controlFile); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -24,6 +24,22 @@ Determine if the supplied pg_control is for this version of PostgreSQL | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_83 | ||||
|  | ||||
| #ifdef CATALOG_VERSION_NO_MAX | ||||
|  | ||||
| #define PG_INTERFACE_CONTROL_IS(version)                                                                                           \ | ||||
|     bool                                                                                                                           \ | ||||
|     pgInterfaceControlIs##version(const unsigned char *controlFile)                                                                \ | ||||
|     {                                                                                                                              \ | ||||
|         ASSERT(controlFile != NULL);                                                                                               \ | ||||
|                                                                                                                                    \ | ||||
|         return                                                                                                                     \ | ||||
|             ((ControlFileData *)controlFile)->pg_control_version == PG_CONTROL_VERSION &&                                          \ | ||||
|             ((ControlFileData *)controlFile)->catalog_version_no >= CATALOG_VERSION_NO &&                                          \ | ||||
|             ((ControlFileData *)controlFile)->catalog_version_no < (CATALOG_VERSION_NO / 100000 + 1) * 100000;                     \ | ||||
|     } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define PG_INTERFACE_CONTROL_IS(version)                                                                                           \ | ||||
|     bool                                                                                                                           \ | ||||
|     pgInterfaceControlIs##version(const unsigned char *controlFile)                                                                \ | ||||
| @@ -37,6 +53,8 @@ Determine if the supplied pg_control is for this version of PostgreSQL | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Read the version specific pg_control into a general data structure | ||||
| ***********************************************************************************************************************************/ | ||||
|   | ||||
| @@ -95,7 +95,7 @@ typedef unsigned int Oid; | ||||
| #endif | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Types from src/include/utils/pg_crc32.h | ||||
| Types from src/include/port/pg_crc32.h | ||||
| ***********************************************************************************************************************************/ | ||||
|  | ||||
| // pg_crc32/c type | ||||
| @@ -177,9 +177,31 @@ Types from src/include/catalog/catversion.h | ||||
| ***********************************************************************************************************************************/ | ||||
|  | ||||
| // CATALOG_VERSION_NO define | ||||
| // | ||||
| // When PostgreSQL is in alpha/beta/rc the catalog version may change with each release. To prevent breakage during this period | ||||
| // define CATATLOG_VERSION_NO_MAX. This will allow the catalog version to "float" through the end of the year. After the PostgreSQL | ||||
| // release, remove CATALOG_VERSION_NO_MAX in the next pgBackRest release to lock down the catalog version. A side effect of this is | ||||
| // that during the period when the catalog number is allowed to float pgBackRest may misidentify development versions of PostgreSQL | ||||
| // for the next release as being an alpha/beta/rc for the current release. This seems a minor issue to prevent breakage. | ||||
| // --------------------------------------------------------------------------------------------------------------------------------- | ||||
| #if PG_VERSION > PG_VERSION_MAX | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_14 | ||||
|  | ||||
| /* | ||||
|  * We could use anything we wanted for version numbers, but I recommend | ||||
|  * following the "YYYYMMDDN" style often used for DNS zone serial numbers. | ||||
|  * YYYYMMDD are the date of the change, and N is the number of the change | ||||
|  * on that day.  (Hopefully we'll never commit ten independent sets of | ||||
|  * catalog changes on the same day...) | ||||
|  */ | ||||
|  | ||||
| /*							yyyymmddN */ | ||||
| #define CATALOG_VERSION_NO	202105121 | ||||
|  | ||||
| // Allow the catalog version to float during the PostgreSQL 14 beta/rc period | ||||
| #define CATALOG_VERSION_NO_MAX | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_13 | ||||
|  | ||||
| /* | ||||
| @@ -454,6 +476,44 @@ Types from src/include/catalog/pg_control.h | ||||
| // --------------------------------------------------------------------------------------------------------------------------------- | ||||
| #if PG_VERSION > PG_VERSION_MAX | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_14 | ||||
|  | ||||
| /* | ||||
|  * Body of CheckPoint XLOG records.  This is declared here because we keep | ||||
|  * a copy of the latest one in pg_control for possible disaster recovery. | ||||
|  * Changing this struct requires a PG_CONTROL_VERSION bump. | ||||
|  */ | ||||
| typedef struct CheckPoint | ||||
| { | ||||
| 	XLogRecPtr	redo;			/* next RecPtr available when we began to | ||||
| 								 * create CheckPoint (i.e. REDO start point) */ | ||||
| 	TimeLineID	ThisTimeLineID; /* current TLI */ | ||||
| 	TimeLineID	PrevTimeLineID; /* previous TLI, if this record begins a new | ||||
| 								 * timeline (equals ThisTimeLineID otherwise) */ | ||||
| 	bool		fullPageWrites; /* current full_page_writes */ | ||||
| 	FullTransactionId nextXid;	/* next free transaction ID */ | ||||
| 	Oid			nextOid;		/* next free OID */ | ||||
| 	MultiXactId nextMulti;		/* next free MultiXactId */ | ||||
| 	MultiXactOffset nextMultiOffset;	/* next free MultiXact offset */ | ||||
| 	TransactionId oldestXid;	/* cluster-wide minimum datfrozenxid */ | ||||
| 	Oid			oldestXidDB;	/* database with minimum datfrozenxid */ | ||||
| 	MultiXactId oldestMulti;	/* cluster-wide minimum datminmxid */ | ||||
| 	Oid			oldestMultiDB;	/* database with minimum datminmxid */ | ||||
| 	pg_time_t	time;			/* time stamp of checkpoint */ | ||||
| 	TransactionId oldestCommitTsXid;	/* oldest Xid with valid commit | ||||
| 										 * timestamp */ | ||||
| 	TransactionId newestCommitTsXid;	/* newest Xid with valid commit | ||||
| 										 * timestamp */ | ||||
|  | ||||
| 	/* | ||||
| 	 * Oldest XID still running. This is only needed to initialize hot standby | ||||
| 	 * mode from an online checkpoint, so we only bother calculating this for | ||||
| 	 * online checkpoints and only when wal_level is replica. Otherwise it's | ||||
| 	 * set to InvalidTransactionId. | ||||
| 	 */ | ||||
| 	TransactionId oldestActiveXid; | ||||
| } CheckPoint; | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_12 | ||||
|  | ||||
| /* | ||||
| @@ -2163,6 +2223,10 @@ Types from src/include/access/xlog_internal.h | ||||
| // --------------------------------------------------------------------------------------------------------------------------------- | ||||
| #if PG_VERSION > PG_VERSION_MAX | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_14 | ||||
|  | ||||
| #define XLOG_PAGE_MAGIC 0xD10D	/* can be used as WAL version indicator */ | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_13 | ||||
|  | ||||
| #define XLOG_PAGE_MAGIC 0xD106	/* can be used as WAL version indicator */ | ||||
| @@ -2221,6 +2285,27 @@ Types from src/include/access/xlog_internal.h | ||||
| // --------------------------------------------------------------------------------------------------------------------------------- | ||||
| #if PG_VERSION > PG_VERSION_MAX | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_14 | ||||
|  | ||||
| /* | ||||
|  * Each page of XLOG file has a header like this: | ||||
|  */ | ||||
| typedef struct XLogPageHeaderData | ||||
| { | ||||
| 	uint16		xlp_magic;		/* magic value for correctness checks */ | ||||
| 	uint16		xlp_info;		/* flag bits, see below */ | ||||
| 	TimeLineID	xlp_tli;		/* TimeLineID of first record on page */ | ||||
| 	XLogRecPtr	xlp_pageaddr;	/* XLOG address of this page */ | ||||
|  | ||||
| 	/* | ||||
| 	 * When there is not enough space on current page for whole record, we | ||||
| 	 * continue on the next page.  xlp_rem_len is the number of bytes | ||||
| 	 * remaining from a previous page; it tracks xl_tot_len in the initial | ||||
| 	 * header.  Note that the continuation data isn't necessarily aligned. | ||||
| 	 */ | ||||
| 	uint32		xlp_rem_len;	/* total len of remaining data for record */ | ||||
| } XLogPageHeaderData; | ||||
|  | ||||
| #elif PG_VERSION >= PG_VERSION_93 | ||||
|  | ||||
| /* | ||||
|   | ||||
| @@ -25,8 +25,9 @@ PostgreSQL version constants | ||||
| #define PG_VERSION_11                                               110000 | ||||
| #define PG_VERSION_12                                               120000 | ||||
| #define PG_VERSION_13                                               130000 | ||||
| #define PG_VERSION_14                                               140000 | ||||
|  | ||||
| #define PG_VERSION_MAX                                              PG_VERSION_13 | ||||
| #define PG_VERSION_MAX                                              PG_VERSION_14 | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Version where various PostgreSQL capabilities were introduced | ||||
| @@ -77,5 +78,6 @@ PostgreSQL version string constants for use in error messages | ||||
| #define PG_VERSION_11_STR                                            "11" | ||||
| #define PG_VERSION_12_STR                                            "12" | ||||
| #define PG_VERSION_13_STR                                            "13" | ||||
| #define PG_VERSION_14_STR                                            "14" | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -12,6 +12,10 @@ | ||||
| # - docker login -u pgbackrest | ||||
| # - VM=XXX;DATE=YYYYMMDDX;BASE=pgbackrest/test:${VM?}-base;docker tag ${BASE?} ${BASE?}-${DATE?} && docker push ${BASE?}-${DATE?} | ||||
| # ********************************************************************************************************************************** | ||||
| 20210521A: | ||||
|   x86_64: | ||||
|     u18: a92925d1200fd12d5f3d59f3a3db555c6efa00be | ||||
|  | ||||
| 20210503A: | ||||
|   aarch64: | ||||
|     u20: 00a309971d5566ff3eb0db92c66b4f4ef0566d36 | ||||
| @@ -21,10 +25,6 @@ | ||||
|   x86_64: | ||||
|     co7: 2c1e13990f92635cc7d959dcbe497b765861c2b2 | ||||
|  | ||||
| 20200924A: | ||||
|   x86_64: | ||||
|     u18: d95d53e642fc1cea4a2b8e935ea7d9739f7d1c46 | ||||
|  | ||||
| 20200507A: | ||||
|   x86_64: | ||||
|     f32: 61792779061d2a675509c65bfa64b61b8d4cea17 | ||||
|   | ||||
| @@ -395,6 +395,7 @@ unit: | ||||
|           - postgres/interface/v110 | ||||
|           - postgres/interface/v120 | ||||
|           - postgres/interface/v130 | ||||
|           - postgres/interface/v140 | ||||
|           - protocol/client | ||||
|           - protocol/command | ||||
|           - protocol/helper | ||||
|   | ||||
| @@ -484,7 +484,7 @@ sub containerBuild | ||||
|             { | ||||
|                 $strScript .= | ||||
|                     "    echo 'deb http://apt.postgresql.org/pub/repos/apt/ " . | ||||
|                     $$oVm{$strOS}{&VM_OS_REPO} . '-pgdg main' . | ||||
|                     $$oVm{$strOS}{&VM_OS_REPO} . '-pgdg main' . ($strOS eq VM_U18 ? ' 14' : '') . | ||||
|                         "' >> /etc/apt/sources.list.d/pgdg.list && \\\n" . | ||||
|                     "    wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \\\n" . | ||||
|                     "    apt-get update && \\\n" . | ||||
|   | ||||
| @@ -41,6 +41,8 @@ use constant PG_VERSION_12                                          => '12'; | ||||
|     push @EXPORT, qw(PG_VERSION_12); | ||||
| use constant PG_VERSION_13                                          => '13'; | ||||
|     push @EXPORT, qw(PG_VERSION_13); | ||||
| use constant PG_VERSION_14                                          => '14'; | ||||
|     push @EXPORT, qw(PG_VERSION_14); | ||||
|  | ||||
| use constant PG_VERSION_APPLICATION_NAME                            => PG_VERSION_90; | ||||
|     push @EXPORT, qw(PG_VERSION_APPLICATION_NAME); | ||||
| @@ -61,7 +63,7 @@ sub versionSupport | ||||
|  | ||||
|     my @strySupportVersion = (PG_VERSION_83, PG_VERSION_84, PG_VERSION_90, PG_VERSION_91, PG_VERSION_92, PG_VERSION_93, | ||||
|                               PG_VERSION_94, PG_VERSION_95, PG_VERSION_96, PG_VERSION_10, PG_VERSION_11, PG_VERSION_12, | ||||
|                               PG_VERSION_13); | ||||
|                               PG_VERSION_13, PG_VERSION_14); | ||||
|  | ||||
|     # Return from function and log return values if any | ||||
|     return logDebugReturn | ||||
|   | ||||
| @@ -296,6 +296,7 @@ my $oyVm = | ||||
|             PG_VERSION_84, | ||||
|             PG_VERSION_90, | ||||
|             PG_VERSION_91, | ||||
|             PG_VERSION_92, | ||||
|         ], | ||||
|     }, | ||||
|  | ||||
| @@ -393,11 +394,11 @@ my $oyVm = | ||||
|             PG_VERSION_11, | ||||
|             PG_VERSION_12, | ||||
|             PG_VERSION_13, | ||||
|             PG_VERSION_14, | ||||
|         ], | ||||
|  | ||||
|         &VM_DB_TEST => | ||||
|         [ | ||||
|             PG_VERSION_92, | ||||
|             PG_VERSION_93, | ||||
|             PG_VERSION_94, | ||||
|             PG_VERSION_95, | ||||
| @@ -405,6 +406,7 @@ my $oyVm = | ||||
|             PG_VERSION_11, | ||||
|             PG_VERSION_12, | ||||
|             PG_VERSION_13, | ||||
|             PG_VERSION_14, | ||||
|         ], | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -477,7 +477,8 @@ sub clusterStop | ||||
|     if (!$bIgnoreLogError && storageTest()->exists($self->pgLogFile())) | ||||
|     { | ||||
|         $self->executeSimple( | ||||
|             'grep -v "FATAL\:  57P03\: the database system is starting up" ' . $self->pgLogFile() . ' | grep "ERROR\|FATAL"', | ||||
|             'grep -v "FATAL\:  57P03\: the database system is (starting up|not yet accepting connections|" | ||||
|                 "not accepting connections)" ' . $self->pgLogFile() . ' | grep "ERROR\|FATAL"', | ||||
|             {iExpectedExitStatus => 1}); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -249,6 +249,7 @@ sub dbCatalogVersion | ||||
|         &PG_VERSION_11 => 201806231, | ||||
|         &PG_VERSION_12 => 201909212, | ||||
|         &PG_VERSION_13 => 202007201, | ||||
|         &PG_VERSION_14 => 202105121, | ||||
|     }; | ||||
|  | ||||
|     if (!defined($hCatalogVersion->{$strPgVersion})) | ||||
| @@ -293,6 +294,7 @@ sub dbControlVersion | ||||
|         &PG_VERSION_11 => 1100, | ||||
|         &PG_VERSION_12 => 1201, | ||||
|         &PG_VERSION_13 => 1300, | ||||
|         &PG_VERSION_14 => 1300, | ||||
|     }; | ||||
|  | ||||
|     if (!defined($hControlVersion->{$strPgVersion})) | ||||
|   | ||||
| @@ -65,6 +65,7 @@ sub run | ||||
|         {pg => PG_VERSION_11, repoDest =>     HOST_BACKUP, storage => AZURE, encrypt => false, compress =>  ZST, repo => 2}, | ||||
|         {pg => PG_VERSION_12, repoDest =>     HOST_BACKUP, storage =>    S3, encrypt =>  true, compress =>  LZ4, repo => 1}, | ||||
|         {pg => PG_VERSION_13, repoDest => HOST_DB_STANDBY, storage =>   GCS, encrypt => false, compress =>  ZST, repo => 1}, | ||||
|         {pg => PG_VERSION_14, repoDest =>     HOST_BACKUP, storage => POSIX, encrypt =>  true, compress =>  LZ4, repo => 2}, | ||||
|     ) | ||||
|     { | ||||
|         # Only run tests for this pg version | ||||
|   | ||||
| @@ -63,6 +63,10 @@ uint32_t hrnPgInterfaceCatalogVersion130(void); | ||||
| void hrnPgInterfaceControl130(PgControl pgControl, unsigned char *buffer); | ||||
| void hrnPgInterfaceWal130(PgWal pgWal, unsigned char *buffer); | ||||
|  | ||||
| uint32_t hrnPgInterfaceCatalogVersion140(void); | ||||
| void hrnPgInterfaceControl140(PgControl pgControl, unsigned char *buffer); | ||||
| void hrnPgInterfaceWal140(PgWal pgWal, unsigned char *buffer); | ||||
|  | ||||
| typedef struct HrnPgInterface | ||||
| { | ||||
|     // Version of PostgreSQL supported by this interface | ||||
| @@ -80,6 +84,13 @@ typedef struct HrnPgInterface | ||||
|  | ||||
| static const HrnPgInterface hrnPgInterface[] = | ||||
| { | ||||
|     { | ||||
|         .version = PG_VERSION_14, | ||||
|  | ||||
|         .catalogVersion = hrnPgInterfaceCatalogVersion140, | ||||
|         .control = hrnPgInterfaceControl140, | ||||
|         .wal = hrnPgInterfaceWal140, | ||||
|     }, | ||||
|     { | ||||
|         .version = PG_VERSION_13, | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								test/src/common/harnessPostgres/harness140.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								test/src/common/harnessPostgres/harness140.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /*********************************************************************************************************************************** | ||||
| Harness for PostgreSQL Interface (see PG_VERSION for version) | ||||
| ***********************************************************************************************************************************/ | ||||
| #include "build.auto.h" | ||||
|  | ||||
| #define PG_VERSION                                                  PG_VERSION_14 | ||||
|  | ||||
| #include "common/harnessPostgres/harnessVersion.intern.h" | ||||
|  | ||||
| HRN_PG_INTERFACE(140); | ||||
		Reference in New Issue
	
	Block a user