June 29, 2023·4 min read·engineeringpostgresqlreleaseslocalestesting

PostgreSQL 16 Beta 2 restores libc as the initialization default

The second PostgreSQL 16 beta changes locale-provider defaults and repairs developing features. Explicit initialization settings make the beta change concrete.

Creating a database cluster includes choices about language and character handling that persist beyond installation. PostgreSQL 16 Beta 2 changes one such choice back to libc, restoring it as the default locale provider selected by initdb. A beta upgrade therefore involves more than checking whether an application still parses the same SQL. A newly initialized test cluster may have different defaults from one created with the earlier beta.

The June 29 announcement lists the default-provider reversal among the changes since Beta 1. It also says the beta previews the planned feature set while allowing details to change during testing. This is an example of that qualification with a specific operational consequence, rather than a promise about the eventual final release.

I value PostgreSQL's documented operational choices. For a beta, a changed default is useful information because it identifies an assumption that application testing might otherwise leave implicit. The test environment needs to represent the database being evaluated, including how that database was initialized.

Initialization supplies defaults to later databases

The initdb documentation at the Beta 2 tag describes what initialization creates. It establishes shared catalogs and the postgres, template1 and template0 databases. It also selects locale and character-encoding settings for the template databases, which supply defaults for databases created later.

With the libc provider, locale selection comes from the environment unless options override it. The documentation provides --locale for the overall locale and separate options for individual categories. The provider itself can be selected explicitly through --locale-provider. Those are initialization choices with a longer lifetime than the command that creates the data directory.

ICU remains an available provider when PostgreSQL has been built with ICU support. The same tagged documentation describes selecting it with --locale-provider=icu and choosing its locale with --icu-locale. Restoring the default to libc does not remove the alternative. It changes what happens when a deployment leaves that choice unspecified.

The documentation also notes that ICU initialization still selects and initializes libc locale settings for implementation and legacy-code reasons. The two providers are therefore not a justification for assuming that every other locale-related setting disappears when ICU is selected. An explicit deployment specification needs to reflect the options PostgreSQL actually initializes.

ICU handles its own C-locale selection

Beta 2 also returns the handling of the C locale with ICU to the ICU library. The announcement says that on ICU 64 and later the C locale is obsolete, and ICU supplies its own mechanism for choosing a locale or raising an error. That is a separate change from choosing the default provider.

The distinction matters when interpreting a failed initialization. Selecting ICU explicitly and asking it to handle a particular locale is different from accepting the default provider. The announcement identifies library-version-dependent behavior, so a test result needs enough environment information to show which case it exercised. The default-provider reversal alone does not explain every ICU outcome.

The tagged documentation says initdb prints its selected locale settings. That output gives an immediate record of what initialization actually chose. For a beta comparison, retaining those settings makes it possible to separate a server behavior change from a different initialization choice. It also avoids treating a successful command as proof that every implicit setting matched the intended environment.

The other fixes cross feature boundaries

Several other Beta 2 corrections show why testing a developing database needs workloads with interacting features. The announcement names fixes related to join optimizations, without claiming a particular percentage improvement. It also identifies a B-tree correction associated with logical decoding from standby servers. That connection puts an established index implementation in the scope of a new replication capability.

A further fix concerns cache-lookup hazards while checking MAINTAIN privileges on partition ancestors. Permission checks involving partition relationships require correct object lookup as well as the intended access rule. The announcement does not provide a full reproducer, so the useful claim is the identified intersection of privileges, partitions and cache lookup, rather than an invented failure sequence.

My preference is for beta reports that name those intersections. They explain which application behaviors are relevant to exercising the release, and they make a better starting point than an undifferentiated claim that the beta contains stability improvements.

Beta installation remains a major-version exercise

The announcement requires an upgrade strategy comparable to moving between major PostgreSQL versions, naming pg_upgrade and dump-and-restore approaches. It does not describe replacing binaries over an existing earlier-version data directory as the beta upgrade procedure. That operational distinction remains relevant even when the objective is a temporary compatibility environment.

The project asks users to run representative application workloads and explicitly advises against using Beta 2 in production. It also says further betas and release candidates will follow as needed before the planned final release later in 2023. At this point, the concrete deliverable is a testable second beta whose default initialization behavior has changed. Results from it need to identify the selected locale provider so that subsequent testing can distinguish SQL regressions from differences established when the cluster was created.