PostgreSQL Administration
Update einer PostgreSql-Major-Version
Diese Anleitung ist gedacht für ein Upgrade von debian squeeze auf debian wheezy. Ausgangslage ist daher, dass postgresql-8.4 bereits installiert ist.
In dieser Anleitung wird auf die Verwendung von pg_upgrade verzichtet. pg_upgrade macht insbesondere bei großen Datenbeständen mit der Option -k Sinn.
Standardmäßig kommt postgresql 9.1 mit wheezy mit. Optional kann man aber auch gleich postgresql 9.3 installieren. Das folgende apt-Repo wird von postgresql aktualisiert und ist für die Verwendung von debian gedacht.
apt-get install python-software-properties
wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ wheezy-pgdg main"
apt-get update
apt-get upgrade
Jetzt muss man die neue postgre-Version installieren (Nach Debian-Update auf wheezy ist postgresql-9.1 bereits installiert)
apt-get install postgresql-9.3 postgresql-server-dev-8.4 postgresql-server-dev-9.3
Alten Cluster der Version 9.1 und 9.3 entfernen (Achtung: Dies löscht alle Daten. Nur der Cluster von 8.4, der die ursprünglichen Daten enthält, bleibt erhalten):
pg_dropcluster 9.1 main --stop
pg_dropcluster 9.3 main --stop
Neue Binaries verwenden:
In Dateien /root/.bash_profile
und /var/lib/postgresql/.bash_profile
folgende Zeile unten hinzufügen/ersetzen:
PATH=$PATH:/usr/lib/postgresql/9.3/bin
Benutzer abmelden und anmelden als root.
Neuen Cluster in Version 9.3 erzeugen:
pg_createcluster
--encoding=UTF-8 \
--locale=en_US.UTF-8 \
--lc-collate=en_US.UTF-8 \
--lc-ctype=en_US.UTF-8 \
--lc-messages=en_US.UTF-8 \
--lc-monetary=en_US.UTF-8 \
--lc-numeric=en_US.UTF-8 \
--lc-time=en_US.UTF-8 \
-d /var/lib/postgresql/9.3/main 9.3 main -- \
--auth=md5 --pwprompt
Neuer Cluster hat Port 5433!
postgres-Systemnutzer immer vertrauen (nötig für Rücksicherung), hierzu Datei /etc/postgresql/9.3/main/pg_hba.conf
editieren (Zeilen einfügen):
#postgres user
local all postgres trust
service postgresql restart
sudo su - postgres
pg_dumpall -p5432 >dump.sql
cat dump.sql | psql -p 5433
exit
In /etc/postgres/8.4/main/posgresql.conf
Port ändern auf 50432
In /etc/postgres/8.4/main/posgresql.conf
Port ändern auf 5432
service postgres restart
Anschließend neuen Cluster auf Funktionsfähigkeit testen.
Alten Cluster löschen:
pg_dropcluster 8.4 main --stop
Alte postgresql-Versionen entfernen:
apt-get remove postgresql-8.4 postgresql-server-dev-8.4 postgresql-9.1 postgresql-server-dev-9.1
Quellen:
http://bailey.st/blog/2013/05/14/how-to-install-postgresql-9-2-on-debian-7-wheezy/
http://www.postgresql.org/docs/9.3/static/app-pg-dumpall.html
Struktur einer Relation ausgeben
Im Befehlszeilenclient psql lässt sich die Struktur einer Relation ausgeben mit:
\d tablename
Dies entspricht in etwa einem desc tablename;
bei MySQL.
postgreSQL installieren und konfigurieren
Installation:
sudo apt-get install postgresql
Vorarbeiten: Um zu ermöglichen, dass die postgreSQL mittels der Variable shared_buffers
einen Cache mit mehr als ca. 32MB vorhalten kann, muss zunächst ein Kernel-Parameter namens SHMMAX
hochgesetzt werden:
Unter ubuntu 11.04 kann man in der Datei /etc/sysctl.d/30-postgresql-shm.conf
die folgende Zeile setzen (hier: bis zu 4GB für shared_buffers
)
kernel.shmmax = 4294967296
Bei anderen Distributionen kann man diese Datei neu in /etc/sysctl.d/
anlegen oder man kann die Zeile in die /etc/sysctl.conf
einfügen.
SHMMAX
muss größer sein als shared_buffers
. Sonst kommt folgender Fehler beim Start des PostgreSQL-Servers:
CET FATAL: could not create shared memory segment: Invalid argument
CET DETAIL: Failed system call was shmget(key=...).
CET HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter
Konfiguration mittels Konfigurationsparametern:
shared_buffers
: Arbeitsspeicher, der für Caching verwendet werden kann. Sinnvoll ist z.B. 25-40% des verfügbaren Arbeitsspeichers.
temp_buffers
: Speicher für temporäre Tabellen im Arbeitsspeicher. Benötigen temporäre Tabellen mehr Speicher, wird auf Festplatte gespeichert. Dieser Wert sollte nur hochgesetzt werden, wenn oft große temporäre Tabellen (SQL: create temporary table ...) oft benutzt werden.
work_mem
: Arbeitsspeicher, der für Sortier- oder Hashoperationen benutzt werden darf. Sinnvoll sind 3-10% des verfügbaren Arbeitsspeichers.
PostgreSQL-Befehle in PATH-Variable aufnehmen (hier: ubuntu 13.10)
Bei einer Standard-Installation stehen dem Benutzer postgres zunächst nicht alle Befehler auf der Konsole zur Verfügung. Zur Abhilfe kann der entsprechende Pfad zur PATH-Variable des postgres-Benutzers hinzugefügt werden:
sudo su - postgres
cd
vim .bash_profile
Dort neue Zeile eintragen und speichern:
PATH=$PATH:/usr/lib/postgresql/9.3/bin
Jetzt sollten alle PostgreSQL-Befehle zur Verfügung stehen. Man muss den Pfad bei einem Wechsel der PostgreSQL-Version unbedingt anpassen.
PostgreSQL initialisieren
Dieses Beispiel initialisiert die PostgreSQL Instanz mit folgenden Einstellungen
- Das Encoding wird auf Unicode (UTF-8) gesetztDie Locales werden auf en_US gesetzt.
- Es ist eine Passwort-Authentifizierung nötig. Passwörter werden als md5-Hashes gespeichert. Bei Verbindungen über Netzwerk sollten diese unbedingt SSL-verschlüsselt oder SSH-getunnelt werden!
Hinweis: die vom Betriebsystem zur Verfügung gestellten locales können eingesehen werden mit
locale -a
Damit die locales auch beim Start Startskript verwendet werden, muss zuerst Folgendes in der Datei /etc/postgresql/8.4/main/postgresql.conf
gepflegt werden:
# locale for system error message strings
lc_messages = 'en_US.utf8'
# locale for monetary formatting
lc_monetary = 'en_US.utf8'
# locale for number formatting
lc_numeric = 'en_US.utf8'
# locale for time formatting
lc_time = 'en_US.utf8'
#YYYY-MM-DD ISO style
datestyle = 'iso, ymd'
Außerdem kann man PostgreSQL per pg_hba.conf
so konfigurieren, dass immer ein Passwort übergeben werden muss. Dies gilt auch für bereits angemeldete Benutzer:
local all postgres md5
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:host all all 127.0.0.1/32 md5
# IPv6 local connections:host all all ::1/128 md5
Hierbei sollte man TCP-Verbindungen möglichst nicht zulassen (mit listen_addresses = 'localhost'
in der Datei /etc/postgresql/9.3/main/postgresql.conf
)
Achtung: Die Initialisierung löscht möglicherweise alle Datenbanken (und somit alle Daten!) sowie Benutzer. Die PostgreSQL sollte daher am besten vor dem Anlegen von Datenbanken initialisiert werden.
sudo service postgresql stop
sudo su - postgres
cd /var/lib/postgresql/9.3/
mv main main_mkdir main
initdb --auth=md5 --pwprompt \
--encoding=UTF8 \
--locale=en_US.utf8 \
--lc-collate=en_US.utf8 \
--lc-ctype=en_US.utf8 \
--lc-messages=en_US.utf8 \
--lc-monetary=en_US.utf8 \
--lc-numeric=en_US.utf8 \
--lc-time=en_US.utf8 \
--pgdata=/var/lib/postgresql/9.3/main
exit
cp ./../main_/server* . #nur bei älteren ubuntu-Versionen
sudo service postgresql start
Das alte Verzeichnis /var/lib/postgresql/9.3/main_
kann bei Gelegenheit gelöscht werden. Damit sind dann allerdings auch die alten Daten gelöscht. Insofern sollte man sich vor der Löschung vergewissern, dass alle Daten im neuen PostgreSQL Cluster verfügbar sind
Quellen:
http://www.postgresql.org/docs/8.4/static/app-initdb.html
Tablespaces anzeigen
in psql:
\db
Benutzer anlegen
Benutzer anlegen:
Im Betriebsystem anmelden als Benutzer postgres
createuser -U postgres --password --pwprompt --encrypted newuser
Zunächst wird ein neues Passwort zweimalig abgefragt. Im Anschluss fragt postgresql, ob der Benutzer superuser
sein soll. Normalerweise sollte die Antwort "nein" lauten. Zum Schluss muss man evtl. noch das Datenbank-Passwort von posgres
eingeben.
Zu beachten ist, dass das Passwort zur Authentifizierung nur nötig ist, wenn die Datei /etc/postgresql/8.4/main/pg_hba.conf
entsprechend konfiguriert ist (md5
als method
)
Passwort ändern
ALTER USER myuser with encrypted PASSWORD '123';
Datenbank anlegen
In der Shell:
createdb --encoding=UTF8 -U newuser newdb
Befehlszeilenclient verwenden (psql)
In der Shell:
psql -U newuser -d newdb
Beenden mit \q
.
Clientseitiges Encoding festlegen
Abweichend oder ergänzend zur Serverkonfiguration lässt sich ein Encoding auch für die aktuelle Sitzung festlegen:
in SQL:
SET CLIENT_ENCODING TO 'UTF8';
in psql:
\encoding UTF8
weitere Encodings:
PL/pgSQL aktivieren für psql
Damit PL/pgSQL zur Verfügung steht, muss es aktiviert werden mit
CREATE FUNCTION plpgsql_call_handler ()
RETURNS OPAQUE AS '/usr/local/pgsql/lib/plpgsql.so' LANGUAGE 'C';
CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPILER 'PL/pgSQL';
Laufende User-Prozesse anzeigen
Mit folgendem SQL-Statement können alle laufenden User-Prozesse auf dem postgresql-Server angezeigt werden:
SELECT datname,procpid,current_query FROM pg_stat_activity; -- pg 8.4
SELECT datname,pid,query_start, state, query FROM pg_stat_activity; -- pg 9.3
datname | procpid | current_query
-----------+---------+-------------------------------------------------------------
dwmteam1b | 27527 | SELECT datname,procpid,current_query FROM pg_stat_activity;
(1 Zeile)
Laufenden User-Prozess beenden
Mit folgendem SQL-Statement kann ein User-Prozess auf dem postgresql-Server beendet werden:
select pg_cancel_backend(22345);
22345
ist in diesem Fall die procpid
eines User-Prozesses. Bei Erfolg gibt die Funktion true
zurück, sonst false
.
Man muss hierzu superuser
sein, ansonsten erscheint eine Meldung:
ERROR: must be superuser to signal other server processes
Mit Transaktionen langsame INSERTs beschleuningen
Wenn man INSERT
-Statements innerhalb einer Transaktion laufen lässt, kann man eine massive Beschleunigung erreichen. Im Labortest auf einem Laptop stieg der Durchsatz von 200 INSERT
s pro Sekunde auf ca. 2000 INSERT
s pro Sekunde. Eine Transaktion lässt sich erzeugen mit:
BEGIN;
INSERT ...;
...
INSERT ...;
COMMIT;