Hi,

I was recently reminded of my previous desire to allow setting the segment
size to less than 1GB. It's pretty painful to test large amount of segments
with a segment size of 1GB, certainly our regression test don't cover anything
with multiple segments.

This likely wouldn't have detected the issue fixed in 0e758ae89a2, but it make
it easier to validate that the fix doesn't break anything badly.

In the attached patch I renamed --with-segsize= to --with-segsize-mb= /
-Dsegsize= to -Dsegsize_mb=, to avoid somebody building with --with-segsize=2
or such suddenly ending up with an incompatible build.

Greetings,

Andres Freund
>From e8f67e3c27ff553f6a3a26947cac8df91136e8f5 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Mon, 7 Nov 2022 09:05:35 -0800
Subject: [PATCH] allow-smaller-segsize

---
 doc/src/sgml/installation.sgml |  6 +++---
 doc/src/sgml/storage.sgml      |  2 +-
 .cirrus.yml                    |  1 +
 configure                      | 27 ++++++++++++++-------------
 configure.ac                   | 12 ++++++------
 meson.build                    |  6 ++++--
 meson_options.txt              |  4 ++--
 7 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 319c7e69660..20a98c3887c 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -1458,13 +1458,13 @@ build-postgresql:
       </varlistentry>
 
       <varlistentry>
-       <term><option>--with-segsize=<replaceable>SEGSIZE</replaceable></option></term>
+       <term><option>--with-segsize-mb=<replaceable>SEGSIZE</replaceable></option></term>
        <listitem>
         <para>
-         Set the <firstterm>segment size</firstterm>, in gigabytes.  Large tables are
+         Set the <firstterm>segment size</firstterm>, in megabytes.  Large tables are
          divided into multiple operating-system files, each of size equal
          to the segment size.  This avoids problems with file size limits
-         that exist on many platforms.  The default segment size, 1 gigabyte,
+         that exist on many platforms.  The default segment size, 1024 megabytes,
          is safe on all supported platforms.  If your operating system has
          <quote>largefile</quote> support (which most do, nowadays), you can use
          a larger segment size.  This can be helpful to reduce the number of
diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml
index e5b9f3f1ffa..03e0bb0ecbf 100644
--- a/doc/src/sgml/storage.sgml
+++ b/doc/src/sgml/storage.sgml
@@ -236,7 +236,7 @@ When a table or index exceeds 1 GB, it is divided into gigabyte-sized
 filenode; subsequent segments are named filenode.1, filenode.2, etc.
 This arrangement avoids problems on platforms that have file size limitations.
 (Actually, 1 GB is just the default segment size.  The segment size can be
-adjusted using the configuration option <option>--with-segsize</option>
+adjusted using the configuration option <option>--with-segsize-mb</option>
 when building <productname>PostgreSQL</productname>.)
 In principle, free space map and visibility map forks could require multiple
 segments as well, though this is unlikely to happen in practice.
diff --git a/.cirrus.yml b/.cirrus.yml
index 9f2282471a9..b0543f20175 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -377,6 +377,7 @@ task:
       -Dextra_lib_dirs=${brewpath}/lib \
       -Dcassert=true \
       -Dssl=openssl -Duuid=e2fs -Ddtrace=auto \
+      -Dsegsize_mb=1 \
       -DPG_TEST_EXTRA="$PG_TEST_EXTRA" \
       build
 
diff --git a/configure b/configure
index 3966368b8d9..fb55792f51b 100755
--- a/configure
+++ b/configure
@@ -843,7 +843,7 @@ enable_coverage
 enable_dtrace
 enable_tap_tests
 with_blocksize
-with_segsize
+with_segsize_mb
 with_wal_blocksize
 with_CC
 with_llvm
@@ -1553,7 +1553,8 @@ Optional Packages:
   --with-pgport=PORTNUM   set default port number [5432]
   --with-blocksize=BLOCKSIZE
                           set table block size in kB [8]
-  --with-segsize=SEGSIZE  set table segment size in GB [1]
+  --with-segsize-mb=SEGSIZE
+                          set table segment size in MB [1024]
   --with-wal-blocksize=BLOCKSIZE
                           set WAL block size in kB [8]
   --with-CC=CMD           set compiler (deprecated)
@@ -3740,32 +3741,32 @@ $as_echo_n "checking for segment size... " >&6; }
 
 
 
-# Check whether --with-segsize was given.
-if test "${with_segsize+set}" = set; then :
-  withval=$with_segsize;
+# Check whether --with-segsize-mb was given.
+if test "${with_segsize_mb+set}" = set; then :
+  withval=$with_segsize_mb;
   case $withval in
     yes)
-      as_fn_error $? "argument required for --with-segsize option" "$LINENO" 5
+      as_fn_error $? "argument required for --with-segsize-mb option" "$LINENO" 5
       ;;
     no)
-      as_fn_error $? "argument required for --with-segsize option" "$LINENO" 5
+      as_fn_error $? "argument required for --with-segsize-mb option" "$LINENO" 5
       ;;
     *)
