#!/bin/bash -f
#
# Calculate memory parameters for PostgreSQL-8.4 on Linux.
#
#    This program calculate sample values of "shared_buffers" and so on.
#  in $PGDATA/postgresql.conf for your Linux environment according to your
#  Linux configurated parameters.
#
# Author: Jun Kuwamura
# Creation: 2001-04-11
#	originary for "sort_mem" and "shared_buffers" with postgresql-7.1
# History:
#   2005-11-15 juk	modified for postgresql-8.1
#
  bug_report_to="juk@aries.linet.jp"
#
CMDNAME=`basename $0`

### postgresql.conf Defaults ###
#
# - Connection -
#max_connections = 100                  # 1-1024
max_connections=32
# note: increasing max_connections costs ~400 bytes of shared memory per 
# connection slot, plus lock space (see max_locks_per_transaction).  You
# might also need to raise shared_buffers to support more connections.
#
# - Memory -
#shared_buffers = 1000                  # min 16 or max_connections*2, 8KB each
#temp_buffers = 1000                    # min 100, 8KB each
#max_prepared_transactions = 5          # can be 0 or more
# note: increasing max_prepared_transactions costs ~600 bytes of shared memory
# per transaction slot, plus lock space (see max_locks_per_transaction).
max_prepared_transactions=5
#work_mem = 1024                        # min 64, size in KB
#maintenance_work_mem = 16384           # min 1024, size in KB
#max_stack_depth = 2048                 # min 100, size in KB
#
# - Lock -
#max_locks_per_transaction = 64         # min 10
# note: each lock table slot uses ~220 bytes of shared memory, and there are
# max_locks_per_transaction * (max_connections + max_prepared_transactions)
max_locks_per_transaction=64
#
# - Background writer -
#bgwriter_lru_percent = 1.0             # 0-100% of LRU buffers scanned/round
#bgwriter_lru_maxpages = 5              # 0-1000 buffers max written/round
#bgwriter_all_percent = 0.333           # 0-100% of all buffers scanned/round
#bgwriter_all_maxpages = 5              # 0-1000 buffers max written/round
#
# - WAL -
#wal_buffers = 8                        # min 4, 8KB each
wal_buffers=1		# [MB]
wal_sync_method="open_sync"
#
# - Checkpoints -
#checkpoint_segments = 3                # in logfile segments, min 1, 16MB each
checkpoint_segments=15
checkpoint_completion_target=0.9
#
###

# set default and parameter
denominator=2
denominator_main=8

help="\
$CMDNAME: Calculate memory parameters for PostgreSQL-8.4

Usage:
    $CMDNAME [-n max_connections]

				[default $max_connections]

Report bugs to <$bug_report_to>." 
advice="\
Try '$CMDNAME --help' for more information."


while [ "$#" -gt 0 ]
do
    case $1 in
        -h|--help|-\?)
            echo "$help"
            exit 0
            ;;
        -n|--max_connections)
            max_connections=$2
            shift
            ;;
        *)
            echo "$CMDNAME: invalid option or parameter: $1" 1>&2
            echo "$advice" 1>&2
            exit 1
            ;;
    esac
    shift
done

if [ $max_connections -lt 1 -o $max_connections -gt 1024 ]; then
	echo "max_connections must be between 1 and 1024"
	exit
fi


core_mem=`free | grep Mem: | awk '{print $2}'`
effective_cache_size=`expr $core_mem / 2 / 1024`	# [MB]
work_mem=`expr $core_mem / $denominator_main / $max_connections`
maintenance_work_mem=`expr $work_mem \* $max_connections / 1024`	# [kB]


x=`expr $max_connections + $max_prepared_transactions`
shmwaste=`expr $max_locks_per_transaction \* $x \* 200`
shmwaste=`expr $shmwaste + $max_connections \* 400`
shmwaste=`expr $shmwaste + $max_prepared_transactions \* 600`
shm_waste=`expr $shmwaste / 1024`
#echo "shared memory waseted = $shm_waste"

# Calculate number of shared buffers
shm_max_bytes=`cat /proc/sys/kernel/shmmax`
shm_max=`expr $shm_max_bytes / 1024 - $shm_waste`	# unit: [k] bytes
shared_buffers=`expr $shm_max / $denominator / 1024`	# [MB]

# check minimum number of buffers
shared_buffers_min=`expr $max_connections \* 2`
if [ $shared_buffers -lt $shared_buffers_min ]; then
	shared_buffers=$shared_buffers_min
fi

# Output results
echo "max_connections = $max_connections"
echo "work_mem = $work_mem"kB
echo "maintenance_work_mem = $maintenance_work_mem"kB
echo "shared_buffers = $shared_buffers"MB
echo "wal_buffers = $wal_buffers"MB
echo "wal_sync_method = $wal_sync_method"
echo "effective_cache_size = $effective_cache_size"MB
echo "checkpoint_segments = $checkpoint_segments"
echo "checkpoint_completion_target = $checkpoint_completion_target"
