PostgreSQL
Notes - LinuxCBT Tutorial
psql
Features include
command history
tab completion
commands terminate with semicolons
psql --versionprints on the terminal the current version of PostgreSQLpsql -llists all the available databases and exitspsql -Ulets 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
psqlwithout any arguments enters the interactive mode:\hreturns a SQL-specific help (\h COMMANDwill give you documentation for that command)\?returns PSQL-specific help\llists all the DBs (\l+returns more information)\dureturns list of users in system (\du+for more information)\!launches a shell inside sql (\! COMMANDwill execute the command onto a shell)\i FILEexecutes commands (SQL and sql) from an external file\c DBNAMEconnect 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
postgresPrivileges are managed with:
GRANT | REVOKEALTERCREATE | 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
ALTERSQL commandThe special
PUBLICrole 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.conffile
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_logEach 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
publicandpg_catalogschemasAll users (and roles) have the CREATE and USAGE access to the
publicschema 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
publicschema are not readily available without using the GRANT commandDROP <type> <name> CASCADEwill 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 nameintonew nameALTER 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 nameDB 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> SUPERUSERwill 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
UNIQUEconstraint applies to any type of column, and requires that all the values in that column must be uniqueThe creation of
UNIQUEconstraints cause PostgreSQL to automatically create a b-tree index on that columnIf we declare as
UNIQUEa 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 KEYconstraint is a combination of theUNIQUEandNOT NULLconstraintsThere can only be ONE primary key per table
Standard SQL recommends that each table contains a primary key
The
FOREIGN KEYconstraint 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
CHECKconstraint 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
INSERTallows 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
CHECKstatement 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
\copycommandAllows 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>COPYwill 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, ..., columnNare shownThe order of the columns in the resulting view will reflect the order we gave in the
SELECTcommand (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 withstrSELECT * 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 BYclause when usingLIMITbecause 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.idwill 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.idwill 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.idwill create a view in which only the selected columns are displayedSELECT * FROM <table1> AS t1 INNER JOIN <table2> ON t1.id = <table2>.idis functionally equivalent to aJOINwith aWHEREclause, 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
publicschema, but rather to thepg_temp_2schema
Aggregate Functions
Compute single results (scalars) from multiple inputs (rows)
Values are computed after the
WHEREclause (they cannot used within theWHEREclause, but they can be used with theHAVINGclause)The
HAVINGclause is calculated after the computation done by the aggregate functionSELECT count(*) FROM messageswill return the number of rows in the messages tableSELECT sum(id) FROM messageswill return the sum of value from the id column (only works with numbers, obviously)SELECT avg(id) FROM messageswill return the average of the id valuesSELECT min(id) FROM messageswill find the minimum value among the idsSELECT max(id) FROM messageswill find the maximum value among the idsSELECT date, min(id) FROM messages GROUP BY datewill not work without theGROUP BYclause, because we are referencing non-aggregated and aggregated columns in the same querySELECT date, min(id) FROM messages WHERE id < 51 GROUP BY datewill execute theWHEREclause before theGROUP BYclause, so it will restrict the aggregate function to rows for whichid < 51SELECT date, min(id) FROM messages WHERE id < 51 GROUP BY date HAVING min(id) < 30will 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 messagesreturns true if all the values are true (only works with booleans, obviously)SELECT bool_or(enabled) FROM messageswill 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
UPDATEcommand will update tables and sub-tables (or parent tables) unless theONLYkeyword is specifiedThe output will tell us how many records have been affected by the change
UPDATE messages SET enabled=f WHERE id = 100will set the enabled value of the row with id 100 to falseUPDATE messages SET enabled=f, message = 'new message' WHERE id >= 100will update multiple columns simultaneouslyUPDATE messages SET enabled = DEFAULTwill reset all the rows (because theWHEREclause 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 enabledwill 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
WHEREclause)It is a recursive operation (but you can use the ONLY clause to avoid affecting child tables)
DELETE FROM messages WHERE id = 103removes a single record (if exists)DELETE FROM messages WHERE id = 103 RETURNING *will return all the records that have just deletedJust one
DELETEstatement could make the whole transaction fail, i.e. not deleting any rows if just one failsDELETE FROM messagesdeletes all rows from the messages table and all of its child tablesALTER TABLE messagescategories DROP CONSTRAINT IF EXISTS messagescategories_id_fkeywill drop the foreign key constraintIf you wish to delete all the records from a table,
TRUNCATEis 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 messageswill 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 namedmessagesbased on themessageidcolumn; 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 messageswill display information about the indices on the messages tableDROP INDEX messages_idwill 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 messageswill 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/messagesfile 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/messagesfile, we can:create a
messagestable 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 messagestest 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
GRANTcommand is available to grant privileges of all sorts:SELECT- columns or tablesINSERT- columns or tablesUPDATEDELETE- row-basedCREATECONNECT(granted by default)EXECUTE- functionsTRIGGERUSAGETEMPORARYTRUNCATEREFERENCES
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 theSELECTprivileges 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 theINSERTprivileges on all columns of obj_nameGRANT USAGE ON <obj_name> TO <role>will grant theUSAGEprivileges (useful for sequences of auto-generated values)UPDATE messages SET mfacility = 'kernel' WHERE mid = '204358' RETURNING *will update the row for which theWHEREclause 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
REVOKEis 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:
DELETED:
DROP(truncate)x: references
t: triggers
U: usage
/user: permission issuer
REVOKE ALL on object[, object2, ..., objectN] FROM userremoves ALL privileges for user onobject(andobject2, ..., objectN)REVOKE INSERT on object[, object2, ..., objectN] FROM userremoves just theINSERTprivilege for user onobject(andobject2, ..., objectN). To revoke more than one privilege, the command isREVOKE privilege[, privilege2, ..., privilegeN] on object[, object2, ..., objectN] FROM userThe
INSERTprivilege may be granted/revoked independently fromSELECT, unlike theUPDATEandDELETEones (whereSELECTis used to match the criteria specified with theWHEREclause).GRANT ALL on object TO user WITH GRANT OPTIONwill 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
REVOKEsome privileges to a user which hasGRANTEDthe same privileges to some other user, theREVOKEoperation will fail, unless we specify theCASCADEoption.
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_restoreutility-Fp(default): plain SQL script, uncompressed-Fc: auto-compressed format, works only withpg_restore-Ft: tarball, not compressed, works with bothtarandpg_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_postgresfile, in verbose modepg_dump -v postgres > DB_Backup_postgres2- dumps the postgres DB to theDB_Backup_postgres2file, using output redirectionpg_dump -s -f DB_Backup.schema postgres- dumps only the schema of the postgres database to theDB_Backup.schemafilepg_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.categoriesfilepg_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_messagesfilepg_dump -Fc -f DB_Backup.compressed postgres- dumps the postgres database in the compressed format into theDB_Backup.compressedfilepg_dump -Ft -f DB_Backup.postgres.tar postgres- dumps the postgres database in the tar format into theDB_Backup.postgres.tarfilepg_dumpall -f DB_Backup.ALL- dumps the whole DBMS into theDB_Backup.ALLfileYou can avoid to authenticate each time a table is being copied by creating a file called
.pgpassin the home directory
DB Restore
There are two tools to perform this operation:
psqlandpg_restorepg_restore -v -d postgres DB_Backup.postgres.compressedwill perform a full restoration of the postgres DB from theDB_Backup.postgres.compressedfile (in verbose mode)pg_restore -v -d postgres DB_Backup.postgres.tarwill perform a full restoration of the postgres DB from theDB_Backup.postgres.tarfile (in verbose mode)The database referenced with the
-doption must be already existing; you can create it anew with the-Coptionpg_restore -l backup_filewill display the TOC (table of contents) of the backup, that you can use for selective/reordered restorationpsql -f DB_Backup.linuxcbt2.sqlwill 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.compressedwill restore just themessages2table in the postgres database from theDB_Backup.postgres.compressedfilepg_restore -v -d postgres -t messagescategories DB_Backup.postgres.tarwill restore just themessagescategoriestable in the postgres database from theDB_Backup.postgres.tarfile
Windows Restore
psql -h 192.168.75.105will connect to the PostgreSQL databse running on host 192.168.75.105psql -h 192.168.75.105 -f DB_Backup.ALLwill 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.compressedwill restore the messages2 table on the postgres database running on host 192.168.75.105, taking the values from theDB_Backup.postgres.compressedfileThe 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.1allows us to sniff the communication PostgreSQL is receiving and sending in the localhost, and save it to the file namedpostgres.dump.1We can analyze the dump file using Wireshark to reconstruct the whole communication stream
ssh -L 5433:192.168.75.20 192.168.75.20will 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 5433will confirm that the tunnel is actually existingpsql -h localhost -p 5433will 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.conffileopenssl req -new -text -out server.reqwill generate a request to be signedopenssl rsa -in privkey.pem -out server.keywill remove the passphrase from the generated private keyopenssl req -x509 -in server.req -text -key server.key -out server.crtwill generate a self-signed certificate filechown postgres server.key && chmod 600 server.keywill change the owner of the private key to postgres, and make it readable just to that userChanging the
postgresql.conffile to have thessl=onkey will enable SSL (out by default)When you want to use SSL, you must specify the host (even if it is localhost) with the
-hoption. If you connect locally without the-hoption, 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
What I Wish Someone Told Me About Postgres - Hazel Bachrach
Books
The Art of PostgreSQL - Dimitri Fontaine
The Internals of PostgreSQL - Hironobu Suzuki
GitHub Repositories
Websites
Crunchy Data - Postgres Tutorials
explain.dalibo.com - PostgreSQL execution plan visualizer
Last updated
Was this helpful?