-      segsize=$withval
+      segsize_mb=$withval
       ;;
   esac
 
 else
-  segsize=1
+  segsize_mb=1024
 fi
 
 
 # this expression is set up to avoid unnecessary integer overflow
 # blocksize is already guaranteed to be a factor of 1024
-RELSEG_SIZE=`expr '(' 1024 / ${blocksize} ')' '*' ${segsize} '*' 1024`
+RELSEG_SIZE=`expr '(' 1024 / ${blocksize} ')' '*' ${segsize_mb}`
 test $? -eq 0 || exit 1
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${segsize}GB" >&5
-$as_echo "${segsize}GB" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${segsize_mb}MB" >&5
+$as_echo "${segsize_mb}MB" >&6; }
 
 
 cat >>confdefs.h <<_ACEOF
@@ -15555,7 +15556,7 @@ _ACEOF
 
 
 # If we don't have largefile support, can't handle segsize >= 2GB.
-if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize" != "1"; then
+if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize_mb" -gt "1024"; then
    as_fn_error $? "Large file support is not enabled. Segment size cannot be larger than 1GB." "$LINENO" 5
 fi
 
diff --git a/configure.ac b/configure.ac
index f76b7ee31fc..6abefa0de58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -286,14 +286,14 @@ AC_DEFINE_UNQUOTED([BLCKSZ], ${BLCKSZ}, [
 # Relation segment size
 #
 AC_MSG_CHECKING([for segment size])
-PGAC_ARG_REQ(with, segsize, [SEGSIZE], [set table segment size in GB [1]],
-             [segsize=$withval],
-             [segsize=1])
+PGAC_ARG_REQ(with, segsize-mb, [SEGSIZE], [set table segment size in MB [1024]],
+             [segsize_mb=$withval],
+             [segsize_mb=1024])
 # this expression is set up to avoid unnecessary integer overflow
 # blocksize is already guaranteed to be a factor of 1024
-RELSEG_SIZE=`expr '(' 1024 / ${blocksize} ')' '*' ${segsize} '*' 1024`
+RELSEG_SIZE=`expr '(' 1024 / ${blocksize} ')' '*' ${segsize_mb}`
 test $? -eq 0 || exit 1
-AC_MSG_RESULT([${segsize}GB])
+AC_MSG_RESULT([${segsize_mb}MB])
 
 AC_DEFINE_UNQUOTED([RELSEG_SIZE], ${RELSEG_SIZE}, [
  RELSEG_SIZE is the maximum number of blocks allowed in one disk file.
@@ -1737,7 +1737,7 @@ dnl Check for largefile support (must be after AC_SYS_LARGEFILE)
 AC_CHECK_SIZEOF([off_t])
 
 # If we don't have largefile support, can't handle segsize >= 2GB.
-if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize" != "1"; then
+if test "$ac_cv_sizeof_off_t" -lt 8 -a "$segsize_mb" -gt "1024"; then
    AC_MSG_ERROR([Large file support is not enabled. Segment size cannot be larger than 1GB.])
 fi
 
diff --git a/meson.build b/meson.build
index ce2f223a409..eb242d24665 100644
--- a/meson.build
+++ b/meson.build
@@ -418,7 +418,9 @@ meson_bin = find_program(meson_binpath, native: true)
 
 cdata.set('USE_ASSERT_CHECKING', get_option('cassert') ? 1 : false)
 
-cdata.set('BLCKSZ', get_option('blocksize').to_int() * 1024, description:
+blocksize = get_option('blocksize').to_int() * 1024
+segsize = (get_option('segsize_mb') * 1024 * 1024) / blocksize
+cdata.set('BLCKSZ', blocksize, description:
 '''Size of a disk block --- this also limits the size of a tuple. You can set
    it bigger if you need bigger tuples (although TOAST should reduce the need
    to have large tuples, since fields can be spread across multiple tuples).
@@ -428,7 +430,7 @@ cdata.set('BLCKSZ', get_option('blocksize').to_int() * 1024, description:
    Changing BLCKSZ requires an initdb.''')
 
 cdata.set('XLOG_BLCKSZ', get_option('wal_blocksize').to_int() * 1024)
-cdata.set('RELSEG_SIZE', get_option('segsize') * 131072)
+cdata.set('RELSEG_SIZE', segsize)
 cdata.set('DEF_PGPORT', get_option('pgport'))
 cdata.set_quoted('DEF_PGPORT_STR', get_option('pgport').to_string())
 cdata.set_quoted('PG_KRB_SRVNAM', get_option('krb_srvnam'))
diff --git a/meson_options.txt b/meson_options.txt
index c7ea57994dc..b0bd3f4cbe8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -10,8 +10,8 @@ option('wal_blocksize', type : 'combo',
   value: '8',
   description : '''WAL block size, in kilobytes''')
 
-option('segsize', type : 'integer', value : 1,
-  description : '''Segment size, in gigabytes''')
+option('segsize_mb', type : 'integer', value : 1024,
+  description : '''Segment size, in megabytes''')
 
 
 # Miscellaneous options
-- 
2.38.0

Reply via email to