PostgreSQL
Notes - LinuxCBT Tutorial
psql
Features include
command history
tab completion
commands terminate with semicolons
psql --version
prints on the terminal the current version of PostgreSQLpsql -l
lists all the available databases and exitspsql -U
lets you specify the username (defaults to currently-logged-in user)psql -f <FILENAME>
executes commands from an external filePostgreSQL installs 3 default DBs
postgres
- contain user accounts, statistics, and other thingstemplate0
- original DBtemplate1
- (possibly extended) copy of template0, used to generate new DBs
psql
without any arguments enters the interactive mode:\h
returns a SQL-specific help (\h COMMAND
will give you documentation for that command)\?
returns PSQL-specific help\l
lists all the DBs (\l+
returns more information)\du
returns list of users in system (\du+
for more information)\!
launches a shell inside sql (\! COMMAND
will execute the command onto a shell)\i FILE
executes commands (SQL and sql) from an external file\c DBNAME
connect to different DB \q quits the database
Access Control
You can configure users and roles (roles are really users)
The configuration files involved with the access control are
pg_hba.conf
,postgresql.conf
, andpg_ident.conf
(much less than the other two)Accounts are shared among all DBs in PostgreSQL
Default setup includes 1 superuser called
postgres
Privileges are managed with:
GRANT | REVOKE
ALTER
CREATE | DROP ROLE|USER
The creator of a DB object is its owner, and can assign privileges
To change the ownership of a DB object, we use the
ALTER
SQL commandThe special
PUBLIC
role assigns privileges to ALL system users\password <USERNAME>
allows to specify a password for the userBy default, psql tries to connect to a DB with the same name as the username trying to log in
The postgres user cannot be removed from the system
Default configuration does not allow remote login, because it is not specified in the
pg_hba.conf
file
Log Configuration
PostgreSQL supports three kinds of logging:
stderr - the default
csvlog - import into spreadsheets or DBs for post-processing
syslog
We can write to all these logs simultaneously
The config file responsible for setting up the log system is
postgresql.conf
(which can be read without root privileges)Automatic log rotation is included, based on age or size
The logs are stored in
%POSTGRESROOT/data/pg_log
Each time you (re)start PostgreSQL, it generates a new log file
Syslog is based on UDP, and so is prone to message loss
Data Types
Data types work on a per-column basis
Types include:
Numeric:
smallint -16 bits, whole numbers
int - 32 bits, whole numbers
bigint - 64 bits, whole numbers
numeric - with precision and scale
real - 32 bits, variable with max 6 decimal digits
double precision - 64 bytes, variable with max 15 decimal digits
serial - 4 bytes, auto-incrementing
bigserial - 8 bytes, auto-incrementing
Money:
money - 8 bytes
Strings:
text - unlimited, varchar, preferred character storage in PostgreSQL
char(n) - fixed-length, blank-padded if < 'n' length, truncated if > 'n' length
char - equivalent to char(1), 1-character field
varchar(n) - variable length, no padding, with 'n' limit
varchar - variable length without any limits
Dates & Times (uses Julian Dates):
date - 32-bits, dates only
time - 64-bits, defaults to time without time zone, microsecond precision
time with time zone - 96-bits, date & time with time zone, microsecond precision
timestamp with time zone - 64-bits
timestamp without time zone - 64-bits
interval - 96-bits, range of time, microsecond precision
Boolean:
boolean - 8-bits, True (1)(on) or False (0)(off)
Network addresses:
cidr - 7 or 19-bytes, IPv4 or IPv6 networks
inet - 7 or 19-bytes, IPv4 or IPv6 hosts and networks
macaddr - 48-bits
XML
Arrays
CREATE Objects
Definition of objects is limited to 63 characters
Identifiers MUST begin with alpha character
Allows to create DBs, tables, schemas, indexes, functions, etc.
The PostgreSQL hierarchy goes like:
DataBase
Schema(s) (optional, default schema is 'public')
Objects (tables, functions, triggers, etc.)
All DBs have the
public
andpg_catalog
schemasAll users (and roles) have the CREATE and USAGE access to the
public
schema for ALL DBs
DROP Objects
Removes objects (DBs, schemas, tables, functions, triggers, etc.)
Objects currently in use will NOT be dropped by default
Dropping DBs will drop all the sub-objects, including schemas, tables, functions, etc.
No active sessions must be ongoing while creating a database from a template
Objects created with the
public
schema are not readily available without using the GRANT commandDROP <type> <name> CASCADE
will drop all the objects that are dependent on the<name>
object
ALTER Objects
Allows changes to objects (DBs, schemas, tables, ecc.), especially name, structure, owner
ALTER DATABASE <old name> RENAME TO <new name>
will change ONLY the name (not the structure, not anything else) ofold name
intonew name
ALTER should be used without connections to the objects which is being altered
ALTER DATABASE <database name> OWNER TO <new owner>
will change the ownership of thedatabase name
DB tonew owner
(which can also be a role)ALTER TABLE <old name> RENAME TO <new name>
will change ONLY the name of the table, leaving untouched the schema or the structureALTER TABLE <table name> ALTER COLUMN <column name> SET DATA TYPE <new type>
will change the structure of the table (may result in data loss if target column does NOT support target data)ALTER TABLE <table name> ADD <column name> <column type>
will add a new column with a given data typeColumn names MUST be unique and cannot be added more than once
ALTER TABLE <table name> DROP COLUMN IF EXISTS <column name>
will remove the column (and all the existing data)ALTER ROLE <user name> SUPERUSER
will make the user as a superuser (with all privileges)ALTER ROLE <old name> RENAME TO <new name>
will change the name of the user (or the role), while clearing the MD5 hash of the password (which would then need to be reset) and updating all the ownerships of objects
Constraints Usage
Enforce storage requirements per table or per column
Data types work as a basic constraint for value of columns
CREATE TABLE messages (date date NOT NULL)
will create the table messages where the date column must always be specified when adding a new rowMultiple constraints can be bound to a single column
Default column rule is to accept NULL values
The
UNIQUE
constraint applies to any type of column, and requires that all the values in that column must be uniqueThe creation of
UNIQUE
constraints cause PostgreSQL to automatically create a b-tree index on that columnIf we declare as
UNIQUE
a list of columns (like inCREATE TABLE messages (date date, id bigint, message text, UNIQUE(id, message)
), the value contained in those columns can be repeated, but the combination of values cannot and must be uniquePRIMARY KEY
constraint is a combination of theUNIQUE
andNOT NULL
constraintsThere can only be ONE primary key per table
Standard SQL recommends that each table contains a primary key
The
FOREIGN KEY
constraint links tables with other tablesCREATE TABLE messagesCategories (id int REFERENCES messages(id), category text)
will create a foreign key constraint, so that the ids in the messagesCategories table must reflect values from the id column in the messages tableThe
CHECK
constraint confirms column values based on some boolean criteriaCREATE TABLE messages (date date NOT NULL, id numeric CHECK(id > 0))
will store in the table only rows for which the id is positiveCREATE TABLE message (data date NOT NULL. id numeric CONSTRAINT positive_id CHECK(id > 0))
allows to specify a name for the constraint; if no name is specified, PostgreSQL will auto-generate a name for you
INSERT Usage
INSERT
allows us to populate our tablesINSERT INTO <table name> VALUES ('2010-04-10', '1')
will require that the statement contains all the column values in orderPostgreSQL inserts values left-to-right
Rows that violate
CHECK
statement or other constraint will not be addedINSERT INTO <table name> (<column name>) VALUES(<value>)
will insert in a new row only the column which has been specifiedINSERT INTO <table name> VALUES (<first row>), (<second row>), (<third row>)
will insert more than one record at a single timeWhile inserting multiple rows, one error in one row will prevent ALL the records in the statement to be added, not only the one which generates the problem.
Foreign key need not to be based on a numeric field
COPY Usage
It's a server-side command, different from the client-side
\copy
commandAllows wholesale import/export of data from/to a file
The file MUST be on the server and readable by the postgres user
Uses absolute path for referencing the file
Defaults to importing based on the TAB separator
Does NOT work with views, but it will work with SELECTs of view
The TRUNCATE command deletes all the records from a table, but leaves the table structure untouched
COPY <table name> FROM <file abs path> DELIMITER '<delimiter>'
will populate<table name>
with the data contained in<file abs path>
COPY
will append the data at the end of the tableCOPY <table name> TO <filename> DELIMITED '<delimiter>'
will export<table name>
onto<filename>
using<delimiter>
as delimiterExporting to an existing file will clear its contents and then write the new data.
SELECT Usage
Allows you to retrieve information or perform queries against your database
SELECT * FROM <table name>
will give us all the rows from table nameSELECT <column1 name, column2 name, ..., columnN name> FROM <table name>
will create a view of table name in which only information fromcolumn1, column2, ..., columnN
are shownThe order of the columns in the resulting view will reflect the order we gave in the
SELECT
command (e.g.,column1, column2, ..., columnN
), even if in the original table the order is differentSELECT <column1 AS col1, column2 AS col2, ...> FROM <table name>
will create aliases for column names in the resulting viewSELECT * FROM <table name> WHERE <expression>
will return a view in which only rows that satisfy the expressionSELECT * FROM <table name> WHERE <column name> LIKE '%str%'
will return all the rows in table name for which the value of column names have a successful string comparison withstr
SELECT * FROM <table name> ORDER BY <column name> <ASC|DESC>
will order the results in the view by the values of column name in ascending (default) or descending orderSELECT DISTINCT <column name> FROM <table name>
will return a view in which only distinct (unique) values in column name are shownWe should use the
ORDER BY
clause when usingLIMIT
because SQL does not guarantee to maintain the original sort orderSELECT * FROM <table name> ORDER BY <column name> ASC LIMIT <no of records>
will return a view in which only the first no or records rows are displayedSELECT * FROM <table name> ORDER BY <column name> LIMIT <no of records> OFFSET <starting record>
will return a view with no of records rows after the first starting records
JOIN Usage
Aggregates related data across tables
The default join is called the CROSS JOIN, i.e. the cartesian product of the two or more tables
SELECT * FROM <table1>, <table2>, ...
will give us the cross join of the tablesSELECT * FROM <table1> AS t1, <table2> AS t2 WHERE t1.id = t2.id
will perform an INNER JOIN binded on the id column of the two tablesSELECT * FROM <table1> AS t1, <table2> AS t2, <table3> AS t3 WHERE t1.id = t2.id AND t1.id = t3.id
will join three different tables based on the common id valuesSELECT <col1>, <col2>, <col3> FROM <table1> AS t1, <table2> AS t2, <table3> AS t3 WHERE t1.id = t2.id AND t1.id = t3.id
will create a view in which only the selected columns are displayedSELECT * FROM <table1> AS t1 INNER JOIN <table2> ON t1.id = <table2>.id
is functionally equivalent to aJOIN
with aWHERE
clause, but it's more elegantSELECT * FROM <table1> AS t1 INNER JOIN <table2> USING (id)
is equivalent to the above query, but will not display the duplicate columnLEFT JOIN will match all the values on the left table and include only values from the right table that match
RIGHT JOIN will match all the values on the right table and include only values from the left table that match
VIEW Usage
Not a real object, it is a query that is executed upon invocation
They may be based on 1 or more tables
PostgreSQL supports temporary views (that last for session duration)
Column names are auto-derived from the query
CREATE VIEW <name> AS SELECT * FROM <table1> INNER JOIN <table2> USING (<col>)
will create a permanent view of the inner join of these two tablesWhen we will call
SELECT * FROM <name>
, PostgreSQL will execute the query on-the-fly and present us the resultSELECT id AS i, date AS d, category AS c FROM <name>
will alias the column names to i, d, and cCREATE OR REPLACE VIEW <name> (<alias1>, <alias2>, <alias3>) AS SELECT * FROM <table1> INNER JOIN <table2> USING (<col>)
will create (or update) a permanent view of the inner join of these two tablesCREATE TEMP VIEW <name> (<aliases...>) AS SELECT <cols...> FROM <tables...>
will create a temporary view, that will be dropped when the session endsTemporary view are not assigned to the standard
public
schema, but rather to thepg_temp_2
schema
Aggregate Functions
Compute single results (scalars) from multiple inputs (rows)
Values are computed after the
WHERE
clause (they cannot used within theWHERE
clause, but they can be used with theHAVING
clause)The
HAVING
clause is calculated after the computation done by the aggregate functionSELECT count(*) FROM messages
will return the number of rows in the messages tableSELECT sum(id) FROM messages
will return the sum of value from the id column (only works with numbers, obviously)SELECT avg(id) FROM messages
will return the average of the id valuesSELECT min(id) FROM messages
will find the minimum value among the idsSELECT max(id) FROM messages
will find the maximum value among the idsSELECT date, min(id) FROM messages GROUP BY date
will not work without theGROUP BY
clause, because we are referencing non-aggregated and aggregated columns in the same querySELECT date, min(id) FROM messages WHERE id < 51 GROUP BY date
will execute theWHERE
clause before theGROUP BY
clause, so it will restrict the aggregate function to rows for whichid < 51
SELECT date, min(id) FROM messages WHERE id < 51 GROUP BY date HAVING min(id) < 30
will perform the min function on the rows for which id is less than 50, group them by date, and the filter out the records for whichmin(id)
is equal or greater than 30SELECT bool_and(enabled) FROM messages
returns true if all the values are true (only works with booleans, obviously)SELECT bool_or(enabled) FROM messages
will perform the boolean or operation on the values contained in the enabled columnSELECT string_agg(message, ' ') FROM messages;
will concatenate all the (string) values with single space delimiter
UPDATE Usage
Updates table(s) based on criteria
Due to the PostgreSQL object-oriented philosophy, the
UPDATE
command will update tables and sub-tables (or parent tables) unless theONLY
keyword is specifiedThe output will tell us how many records have been affected by the change
UPDATE messages SET enabled=f WHERE id = 100
will set the enabled value of the row with id 100 to falseUPDATE messages SET enabled=f, message = 'new message' WHERE id >= 100
will update multiple columns simultaneouslyUPDATE messages SET enabled = DEFAULT
will reset all the rows (because theWHERE
clause is missing) to the default value of the enabled columnUPDATE messages SET enabled = DEFAULT RETURNING *
will output all the rows that were affected by the modification (PostgreSQL-specific keyword)UPDATE messages SET enabled = DEFAULT WHERE id >= 50 RETURNING enabled
will output the values of the enabled column that were affected by the change
DELETE Records
Removes entire records based on criteria
Does NOT remove individual columns, only entire records
Requires the table name, and preferable criteria (using the
WHERE
clause)It is a recursive operation (but you can use the ONLY clause to avoid affecting child tables)
DELETE FROM messages WHERE id = 103
removes a single record (if exists)DELETE FROM messages WHERE id = 103 RETURNING *
will return all the records that have just deletedJust one
DELETE
statement could make the whole transaction fail, i.e. not deleting any rows if just one failsDELETE FROM messages
deletes all rows from the messages table and all of its child tablesALTER TABLE messagescategories DROP CONSTRAINT IF EXISTS messagescategories_id_fkey
will drop the foreign key constraintIf you wish to delete all the records from a table,
TRUNCATE
is a better option with respect toDELETE
INDEX Usage
Speed up data retrieval and insertion
Without indices, SQL performs sequential table scans looking for data
It's convenient to create indices on columns that are frequently queried and/or joined
During the creation of an index, only read operations are allowed (to maintain consistency)
There is a max of 32 columns per index
EXPLAIN SELECT * FROM messages
will explain (and NOT execute) how the DB is going to execute the query (a query plan)ALTER TABLE messages ADD primary key (id)
will create a B-tree (the data structure that implements the index of that column)CREATE INDEX messages_id ON messages(messageid)
will create a new index on the table namedmessages
based on themessageid
column; if the index is formed by more than one column, their names must be divided by commasEXPLAIN ANALYZE <query>
will give you an estimate of the query plan, and then actually execute it and give back the running time\di messages
will display information about the indices on the messages tableDROP INDEX messages_id
will delete the whole indexWhen you add a primary key constraint on a column, SQL will automatically create an index for you
Built-in Functions
Are mostly mathematical or string functions
SELECT f(number|column) FROM messages
will apply the function f on the number or the values from the columns selectedMathematical functions are:
abs(n)
- absolute valuesqrt(n)
orcbrt(n)
- square or cubic rootceil(n)
orfloor(n)
- next highest or lowest integerdiv(n, m)
- divides n by m (return least integer)log(n)
- logarithm in base 10power(a, b)
- a to the power of brandom()
- random value between 0 and 1round(n)
- rounds up or down to the nearest integertrunc(n, m)
- truncate n with m decimal valuessin(n)
orcos(n)
- classic trigonometric functions
String functions are:
bit_length(str)
char_length(str)
lower(str)
upper(str)
initcap(str)
- will capitalize the first letter of each wordoverlay('test' placing 'xx' from 2)
- will return txxttrim(both ' ' from ' test ')
- trims only leading and trailing, not betweensubstring('test' from 2)
- will return stsplit_part(str, del, part)
- e.g. withsplit_part('syslog message', ' ', 2)
we'll havemessage
You can also have nested functions, e.g.
SELECT initcap(split_part(message, ' ', 2)) FROM messages LIMIT 10
Model Var Log
A single line of the
/var/log/messages
file contains:the timestamp (date and time)
the name of the host that submitted the message
the facility (the source of the message)
content of the message
To create a database that we can use to model the content of a
/var/log/messages
file, we can:create a
messages
table with the commandCREATE TABLE messages (mid BIGSERIAL PRIMARY KEY, mcatid smallint NOT NULL DEFAULT 1, mtime timestamp NOT NULL DEFAULT now(), mhost text NOT NULL DEFAULT 'Unknown Host', mfacility text NULL DEFAULT NULL, mmessage text NOT NULL DEFAULT 'NO MESSAGE')
check that the table was created successfully with the command
\d messages
test the insertion for a sample record with the command
INSERT INTO messages (mtime, mhost, mfacility, mmessage) VALUES (<date>, <hostname>, <facility_name>, <message>)
write a script for reading all the lines in
/var/log/messages
, and adapt them into a format suitable for bulk-loading into PostgreSQLbulk-load the records from the file with the command
COPY messages (mtime, mhost, mfacility, mmessage) FROM <path< DELIMITER ';'
create a category for joins with the command
INSERT INTO messagecategories VALUES ('1', 'NOTICE')
perform a join with the messagecategories table with the command
SELECT mtime, mhost, mfacility, messagecategories.name, mmessage FROM messages as m INNER JOIN messagecategories ON messagecategories.cid = m.catid
GRANT Usage
The
GRANT
command is available to grant privileges of all sorts:SELECT
- columns or tablesINSERT
- columns or tablesUPDATE
DELETE
- row-basedCREATE
CONNECT
(granted by default)EXECUTE
- functionsTRIGGER
USAGE
TEMPORARY
TRUNCATE
REFERENCES
The objects are owned by creators (owners and/or superusers), non-superuser do not have access to them (unless they are granted the privileges)
We can use the
\dp <obj_name>
to reveal privileges related to that objectUPDATE and DELETE privileges require SELECT privileges for criteria application
GRANT SELECT (<columns>) ON <obj_name> TO <role>
will grant theSELECT
privileges just on those columns. For setting the privileges to all columns, it is sufficientGRANT SELECT ON <obj_name>
GRANT INSERT ON <obj_name> TO <role>
will grant theINSERT
privileges on all columns of obj_nameGRANT USAGE ON <obj_name> TO <role>
will grant theUSAGE
privileges (useful for sequences of auto-generated values)UPDATE messages SET mfacility = 'kernel' WHERE mid = '204358' RETURNING *
will update the row for which theWHERE
clause applies, and will display the whole row (this command is specific to PostgreSQL)GRANT ALL ON <obj_name> TO <role>
will grant all privileges to role
REVOKE Privileges
REVOKE
is the converse ofGRANT
, and it's used to un-assign privilegesThe privileges are represented by a single letter, and have the following meanings:
a:
INSERT
(append)r:
SELECT
(read)w:
UPDATE
(write)d:
DELETE
D:
DROP
(truncate)x: references
t: triggers
U: usage
/user: permission issuer
REVOKE ALL on object[, object2, ..., objectN] FROM user
removes ALL privileges for user onobject
(andobject2, ..., objectN
)REVOKE INSERT on object[, object2, ..., objectN] FROM user
removes just theINSERT
privilege for user onobject
(andobject2, ..., objectN
). To revoke more than one privilege, the command isREVOKE privilege[, privilege2, ..., privilegeN] on object[, object2, ..., objectN] FROM user
The
INSERT
privilege may be granted/revoked independently fromSELECT
, unlike theUPDATE
andDELETE
ones (whereSELECT
is used to match the criteria specified with theWHERE
clause).GRANT ALL on object TO user WITH GRANT OPTION
will assign all the privileges to user on object, and also will enable him/her to hand over (GRANT
) these privileges to other users. This is represented by a*
after each of the privileges he/she has been granted.If we try to
REVOKE
some privileges to a user which hasGRANTED
the same privileges to some other user, theREVOKE
operation will fail, unless we specify theCASCADE
option.
DB Backup
It's mainly achieved by using
pg_dump
(for individual tables or DBs) orpg_dumpall
(for the full DBMS)Both commands operate on running DBs
The possible outputs of these commands are:
an SQL script, designed for full replay, to be used with the psql utility
an archive (only for
pg_dump
), designed to allow selective and/or reordered restores, to be used with thepg_restore
utility-Fp
(default): plain SQL script, uncompressed-Fc
: auto-compressed format, works only withpg_restore
-Ft
: tarball, not compressed, works with bothtar
andpg_restore
pg_dump postgres
- dumps the postgres DB to STDOUT (if you are able to authenticate)pg_dump -v -f DB_Backup_postgres postgres
- dumps the postgres DB to theDB_Backup_postgres
file, in verbose modepg_dump -v postgres > DB_Backup_postgres2
- dumps the postgres DB to theDB_Backup_postgres2
file, using output redirectionpg_dump -s -f DB_Backup.schema postgres
- dumps only the schema of the postgres database to theDB_Backup.schema
filepg_dump -t messages -t categories -f DB_Backup.messages.categories postgres
- dumps the messages and categories tables of the postgres database to theDB_Backup.messages.categories
filepg_dump -t 'messages*' -f DB_Backup.ALL_messages postgres
- dumps all the tables of the postgres whose name starts with messages database to theDB_Backup.ALL_messages
filepg_dump -Fc -f DB_Backup.compressed postgres
- dumps the postgres database in the compressed format into theDB_Backup.compressed
filepg_dump -Ft -f DB_Backup.postgres.tar postgres
- dumps the postgres database in the tar format into theDB_Backup.postgres.tar
filepg_dumpall -f DB_Backup.ALL
- dumps the whole DBMS into theDB_Backup.ALL
fileYou can avoid to authenticate each time a table is being copied by creating a file called
.pgpass
in the home directory
DB Restore
There are two tools to perform this operation:
psql
andpg_restore
pg_restore -v -d postgres DB_Backup.postgres.compressed
will perform a full restoration of the postgres DB from theDB_Backup.postgres.compressed
file (in verbose mode)pg_restore -v -d postgres DB_Backup.postgres.tar
will perform a full restoration of the postgres DB from theDB_Backup.postgres.tar
file (in verbose mode)The database referenced with the
-d
option must be already existing; you can create it anew with the-C
optionpg_restore -l backup_file
will display the TOC (table of contents) of the backup, that you can use for selective/reordered restorationpsql -f DB_Backup.linuxcbt2.sql
will restore the database whose definition is contained inDB_Backup.linuxcbt2.sql
(only for files encoded as scripts)pg_restore -v -d postgres -t messages2 DB_Backup.postgres.compressed
will restore just themessages2
table in the postgres database from theDB_Backup.postgres.compressed
filepg_restore -v -d postgres -t messagescategories DB_Backup.postgres.tar
will restore just themessagescategories
table in the postgres database from theDB_Backup.postgres.tar
file
Windows Restore
psql -h 192.168.75.105
will connect to the PostgreSQL databse running on host 192.168.75.105psql -h 192.168.75.105 -f DB_Backup.ALL
will run the DB_Backup.ALL script against the databse running on host 192.168.75.105pg_restore -h 192.168.75.105 -v -d postgres -t messages2 DB_Backup.postgres.compressed
will restore the messages2 table on the postgres database running on host 192.168.75.105, taking the values from theDB_Backup.postgres.compressed
fileThe HBA conf file is the one that allows Postgres to accept incoming remote connections
SSH Tunnels
By default, PostgreSQL uses plaintext communication between the client and the server
tcpdump -v -i lo tcp port 5432 -w postgres.dump.1
allows us to sniff the communication PostgreSQL is receiving and sending in the localhost, and save it to the file namedpostgres.dump.1
We can analyze the dump file using Wireshark to reconstruct the whole communication stream
ssh -L 5433:192.168.75.20 192.168.75.20
will create a secure tunnel between localhost and 192.168.75.20 (the communication in transit will be encrypted, but not on the endpoints)netstat -ntl | grep 5433
will confirm that the tunnel is actually existingpsql -h localhost -p 5433
will connect to the 5433 port on the loopback interface, which is acting as the tunnel to 192.168.75.20You can connect via SSH to a remote instance of Postgres using PuTTY (or some equivalent SSH client), but Windows cannot act as the SSH server unless you use Cygwin or similar
SSL Connections
Enables true end-to-end encryption protection
Postgres will listen for SSL clients on the usual port, 5432
Postgres will auto-negotiate the connection with the client, unless explicitly stated otherwise in the
pg_hba.conf
fileopenssl req -new -text -out server.req
will generate a request to be signedopenssl rsa -in privkey.pem -out server.key
will remove the passphrase from the generated private keyopenssl req -x509 -in server.req -text -key server.key -out server.crt
will generate a self-signed certificate filechown postgres server.key && chmod 600 server.key
will change the owner of the private key to postgres, and make it readable just to that userChanging the
postgresql.conf
file to have thessl=on
key will enable SSL (out by default)When you want to use SSL, you must specify the host (even if it is localhost) with the
-h
option. If you connect locally without the-h
option, it will use Unix Domain Sockets, which do not support SSL
Resources
Articles
10 Postgres tips for beginners - Nikolay Samokhvalov, Postgres.ai
How Postgres stores oversized values – let's raise a TOAST - Drew Silcock
psql Tips - Lætitia Avrot
PostgreSQL DBA Daily Checklist - Shiv Iyer, MinervaDB
Books
The Internals of PostgreSQL - Hironobu Suzuki
GitHub Repositories
Websites
Crunchy Data - Postgres Tutorials
explain.dalibo.com - PostgreSQL execution plan visualizer
Last updated