Revert "Replace random() with pg_prng random function."
authorTatsuo Ishii <ishii@postgresql.org>
Tue, 27 May 2025 10:19:57 +0000 (19:19 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Tue, 27 May 2025 10:19:57 +0000 (19:19 +0900)
This reverts commit 66fcd561d74c8f00326bad94300053bd7ea13566.

It was accidentally committed.

src/Makefile.am
src/include/pool_type.h
src/main/pgpool_main.c
src/pcp_con/pcp_worker.c
src/protocol/child.c
src/protocol/pool_pg_utils.c
src/utils/pg_prng.c [deleted file]

index 56f4121c4ddd990ae72e111a18c7e96d97750387..efc11cb68ffd63a6437a23f07b1bf8758e169b07 100644 (file)
@@ -66,8 +66,7 @@ pgpool_SOURCES = main/main.c \
        utils/pool_health_check_stats.c \
        utils/psqlscan.l \
        utils/pgstrcasecmp.c \
-       utils/pg_strong_random.c \
-       utils/pg_prng.c
+       utils/pg_strong_random.c
 
 utils/psqlscan.c: utils/psqlscan.l
        $(LEX) -o'utils/psqlscan.c' $<
index 03eac9bb43bf8d17d4a0190d32c3b4a96ee2c998..43f29a595abff8f7883b7c6e0087a518fa7e30ff 100644 (file)
@@ -6,7 +6,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2025     PgPool Global Development Group
+ * Copyright (c) 2003-2015     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -222,12 +222,6 @@ typedef uint8 bits8;                       /* >= 8 bits */
 typedef uint16 bits16;                 /* >= 16 bits */
 typedef uint32 bits32;                 /* >= 32 bits */
 
-/*
- * 64-bit integers
- */
-#define INT64CONST(x)  INT64_C(x)
-#define UINT64CONST(x) UINT64_C(x)
-
 /*
  * stdint.h limits aren't guaranteed to be present and aren't guaranteed to
  * have compatible types with our fixed width types. So just define our own.
index 25298eb871ab60397382d4f5455a4747813a765c..d74cf12b2d2cc1e33a8cb6a77f27789461699ddf 100644 (file)
@@ -210,6 +210,8 @@ volatile    User1SignalSlot *user1SignalSlot = NULL;        /* User 1 signal slot on
                                                                                                                 * shmem */
 int            current_child_process_count;
 
+struct timeval random_start_time;
+
 /*
  * To track health check process ids
  */
@@ -301,6 +303,9 @@ PgpoolMain(bool discard_status, bool clear_memcache_oidmaps)
         */
        volatile bool first = true;
 
+       /* For PostmasterRandom */
+       gettimeofday(&random_start_time, NULL);
+
        processState = INITIALIZING;
 
        /*
index a5b88a898c75bfa5d78f9fdff5f5acec3183e0c9..de2658d5e2b657b75c37ecd3025fdaae4956d7e9 100644 (file)
@@ -4,7 +4,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2025     PgPool Global Development Group
+ * Copyright (c) 2003-2024     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -112,6 +112,7 @@ pcp_worker_main(int port)
 
        char            salt[4];
        int                     random_salt = 0;
+       struct timeval uptime;
        char            tos;
        int                     rsize;
 
@@ -121,6 +122,9 @@ pcp_worker_main(int port)
        /* Identify myself via ps */
        init_ps_display("", "", "", "");
 
+       gettimeofday(&uptime, NULL);
+       srandom((unsigned int) (getpid() ^ uptime.tv_usec));
+
        /* set up signal handlers */
        signal(SIGTERM, die);
        signal(SIGINT, die);
index 17585bb791bab3ba58cba944874ec8e2511f76a0..53a4cce68dcebc021840f70f9b953d49ca83d488 100644 (file)
@@ -5,7 +5,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2025     PgPool Global Development Group
+ * Copyright (c) 2003-2024     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -49,7 +49,6 @@
 #include "pool_config_variables.h"
 #include "utils/palloc.h"
 #include "utils/memutils.h"
-#include "utils/pg_prng.h"
 #include "utils/pool_ssl.h"
 #include "utils/pool_ipc.h"
 #include "utils/pool_relcache.h"
@@ -102,9 +101,6 @@ static int opt_sort(const void *a, const void *b);
 
 static bool unix_fds_not_isset(int* fds, int num_unix_fds, fd_set* opt);
 
-static void initialize_prng(void);
-static TimestampTz GetCurrentTimestamp(void);
-
 /*
  * Non 0 means SIGTERM (smart shutdown) or SIGINT (fast shutdown) has arrived
  */
@@ -149,12 +145,6 @@ bool               stop_now = false;
  */
 static bool connection_pool_initialized = false;
 
-/*
- * prng state
- */
-pg_prng_state prng_state_d;
-pg_prng_state *prng_state;
-
 /*
 * child main loop
 */
@@ -163,6 +153,8 @@ do_child(int *fds)
 {
        sigjmp_buf      local_sigjmp_buf;
        POOL_CONNECTION_POOL *volatile backend = NULL;
+       struct timeval now;
+       struct timezone tz;
 
        /* counter for child_max_connections.  "volatile" declaration is necessary
         * so that this is counted up even if long jump is issued due to
@@ -223,8 +215,13 @@ do_child(int *fds)
        pool_init_process_context();
 
        /* initialize random seed */
-       prng_state = &prng_state_d;
-       initialize_prng();
+       gettimeofday(&now, &tz);
+
+#if defined(sun) || defined(__sun)
+       srand((unsigned int) now.tv_usec);
+#else
+       srandom((unsigned int) now.tv_usec);
+#endif
 
        /* initialize connection pool */
        if (pool_init_cp())
@@ -2222,55 +2219,3 @@ set_process_status(ProcessStatus status)
 {
        pool_get_my_process_info()->status = status;
 }
-
-/*
- * imported from backend/utils/adt/timestamp.c
- */
-/*
- * GetCurrentTimestamp -- get the current operating system time
- *
- * Result is in the form of a TimestampTz value, and is expressed to the
- * full precision of the gettimeofday() syscall
- */
-static TimestampTz
-GetCurrentTimestamp(void)
-{
-       TimestampTz result;
-       struct timeval tp;
-
-       gettimeofday(&tp, NULL);
-
-       result = (TimestampTz) tp.tv_sec -
-               ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
-       result = (result * USECS_PER_SEC) + tp.tv_usec;
-
-       return result;
-}
-
-/*
- * imported from backend/utils/adt/pseudorandomfuncs.c
- * and modified.
- */
-/*
- * initialize_prng() -
- *
- *     Initialize (seed) the PRNG, if not done yet in this process.
- */
-static void
-initialize_prng(void)
-{
-       /*
-        * If possible, seed the PRNG using high-quality random bits. Should
-        * that fail for some reason, we fall back on a lower-quality seed
-        * based on current time and PID.
-        */
-       if (!pg_prng_strong_seed(prng_state))
-       {
-               TimestampTz now = GetCurrentTimestamp();
-               uint64          iseed;
-
-               /* Mix the PID with the most predictable bits of the timestamp */
-               iseed = (uint64) now ^ ((uint64) getpid() << 32);
-               pg_prng_seed(prng_state, iseed);
-       }
-}
index 7f06628aabfc380885dbdb86a58a884ba7919f64..25942b6cc0c2a0d6dc2d36f6cf8def7b0aa7de61 100644 (file)
@@ -3,7 +3,7 @@
  * pgpool: a language independent connection pool server for PostgreSQL
  * written by Tatsuo Ishii
  *
- * Copyright (c) 2003-2025     PgPool Global Development Group
+ * Copyright (c) 2003-2020     PgPool Global Development Group
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby
@@ -28,7 +28,6 @@
 #include "protocol/pool_connection_pool.h"
 #include "utils/palloc.h"
 #include "utils/memutils.h"
-#include "utils/pg_prng.h"
 #include "utils/pool_ipc.h"
 #include "utils/pool_stream.h"
 #include "utils/pool_ssl.h"
@@ -45,8 +44,6 @@ static void free_persistent_db_connection_memory(POOL_CONNECTION_POOL_SLOT * cp)
 static void si_enter_critical_region(void);
 static void si_leave_critical_region(void);
 
-extern pg_prng_state *prng_state;
-
 /*
  * create a persistent connection
  */
@@ -327,8 +324,11 @@ select_load_balancing_node(void)
         */
        int                     suggested_node_id = -2;
 
-       r = pg_prng_double(prng_state);
-//     elog(LOG, "pg_prng_double: %f", r);
+#if defined(sun) || defined(__sun)
+       r = (((double) rand()) / RAND_MAX);
+#else
+       r = (((double) random()) / RAND_MAX);
+#endif
 
        /*
         * Check user_redirect_preference_list
@@ -490,7 +490,11 @@ select_load_balancing_node(void)
                                }
                        }
 
-                       r = pg_prng_double(prng_state) * total_weight;
+#if defined(sun) || defined(__sun)
+                       r = (((double) rand()) / RAND_MAX) * total_weight;
+#else
+                       r = (((double) random()) / RAND_MAX) * total_weight;
+#endif
 
                        selected_slot = PRIMARY_NODE_ID;
                        total_weight = 0.0;
@@ -569,7 +573,11 @@ select_load_balancing_node(void)
                }
        }
 
-       r = pg_prng_double(prng_state) * total_weight;
+#if defined(sun) || defined(__sun)
+       r = (((double) rand()) / RAND_MAX) * total_weight;
+#else
+       r = (((double) random()) / RAND_MAX) * total_weight;
+#endif
 
        total_weight = 0.0;
        for (i = 0; i < NUM_BACKENDS; i++)
@@ -634,7 +642,11 @@ select_load_balancing_node(void)
                        }
                }
 
-               r = pg_prng_double(prng_state) * total_weight;
+#if defined(sun) || defined(__sun)
+               r = (((double) rand()) / RAND_MAX) * total_weight;
+#else
+               r = (((double) random()) / RAND_MAX) * total_weight;
+#endif
 
                selected_slot = PRIMARY_NODE_ID;
 
diff --git a/src/utils/pg_prng.c b/src/utils/pg_prng.c
deleted file mode 100644 (file)
index 7ca3ab0..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * This file was imported from PostgreSQL source code
- * (src/common/pg_prng.c).
- */
-
-/*-------------------------------------------------------------------------
- *
- * Pseudo-Random Number Generator
- *
- * We use Blackman and Vigna's xoroshiro128** 1.0 algorithm
- * to have a small, fast PRNG suitable for generating reasonably
- * good-quality 64-bit data.  This should not be considered
- * cryptographically strong, however.
- *
- * About these generators: https://prng.di.unimi.it/
- * See also https://en.wikipedia.org/wiki/List_of_random_number_generators
- *
- * Portions Copyright (c) 2025, PgPool Global Development Group
- * Portions Copyright (c) 2021-2025, PostgreSQL Global Development Group
- *
- * src/common/pg_prng.c
- *
- *-------------------------------------------------------------------------
- */
-
-#include "pool.h"
-
-#include <math.h>
-
-#include "utils/pg_prng.h"
-
-/* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-
-/* process-wide state vector */
-pg_prng_state pg_global_prng_state;
-
-/* ignore likely/unlikely */
-#define        likely
-#define unlikely
-
-/*
- * 64-bit rotate left
- */
-static inline uint64
-rotl(uint64 x, int bits)
-{
-       return (x << bits) | (x >> (64 - bits));
-}
-
-/*
- * The basic xoroshiro128** algorithm.
- * Generates and returns a 64-bit uniformly distributed number,
- * updating the state vector for next time.
- *
- * Note: the state vector must not be all-zeroes, as that is a fixed point.
- */
-static uint64
-xoroshiro128ss(pg_prng_state *state)
-{
-       uint64          s0 = state->s0,
-                               sx = state->s1 ^ s0,
-                               val = rotl(s0 * 5, 7) * 9;
-
-       /* update state */
-       state->s0 = rotl(s0, 24) ^ sx ^ (sx << 16);
-       state->s1 = rotl(sx, 37);
-
-       return val;
-}
-
-/*
- * We use this generator just to fill the xoroshiro128** state vector
- * from a 64-bit seed.
- */
-static uint64
-splitmix64(uint64 *state)
-{
-       /* state update */
-       uint64          val = (*state += UINT64CONST(0x9E3779B97f4A7C15));
-
-       /* value extraction */
-       val = (val ^ (val >> 30)) * UINT64CONST(0xBF58476D1CE4E5B9);
-       val = (val ^ (val >> 27)) * UINT64CONST(0x94D049BB133111EB);
-
-       return val ^ (val >> 31);
-}
-
-/*
- * Initialize the PRNG state from a 64-bit integer,
- * taking care that we don't produce all-zeroes.
- */
-void
-pg_prng_seed(pg_prng_state *state, uint64 seed)
-{
-       state->s0 = splitmix64(&seed);
-       state->s1 = splitmix64(&seed);
-       /* Let's just make sure we didn't get all-zeroes */
-       (void) pg_prng_seed_check(state);
-}
-
-/*
- * Initialize the PRNG state from a double in the range [-1.0, 1.0],
- * taking care that we don't produce all-zeroes.
- */
-void
-pg_prng_fseed(pg_prng_state *state, double fseed)
-{
-       /* Assume there's about 52 mantissa bits; the sign contributes too. */
-       int64           seed = ((double) ((UINT64CONST(1) << 52) - 1)) * fseed;
-
-       pg_prng_seed(state, (uint64) seed);
-}
-
-/*
- * Validate a PRNG seed value.
- */
-bool
-pg_prng_seed_check(pg_prng_state *state)
-{
-       /*
-        * If the seeding mechanism chanced to produce all-zeroes, insert
-        * something nonzero.  Anything would do; use Knuth's LCG parameters.
-        */
-       if (unlikely(state->s0 == 0 && state->s1 == 0))
-       {
-               state->s0 = UINT64CONST(0x5851F42D4C957F2D);
-               state->s1 = UINT64CONST(0x14057B7EF767814F);
-       }
-
-       /* As a convenience for the pg_prng_strong_seed macro, return true */
-       return true;
-}
-
-/*
- * Select a random uint64 uniformly from the range [0, PG_UINT64_MAX].
- */
-uint64
-pg_prng_uint64(pg_prng_state *state)
-{
-       return xoroshiro128ss(state);
-}
-
-/*
- * We ignore some functions because we do not port pg_bitutils.c (yet).
- */
-#ifdef NOT_USED
-/*
- * Select a random uint64 uniformly from the range [rmin, rmax].
- * If the range is empty, rmin is always produced.
- */
-uint64
-pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
-{
-       uint64          val;
-
-       if (likely(rmax > rmin))
-       {
-               /*
-                * Use bitmask rejection method to generate an offset in 0..range.
-                * Each generated val is less than twice "range", so on average we
-                * should not have to iterate more than twice.
-                */
-               uint64          range = rmax - rmin;
-               uint32          rshift = 63 - pg_leftmost_one_pos64(range);
-
-               do
-               {
-                       val = xoroshiro128ss(state) >> rshift;
-               } while (val > range);
-       }
-       else
-               val = 0;
-
-       return rmin + val;
-}
-
-/*
- * Select a random int64 uniformly from the range [PG_INT64_MIN, PG_INT64_MAX].
- */
-int64
-pg_prng_int64(pg_prng_state *state)
-{
-       return (int64) xoroshiro128ss(state);
-}
-#endif
-
-/*
- * Select a random int64 uniformly from the range [0, PG_INT64_MAX].
- */
-int64
-pg_prng_int64p(pg_prng_state *state)
-{
-       return (int64) (xoroshiro128ss(state) & UINT64CONST(0x7FFFFFFFFFFFFFFF));
-}
-
-#ifdef NOT_USED
-/*
- * Select a random int64 uniformly from the range [rmin, rmax].
- * If the range is empty, rmin is always produced.
- */
-int64
-pg_prng_int64_range(pg_prng_state *state, int64 rmin, int64 rmax)
-{
-       int64           val;
-
-       if (likely(rmax > rmin))
-       {
-               uint64          uval;
-
-               /*
-                * Use pg_prng_uint64_range().  Can't simply pass it rmin and rmax,
-                * since (uint64) rmin will be larger than (uint64) rmax if rmin < 0.
-                */
-               uval = (uint64) rmin +
-                       pg_prng_uint64_range(state, 0, (uint64) rmax - (uint64) rmin);
-
-               /*
-                * Safely convert back to int64, avoiding implementation-defined
-                * behavior for values larger than PG_INT64_MAX.  Modern compilers
-                * will reduce this to a simple assignment.
-                */
-               if (uval > PG_INT64_MAX)
-                       val = (int64) (uval - PG_INT64_MIN) + PG_INT64_MIN;
-               else
-                       val = (int64) uval;
-       }
-       else
-               val = rmin;
-
-       return val;
-}
-#endif
-
-/*
- * Select a random uint32 uniformly from the range [0, PG_UINT32_MAX].
- */
-uint32
-pg_prng_uint32(pg_prng_state *state)
-{
-       /*
-        * Although xoroshiro128** is not known to have any weaknesses in
-        * randomness of low-order bits, we prefer to use the upper bits of its
-        * result here and below.
-        */
-       uint64          v = xoroshiro128ss(state);
-
-       return (uint32) (v >> 32);
-}
-
-/*
- * Select a random int32 uniformly from the range [PG_INT32_MIN, PG_INT32_MAX].
- */
-int32
-pg_prng_int32(pg_prng_state *state)
-{
-       uint64          v = xoroshiro128ss(state);
-
-       return (int32) (v >> 32);
-}
-
-/*
- * Select a random int32 uniformly from the range [0, PG_INT32_MAX].
- */
-int32
-pg_prng_int32p(pg_prng_state *state)
-{
-       uint64          v = xoroshiro128ss(state);
-
-       return (int32) (v >> 33);
-}
-
-/*
- * Select a random double uniformly from the range [0.0, 1.0).
- *
- * Note: if you want a result in the range (0.0, 1.0], the standard way
- * to get that is "1.0 - pg_prng_double(state)".
- */
-double
-pg_prng_double(pg_prng_state *state)
-{
-       uint64          v = xoroshiro128ss(state);
-
-       /*
-        * As above, assume there's 52 mantissa bits in a double.  This result
-        * could round to 1.0 if double's precision is less than that; but we
-        * assume IEEE float arithmetic elsewhere in Postgres, so this seems OK.
-        */
-       return ldexp((double) (v >> (64 - 52)), -52);
-}
-
-/*
- * Select a random double from the normal distribution with
- * mean = 0.0 and stddev = 1.0.
- *
- * To get a result from a different normal distribution use
- *   STDDEV * pg_prng_double_normal() + MEAN
- *
- * Uses https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
- */
-double
-pg_prng_double_normal(pg_prng_state *state)
-{
-       double          u1,
-                               u2,
-                               z0;
-
-       /*
-        * pg_prng_double generates [0, 1), but for the basic version of the
-        * Box-Muller transform the two uniformly distributed random numbers are
-        * expected to be in (0, 1]; in particular we'd better not compute log(0).
-        */
-       u1 = 1.0 - pg_prng_double(state);
-       u2 = 1.0 - pg_prng_double(state);
-
-       /* Apply Box-Muller transform to get one normal-valued output */
-       z0 = sqrt(-2.0 * log(u1)) * sin(2.0 * M_PI * u2);
-       return z0;
-}
-
-/*
- * Select a random boolean value.
- */
-bool
-pg_prng_bool(pg_prng_state *state)
-{
-       uint64          v = xoroshiro128ss(state);
-
-       return (bool) (v >> 63);
-}