Migration vers 9.3 et supérieures¶
Augmentation de la consommation mémoire de work_mem
¶
Depuis PostgreSQL 9.3, la mémoire assignée par work_mem
peut enfin être totalement allouée
(c’était une limitation des versions précédentes). Cela signifie aussi que probablement, vous
aurez plus de mémoire allouée en tant que work_mem
dans une instance 9.3 que dans les versions
précédentes.
Commit Delay¶
Le paramètre commit_delay
n’est maintenant modifiable que par les superutilisateurs. Cela n’a
que peu d’importance, ce paramètre n’étant que très rarement modifié.
Renommage de replication_timeout
¶
À partir de PostgreSQL 9.3
, replication_timeout
devient wal_sender_timeout
.
Renommage de unix_socket_directory
¶
Le paramètre unix_socket_directory
a été remplacé par unix_socket_directories
: cela permet
d’avoir plusieurs répertoires pouvant contenir un socket Unix de connexion à l’instance, chacune,
par exemple, dans un répertoire ayant des permissions différentes (pour restreindre l’accès à
l’instance).
Noms de journaux de transaction¶
Les noms de journaux de transaction peuvent maintenant se terminer par FF
. Jusque-là, les 16
derniers mégaoctets d’un tronçon de 4 Go étaient sautés. Cela peut avoir un impact si vous avez un script
vérifiant la présence de toute une série de journaux de transactions dans un répertoire.
CREATE TABLE
¶
Les messages de NOTICE
de création d’objets supplémentaires à la création d’une table sont
maintenant du DEBUG2
.
Sous PostgreSQL 9.2
:
postgres=# CREATE TABLE test (a int PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
Sous PostgreSQL 9.3 :
Cela pourrait gêner des scripts de déploiement qui vérifient ces informations.
Triggers en cascade¶
Voici un exemple très simplifié illustrant le problème :
- une table
detail
; - une table
sum
; - la table
sum
est maintenue à jour par des triggers surdetail
; - un trigger sur
sum
en cas deDELETE
supprime tous les détails associés.
CREATE FUNCTION delete_detail() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE sum SET sum=sum-old.value WHERE sum.name=old.name;
-- En théorie il faudrait gérer une exception au cas où on aurait une mise
-- à jour en parallèle
RETURN old;
END
$$;
CREATE FUNCTION delete_sum() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
DELETE FROM detail WHERE detail.name=old.name;
-- En théorie il faudrait gérer une exception au cas où on aurait une mise
-- à jour en parallèle
RETURN old;
END
$$;
CREATE FUNCTION insert_detail() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE sum SET sum=sum+new.value WHERE sum.name=new.name;
IF not found THEN
insert into sum (name,sum) values (new.name,new.value);
END IF;
-- En théorie il faudrait gérer une exception au cas où on aurait une mise
-- à jour en parallèle
RETURN new;
END
$$;
CREATE FUNCTION update_detail() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE sum SET sum=sum+new.value-old.value WHERE sum.name=new.name;
-- En théorie il faudrait gérer une exception au cas où on aurait une mise
-- à jour en parallèle
RETURN new;
END
$$;
CREATE TABLE detail (
name text,
value bigint
);
CREATE TABLE sum (
name text,
sum bigint
);
CREATE TRIGGER delete_trigger BEFORE DELETE ON detail FOR EACH ROW EXECUTE PROCEDURE delete_detail();
CREATE TRIGGER delete_trigger_sum BEFORE DELETE ON sum FOR EACH ROW EXECUTE PROCEDURE delete_sum();
CREATE TRIGGER insert_trigger BEFORE INSERT ON detail FOR EACH ROW EXECUTE PROCEDURE insert_detail();
CREATE TRIGGER update_trigger BEFORE UPDATE ON detail FOR EACH ROW EXECUTE PROCEDURE update_detail();
Sous PostgreSQL 9.2 :
postgres=# INSERT INTO detail VALUES ('test',1);
INSERT 0 1
postgres=# INSERT INTO detail VALUES ('test',1);
INSERT 0 1
postgres=# SELECT * FROM sum;
name | sum
------+-----
test | 2
(1 ligne)
postgres=# DELETE FROM sum;
DELETE 0
postgres=# SELECT * FROM sum;
name | sum
------+-----
test | 0
(1 ligne)
Sous PostgreSQL 9.3 :
postgres=# INSERT INTO detail VALUES ('test',1);
INSERT 0 1
postgres=# INSERT INTO detail VALUES ('test',1);
INSERT 0 1
postgres=# SELECT * FROM sum;
name | sum
------+-----
test | 2
(1 ligne)
postgres=# DELETE FROM sum;
ERROR: tuple to be updated was already modified by an operation triggered by the current command
ASTUCE : Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows.
Le trigger de la table detail
essaye de s’exécuter sur la table sum
, alors que celui-ci a
normalement été supprimé. En 9.3, l’erreur est bien interceptée au lieu d’entraîner la
bizarrerie de PostgreSQL 9.2.
Foreign key et ON UPDATE SET NULL/SET DEFAULT
¶
Voici un exemple :
CREATE TABLE parent (a int, b int, c int, primary key (a,b));
CREATE TABLE enfant (d int primary key, a int, b int, foreign key (a,b) references parent(a,b) on update set null);
INSERT INTO parent VALUES (1,1,1);
INSERT INTO enfant VALUES (1,1,1);
UPDATE parent SET b=0;
Sous PostgreSQL 9.2 :
(ici , ¤
représente NULL
)
Sous PostgreSQL 9.3
:
L’ancien comportement est celui du standard SQL-92. Le nouveau celui des standards plus récents.