Vous n'êtes pas identifié(e).
Pages : 1
Petite question relative à ça au passage : les fichiers qui composent une extension pour sa version x.y donnée restent compatibles à l'intérieur d'une même version majeure de pg (16.4, 16.5, ...) ?
Bonjour,
Depuis quelques jours, j'ai une erreur bizarre qui apparait parfois lorsque je supprime une base : un problème d'accès à des fichiers sous /main/global/ !
Je suis en pg 16.4 (migration depuis la v15 le 10 août) et en Debian Bookworm (=v12.7) avec rien de particulier dans la conf...
La partition pour pg est en ext4 avec attributs "rw,noatime".
Il y a une soixantaine de bases, les grosses font entre 20 et 70Go.
$ grep -h -C1 'global/' /var/log/postgresql/postgresql-16-main.log*
(j'ai masqué quelques infos persos avec des "*" ;-)
2024-10-13 20:36:24 CEST [2401]: [1450-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 59 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.206 s, sync=0.001 s, total=0.212 s; sync files=15, longest=0.001 s, average=0.001 s; distance=531 kB, estimate=807 kB; lsn=11D/7F8A9318, redo lsn=11D/7F8A92E0
2024-10-13 20:36:24 CEST [2410]: [1-1] user=,db=,app=,client= ERROR: could not open file "global/6100": Operation not permitted
2024-10-13 20:36:25 CEST [2965643]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=46830
2024-10-13 20:36:25 CEST [2965644]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=50224
2024-10-13 20:36:25 CEST [2965640]: [3-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-13 20:36:25 CEST [2965640]: [4-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** STATEMENT: DROP DATABASE ********;
2024-10-13 20:36:25 CEST [2965643]: [2-1] user=********,db=********,app=[unknown],client=***.***.***.*** FATAL: could not open file "global/pg_filenode.map": Operation not permitted
2024-10-13 20:36:25 CEST [2965644]: [2-1] user=********,db=********,app=[unknown],client=***.***.***.*** FATAL: could not open file "global/pg_filenode.map": Operation not permitted
2024-10-13 20:36:25 CEST [2965646]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=50228
--
2024-10-17 08:15:46 CEST [2401]: [3454-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 106 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.199 s, sync=0.001 s, total=0.202 s; sync files=61, longest=0.001 s, average=0.001 s; distance=586 kB, estimate=2373 kB; lsn=11E/417A77C8, redo lsn=11E/417A7790
2024-10-17 08:15:47 CEST [3452150]: [3-1] user=********,db=template1,app=********,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-17 08:15:47 CEST [3452150]: [4-1] user=********,db=template1,app=********,client=***.***.***.*** STATEMENT: DROP DATABASE "********"
--
2024-10-17 10:06:02 CEST [2401]: [3500-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 48 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.201 s, sync=0.001 s, total=0.222 s; sync files=7, longest=0.001 s, average=0.001 s; distance=447 kB, estimate=998 kB; lsn=11E/42175090, redo lsn=11E/42175058
2024-10-17 10:06:03 CEST [3506557]: [4-1] user=********,db=********,app=psql/********,client=[local] ERROR: could not open file "global/1213": Operation not permitted
2024-10-17 10:06:03 CEST [3506557]: [5-1] user=********,db=********,app=psql/********,client=[local] STATEMENT: drop DATABASE ******** ;
--
2024-10-17 12:33:34 CEST [2401]: [3562-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 91 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.199 s, sync=0.002 s, total=0.205 s; sync files=10, longest=0.001 s, average=0.001 s; distance=718 kB, estimate=495087 kB; lsn=11E/683C0698, redo lsn=11E/683C0660
2024-10-17 12:33:34 CEST [3720580]: [3-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-17 12:33:34 CEST [3720580]: [4-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** STATEMENT: DROP DATABASE IF EXISTS ********;
--
2024-10-17 17:39:52 CEST [4036373]: [3-1] user=********,db=********,app=[unknown],client=***.***.***.*** LOG: connection authorized: user=******** database=******** SSL enabled (protocol=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384, bits=256)
2024-10-17 17:40:01 CEST [2408]: [1-1] user=,db=,app=,client= ERROR: could not open file "global/1262": Operation not permitted
2024-10-17 17:40:02 CEST [4036438]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=33480
2024-10-22 11:52:39 CEST [2401]: [6428-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 922 buffers (0.0%); 0 WAL file(s) added, 0 removed, 1 recycled; write=0.243 s, sync=0.002 s, total=0.255 s; sync files=141, longest=0.001 s, average=0.001 s; distance=5511 kB, estimate=13011 kB; lsn=11F/3303F148, redo lsn=11F/3303F110
2024-10-22 11:52:41 CEST [3519566]: [3-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-22 11:52:41 CEST [3519566]: [4-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** STATEMENT: DROP DATABASE IF EXISTS ******** WITH (FORCE);
--
2024-10-22 16:18:06 CEST [2401]: [6536-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 110 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.211 s, sync=0.001 s, total=0.223 s; sync files=57, longest=0.001 s, average=0.001 s; distance=599 kB, estimate=10743 kB; lsn=11F/40C2D3B0, redo lsn=11F/40C2D378
2024-10-22 16:18:07 CEST [3794417]: [3-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-22 16:18:07 CEST [3794417]: [4-1] user=********,db=postgres,app=dropdb,client=***.***.***.*** STATEMENT: DROP DATABASE IF EXISTS ******** WITH (FORCE);
--
2024-10-24 17:52:43 CEST [2401]: [7728-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 18103 buffers (0.1%); 0 WAL file(s) added, 0 removed, 96 recycled; write=0.427 s, sync=0.002 s, total=2.421 s; sync files=123, longest=0.001 s, average=0.001 s; distance=1581877 kB, estimate=1581877 kB; lsn=120/8EE79928, redo lsn=120/8EE79150
2024-10-24 17:52:45 CEST [3040312]: [4-1] user=********,db=postgres,app=dropdb,client=[local] ERROR: could not open file "global/1213": Operation not permitted
2024-10-24 17:52:45 CEST [3040312]: [5-1] user=********,db=postgres,app=dropdb,client=[local] STATEMENT: DROP DATABASE IF EXISTS ******** WITH (FORCE);
--
2024-10-24 20:48:24 CEST [3222882]: [4-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 186 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.208 s, sync=0.001 s, total=0.214 s; sync files=54, longest=0.001 s, average=0.001 s; distance=1153 kB, estimate=1153 kB; lsn=124/8576A3F8, redo lsn=124/8576A3C0
2024-10-24 20:48:24 CEST [3229106]: [3-1] user=********,db=template1,app=********,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-24 20:48:24 CEST [3229106]: [4-1] user=********,db=template1,app=********,client=***.***.***.*** STATEMENT: DROP DATABASE "********"
--
2024-10-24 21:18:19 CEST [3222882]: [16-1] user=,db=,app=,client= LOG: checkpoint complete: wrote 95 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.205 s, sync=0.001 s, total=0.212 s; sync files=49, longest=0.001 s, average=0.001 s; distance=646 kB, estimate=950 kB; lsn=124/859DEBD0, redo lsn=124/859DE190
2024-10-24 21:18:19 CEST [3258409]: [3-1] user=********,db=template1,app=********,client=***.***.***.*** ERROR: could not open file "global/1213": Operation not permitted
2024-10-24 21:18:19 CEST [3258409]: [4-1] user=********,db=template1,app=********,client=***.***.***.*** STATEMENT: DROP DATABASE "********"
--
2024-10-25 10:10:27 CEST [4179788]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=[local] LOG: connection received: host=[local]
2024-10-25 10:10:27 CEST [3222889]: [1-1] user=,db=,app=,client= ERROR: could not open file "global/6100": Operation not permitted
2024-10-25 10:10:27 CEST [4179789]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=35002
2024-10-25 10:10:27 CEST [4179790]: [1-1] user=[unknown],db=[unknown],app=[unknown],client=***.***.***.*** LOG: connection received: host=***.***.***.*** port=56532
2024-10-25 10:10:28 CEST [4099649]: [6-1] user=********,db=template1,app=psql/********,client=[local] ERROR: could not open file "global/1213": Operation not permitted
2024-10-25 10:10:28 CEST [4099649]: [7-1] user=********,db=template1,app=psql/********,client=[local] STATEMENT: drop database db_test_drop ;
Les fichiers concernés sont global/1213, global/1262, global/6100 et global/pg_filenode.map
(surtout le 1213!)
Au niveau des droits c'est ok:
$ ls -l /var/lib/postgresql/16/main/global/{1213,1262,6100,pg_filenode}*
-rw------- 1 postgres postgres 8192 24 oct. 22:02 /var/lib/postgresql/16/main/global/1213
-rw------- 1 postgres postgres 24576 10 août 14:34 /var/lib/postgresql/16/main/global/1213_fsm
-rw------- 1 postgres postgres 8192 24 oct. 21:57 /var/lib/postgresql/16/main/global/1213_vm
-rw------- 1 postgres postgres 16384 25 oct. 10:11 /var/lib/postgresql/16/main/global/1262
-rw------- 1 postgres postgres 24576 24 oct. 21:47 /var/lib/postgresql/16/main/global/1262_fsm
-rw------- 1 postgres postgres 8192 24 oct. 21:52 /var/lib/postgresql/16/main/global/1262_vm
-rw------- 1 postgres postgres 0 10 août 14:34 /var/lib/postgresql/16/main/global/6100
-rw------- 1 postgres postgres 524 17 oct. 12:35 /var/lib/postgresql/16/main/global/pg_filenode.map
En switchant sur le compte système "postgres", je peux faire un "cat" de tous ces fichiers sans problème.
D'après le dico, ce sont les tables système suivantes:
# select oid,relname from pg_catalog.pg_class where oid in (1213,1262,6100);
oid | relname
------+-----------------
1213 | pg_tablespace
1262 | pg_database
6100 | pg_subscription
J'ai essayé de créer puis supprimer un tablespace de test hier soir, histoire de voir si ça pourrait remettre des trucs d'équerre, je n'ai pas eu d'erreur et les fichiers 1213* ont bien été modifiés (j'y vois même encore le nom du tablespace supprimé)
Relancer postgres ne change rien non plus...
Je viens de réessayer ce matin (ce sont les lignes du log à 10h10):
$ psql template1
psql (16.4 (Debian 16.4-1.pgdg120+2))
template1=# create database db_test_drop;
CREATE DATABASE
template1=# drop database db_test_drop ;
ERROR: could not open file "global/1213": Operation not permitted
template1=# drop database db_test_drop ;
DROP DATABASE
mais 2 minutes après ça passe :
template1=# create database db_test_drop;
CREATE DATABASE
template1=# drop database db_test_drop ;
DROP DATABASE
Je n'ai pas encore trouvé de fenêtre pour essayer un fsck sur la partoche mais je n'y crois pas trop, ce serveur n'a jamais été confronté à des arrêts brutaux susceptibles de générer une corruption de l'ext4 et tout continue de fonctionner correctement.
Pour finir la description de l'environnement, ce serveur Linux fait tourner un "anti-crasses" (cybereason), imposé depuis 2 ans par le service "infrastucture réseau" mais je ne vois rien dans ses logs qui laisserait penser qu'il "capture" les i/o bas niveau et interfèrerait donc avec le process postgres...
Avez vous des idées pour avancer sur le diagnostic ?
Merci :-)
Ok, super, comme ça je peux faire un simple paquet debian pour déployer ;-)
Bonjour,
L'extension adminpack ayant disparu en v17, j'ai trouvé un remplaçant potentiel sur github qui me satisfait (fio : https://github.com/csimsek/pgsql-fio ).
Elle s'intègre de manière classique avec un "make" suivi d'un "make install" (testé en v16).
Mais pour ne pas avoir à la compiler sur des serveurs de prod, où je n'ai pas trop envie d'installer pleins de paquets "*-dev" ainsi que le compilateur C, je voulais savoir si une simple copie des fichiers était suffisante, à savoir cette liste :
$ locate fio|grep postgresql/16
/usr/lib/postgresql/16/lib/fio.so
/usr/lib/postgresql/16/lib/bitcode/fio
/usr/lib/postgresql/16/lib/bitcode/fio.index.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src
/usr/lib/postgresql/16/lib/bitcode/fio/src/chmod.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/fio.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/mkdir.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/readdir.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/readfile.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/removefile.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/renamefile.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/utils.bc
/usr/lib/postgresql/16/lib/bitcode/fio/src/writefile.bc
/usr/share/postgresql/16/extension/fio--1.0.sql
/usr/share/postgresql/16/extension/fio.control
Ma question est en fait : est-ce que le "make install" fait autre chose que de copier ces fichiers, par exemple maintenir un index de la liste des extensions ?
(aucun autre fichier que ceux listés ci dessus n'a un timestamp de modif qui irait dans ce sens...)
Merci.
Bonjour,
J'utilise plein de sources odbc sous Windows pour lire des bases postgresql v16.
Je les génère par un script en powershell, histoire que les utilisateurs créent tout ça facilement en 1 clic (ajout de bases, renommages, etc).
Mais depuis Excel, quand on choisit une source, on peut précisez que le base derrière supporte les "row reduction clauses" : un bouton "detect" trouve bien LIMIT of OFFSET, ce qui améliore parfois les temps de réponse.
Mais ce n'est pas automatique, il faut le faire à chaque fois qu'une source odbc est sélectionnée...
Est-ce que cet attribut peut être mis directement dans une source odbc ? (il n'est pas dispo dans les 3 pages de conf d'une source pgsql dans l'admin des sources odbc).
J'ai l'impression que c'est un attribut de l'objet "source" d'Excel/PowerQuery (un enrichissement de la source odbc) mais je demande au cas où... ;-)
C'est bien ça ! J'ai testé avec un autre client ODBC ("Database browser" trouvé sur https://www.etl-tools.com) et lui il sait bien afficher les vues mat.
(pour info, ça ne marche pas avec Office 365 Enterprise ni avec Office Home 2019)
Je vais donc les remplacer par de vraies tables "de cache"...
Merci.
Bonjour,
J'utilise la (quasi) dernière version (13.00.000) du driver odbc officiel sous windows 10.
Le serveur est en v12, sous Linux.
Depuis Excel, je vois les schémas, les tables et les vues mais pas les vues matérialisées.
Pourtant en jetant un oeil au source, on dirait que c'est pris en compte...
Même manque avec le driver v12...
Bonjour,
Pensez-vous qu'il serait possible de voir la date de chaque témoignage car actuellement ce n'est pas pratique de savoir lesquels sont nouveaux :-(
J'ai trouvé un "hack" pour faire passer le similarity_threshold à la base distante: dans celle-ci, je crée plusieurs vues qui font simplement un "select set_limit()" et j'appelle la bonne vue distante avant ma vraie requete distante avec l'opérateur "%" => ça fonctionne mais il ne faudrait pas que set_limit disparaisse (marquée comme deprecated dans la doc !)
Voici une fonction qui crée autant de vues que de valeurs de similarity souhaitées:
create or replace function fc_create_set_fdw_pgtrgm_similarity_views(
param_view_name_prefix text, -- can be schema prefixed, _nnn will be added after this name, ie _065 for 0.65 value
param_from_value float, -- 0 to 1
param_to_value float,
param_step float
) returns setof text as $$
declare
curr_value numeric(3,2);
view_name text;
sql_cmd text;
begin
curr_value=param_from_value;
while (curr_value<=param_to_value) loop
view_name=param_view_name_prefix||'_'||to_char(curr_value*100,'FM000');
--
sql_cmd='drop view if exists '||view_name||' cascade';
execute sql_cmd;
--
sql_cmd='create or replace view '||view_name||' as select set_limit('||to_char(curr_value,'FM0.00')||')'; -- TODO: set_limit() is currently deprecated
execute sql_cmd;
return next sql_cmd;
--
perform fc_comment_on('view',view_name,
'View that just set the pg_trgm.similarity_threshold value (only way to set it for a remote fdw query with the % operator!)',current_setting('sessionvar.version',true));
--
curr_value=curr_value+param_step;
end loop;
--
return;
end; $$
language plpgsql;
Idéalement, if faudrait pouvoir envoyer un "SET" à une base distante, y'a du patch en cours à ce sujet ?
J'ai pu finalement avoir l'accès à l'AD via un "proxy" ldap :-)
Malheureusement, le serveur n'aime pas cette config (ldap+mapping): l'option d'authentification « map » est seulement valide pour les méthodes d'authentification « ident, peer, gssapi, sspi et cert »
Dommage :-((((
Bonjour,
J'ai des clients sous Windows 10, loggés via domaine/ad et un serveur pg v10.9 sous Linux.
J'ai plusieurs sources odbc vers différentes bases et ça fonctionne parfaitement (via des vues dans Excel par exemple, les perfs sont excellentes, même pour des dizaines de milliers de lignes avec 50 colonnes !).
Ce qui me gène, c'est le fait de stocker le mot de passe d'un compte dans les infos odbc : j'utilise un compte pg à qui je donne les droits select/execute sur toutes les tables/vues/procs.
D'autant plus que j'ai plein de bases et que du coup je génère les sources odbc par un script powershell qui contient donc ce mot de passe "en dur"...
Bien sur, si je ne mets pas de mot de passe dans la source odbc, il me sera demandé à chaque première lecture dans Excel...
Est-il possible d'utiliser le compte windows à la place (mettre le login windows comme username dans la source, sans le mot de passe) et, avec le mapping de tous les comptes windows potentiels dans pg_ident.conf vers mon compte pg "readonly", de demander le mot de passe windows lors de la première connection ?
Je crains ne pouvoir accèder directement à l'ad depuis le serveur Linux, ni via ldap... Seul "SAML" serait possible...
Bonjour,
La plupart des ORM font leur requête en deux fois, par exemple:
LOG: execute <unnamed>: SELECT ... WHERE t0.id = $1
DETAIL: parameters: $1 = '4396'
C'est un peu galère pour suivre ce que fait une appli à debugger, surtout quand on a 20 paramètres...
(pas moyen de copier/coller le sql entre autres...)
Est-ce qu'un outil de reformatage de ces "paires" de ligne existe déja ?
(sinon, je bricolerai qq chose :-)
<mode rêve>Un paramètre dans le postgresql.conf qui forcerait la fusion de ce type de requête serait idéal !</mode>
Ah, oui, j'aime bien l'idée de "détourner" un plugin Nagios pour comparer 2 schémas :-)
Mais je vais/veux utiliser la réplication logique :-)
Lors du brexit, quand je vais retirer l'Angleterre du groupe europe dans ma base country, les autres bases vont récupérer cette modif, via "subscription", dans "leurs" tables country*...
Je me renseigne juste sur le meilleur moyen/astuce de créer et maintenir la structure de ces tables "mirroir" dans les bases qui s'abonnent...
Bonjour,
J'ai plein de bases qui chacunes contiennent des infos de pays.
Comme y'a un gros ménage de prévu les prochains mois, je pense à faire une base "country" (bon assez grosse quand même car il y aura les langues pratiquées par pays, l'appartenance à des groupes, des historiques de taux de devises, les traductions de tout ça, etc... une bonne vingtaine de tables en tout) dont je répliquerais les tables dans toutes mes autres bases.
Je laisse les fdw de coté pour cet usage (problèmes de perfs, séquenciers, pas possible d'utiliser des FK qui pointent dessus, ...).
Actuellement, j'ai un script bash qui part d'un dump sql pour en faire une version "nettoyée", que je pourrai lancer dans mes bases cibles:
echo "Preparing a cleaned sql dump to create all published tables in another database..."
pg_dump ${PG_PARAMS} --format=plain --no-owner --schema-only --no-acl ${DB_NAME} >${DB_NAME}_schema_only.pgdump.sql
# functions definition can end with $$; or $_$; or $_X$;
# views definitions have at least one space on the start of each line of the body (TODO: better pattern to check this)
pcregrep -vM \
'(^$|^--|^SET |^COMMENT ON (DATABASE|EXTENSION|OPERATOR|FUNCTION|VIEW|) |^CREATE EXTENSION |^CREATE OPERATOR (\n|.)*?\);$|^CREATE TRIGGER |^CREATE FUNCTION (\n|.)*?\$_{0,1}X{0,1}\$;$|^CREATE VIEW (\n|.)*?;$|CREATE PUBLICATION |ALTER PUBLICATION )' \
${DB_NAME}_schema_only.pgdump.sql \
>${DB_NAME}_schema_only.pgdump.cleaned.sql
Voyez vous/existe-t-il une meilleure méthode ?
J'envisageais aussi de passer par un fdw sur la base cible vers la base country pour analyser son dico et y retrouver les tables publiées afin le les créer (mais il faut aussi trouver les définitions de types/domaines/etc... pas si facile!)
Ah, oui, du coup, je viens de me rendre compte que je ne peux pas "envoyer" un autre threshold à la base distante :-(
(à moins que le fdw se connecte par un utilisateur dédié sur lequel on aurait fait un "alter role set th=0.1")
Qu'est ce que ça implique de passer cette fonction en immutable ? (je n'ai pas besoin d'une vue "stable" des données, c'est pour faire des recherches de titres de films...)
Bon, je crois avoir trouvé une solution: ce n'est que si les fonctions sont immutables qu'elles peuvent être déportées (dixit la doc).
En faisant un simple "alter function similarity_op(text,text) immutable;" (au lieu de stable) sur la base cible et la base contenant le fdw, le sql envoyé est bien celui avec le filtre !
Et je divise par 10 le temps d'éxécution, ce qui m'arrange bien car pour un affichage de suggestions dans un champ de saisie, devoir attendre 2/3 secondes, c'était pas glop !
Bonjour,
J'ai une requête qui ne veut pas "envoyer son where" au serveur distant (en v10.4 des 2 cotés, même machine, en debian stable).
C'est un filtre "similarity" : where (column % search)
La colonne est indéxée, pas de souci sur la base en direct...
L'explain montre : Remote SQL: SELECT column FROM public.table
et donc malheureusement, ça filtre en local: Rows Removed by Filter: 249486 :-(
J'ai pourtant précisé "extensions 'pg_trgm'" dans le "create server", ce qui est nécessaire pour que pg pousse les filtres sur le serveur distant...
Est-ce un bug ?
J'ai retesté tout ça car avant, comme je passais la même chaine, le "cache" immutable de pg faussait les tests!
Désormais je suffixe la chaine avec un séquencier pour forcer l'écecution...
J'ai rajouté le gros tableau en "SHARED" (en espérant l'avoir bien fait...) et le test avec Unicode::Normalize
set client_min_messages='WARNING';
drop database if exists test_pg_perl;
create database test_pg_perl;
\c test_pg_perl
create extension unaccent;
create extension plperl;
create extension plperlu;
create or replace function perl_unaccent(param_charset text, param_string text) returns text as $$
use Text::Unaccent;
return unac_string($_[0],$_[1]);
$$ language plperlu immutable strict;
create or replace function perl_unaccent_with_bigmap(param_string text) returns text as $$
# Based on:
# http://cpansearch.perl.org/src/PJACKLAM/Text-Unaccent-PurePerl-0.05/lib/Text/Unaccent/PurePerl.pm
# Author: Peter John Acklam
# Time-stamp: 2013-03-02 12:38:55 +00:00
# E-mail: pjacklam@online.no
# URL: http://home.online.no/~pjacklam
if (!defined $_SHARED) {
$_SHARED={
# 00A0 NO-BREAK SPACE
# -> 0020 SPACE
"\xA0" => " ",
--------------------(CUT)--------------------
# FFEE HALFWIDTH WHITE CIRCLE
# -> 25CB WHITE CIRCLE
"\x{FFEE}" => "\x{25CB}"
}
};
my $str_in=$_[0];
my $str_out='';
my $offset_max=length($str_in)-1;
for my $offset (0..$offset_max) {
my $chr=substr($str_in,$offset,1);
$str_out.=exists $_SHARED->{$chr} ? $_SHARED->{$chr} : $chr;
};
return $str_out;
$$ language plperl immutable strict;
create or replace function perl_unicode_normalize(param_string text) returns text as $$
use Unicode::Normalize;
my $w=NFD($_[0]);
$w =~ s/\pM//g; # strip combining characters
return $w;
$$ language plperlu immutable strict;
\set str2unacc '''Ça va, lʼœil de Владимир a été passé au Kärcher !'''
\echo Test sur la chaine: :str2unacc
select unaccent(:str2unacc);
select perl_unaccent('utf-8',:str2unacc);
select perl_unaccent_with_bigmap(:str2unacc);
select perl_unicode_normalize(:str2unacc);
\set loops 5000
\echo Test sur :loops appels:
explain analyze select unaccent(:str2unacc||seq) from generate_series(1,:loops) as tbl(seq);
explain analyze select perl_unaccent('utf-8',:str2unacc||seq) from generate_series(1,:loops) as tbl(seq);
explain analyze select perl_unaccent_with_bigmap(:str2unacc||seq) from generate_series(1,:loops) as tbl(seq);
explain analyze select perl_unicode_normalize(:str2unacc||seq) from generate_series(1,:loops) as tbl(seq);
Ce qui donne:
Test sur la chaine: 'Ça va, lʼœil de Владимир a été passé au Kärcher !'
unaccent
---------------------------------------------------
Ca va, lʼeil de Владимир a ete passe au Karcher !
perl_unaccent
----------------------------------------------------------------------------
Ca va, lʼÅ\u0093il de Ð\u0092ладимиÑ\u0080 a ete passe au Karcher !
perl_unaccent_with_bigmap
---------------------------------------------------
Ca va, lʼœil de Владимир a ete passe au Karcher !
perl_unicode_normalize
---------------------------------------------------
Ca va, lʼœil de Владимир a ete passe au Karcher !
(1 ligne)
Test sur 5000 appels:
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series tbl (cost=0.00..20.00 rows=1000 width=4) (actual time=0.528..11.804 rows=5000 loops=1)
Total runtime: 12.073 ms
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series tbl (cost=0.00..267.50 rows=1000 width=4) (actual time=0.509..55.731 rows=5000 loops=1)
Total runtime: 56.385 ms
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series tbl (cost=0.00..267.50 rows=1000 width=4) (actual time=0.469..164.947 rows=5000 loops=1)
Total runtime: 165.531 ms
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series tbl (cost=0.00..267.50 rows=1000 width=4) (actual time=0.455..92.159 rows=5000 loops=1)
Total runtime: 92.847 ms
Si je commente le test "defined" (donc en réaffectant le tableau SHARED à chaque fois, ça repasse de 165 à ~6500ms !
En 9.4 j'ai 8.655ms, 1.119ms et 7834ms donc quasi kif-kif...
Merci pour vos analyses !
En attendant, j'ai un peu benchmarké ce qui était dispo (à savoir l'extension unaccent, la lib perl unaccent et le source perl unaccent_pureperl, en pg9.1.16 sur une debian wheezy):
drop database if exists test_pg_perl;
create database test_pg_perl;
\c test_pg_perl
create extension unaccent;
create extension plperl;
create extension plperlu;
create or replace function perl_unaccent(param_charset text, param_string text) returns text as $$
use Text::Unaccent;
return unac_string($_[0],$_[1]);
$$ language plperlu immutable strict;
create or replace function perl_unaccent_pure(param_string text) returns text as $$
# http://cpansearch.perl.org/src/PJACKLAM/Text-Unaccent-PurePerl-0.05/lib/Text/Unaccent/PurePerl.pm
# Author: Peter John Acklam
# Time-stamp: 2013-03-02 12:38:55 +00:00
# E-mail: pjacklam@online.no
# URL: http://home.online.no/~pjacklam
my $map = {
# 00A0 NO-BREAK SPACE
# -> 0020 SPACE
"\xA0" => " ",
...
########################### bon là, j'ai viré tout le tableau associatif pour le paste...
...
# FFEE HALFWIDTH WHITE CIRCLE
# -> 25CB WHITE CIRCLE
"\x{FFEE}" => "\x{25CB}"
};
my $str_in=$_[0];
# Iterate over each character in the input string. If the character exists
# in the map, replace the current character according to the map, otherwise
# keep the character as it is.
my $str_out = '';
my $offset_max = length($str_in) - 1;
for my $offset (0 .. $offset_max) {
my $chr = substr($str_in, $offset, 1);
$str_out .= exists $map->{$chr} ? $map->{$chr} : $chr;
};
return $str_out;
$$ language plperl;
\set str2unacc '''Mon œil à été passé au Kärcher'''
\set loops 5000
explain analyze select unaccent(:str2unacc) from generate_series(1,:loops);
explain analyze select perl_unaccent('utf-8',:str2unacc) from generate_series(1,:loops);
explain analyze select perl_unaccent_pure(:str2unacc) from generate_series(1,:loops);
Voici les résultats:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series (cost=0.00..12.50 rows=1000 width=0) (actual time=0.579..7.934 rows=5000 loops=1)
Total runtime: 8.207 ms
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) (actual time=0.406..0.840 rows=5000 loops=1)
Total runtime: 1.078 ms
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Function Scan on generate_series (cost=0.00..260.00 rows=1000 width=0) (actual time=2.207..7790.519 rows=5000 loops=1)
Total runtime: 7791.658 ms
Je reproduis le bug sur une install from scratch de debian/jessie (autre serveur de test/dev installé fin avril).
Ca semble donc déja exclure un bug de migration de distrib wheezy->jessie...
Y'a-t-il un moyen de débugger ça plus en profondeur ?
Tout vient de la jessie:
aptitude search -F '%25V %p' '~i (^perl$|plperl|unaccent)'
1.08-1+b5 libtext-unaccent-perl
5.20.2-3+deb8u1 perl
9.4.3-0+deb8u1 postgresql-plperl-9.4
Bonjour,
Je fais des tests de migration pg9.1->9.4 (migration debian wheezy->jessie).
J'ai une fonction pour wrapper la fonction perl text::unaccent mais celle-ci fait carrément vautrer le serveur :-((
** Error in `postgres: postgres testperl [local] SELECT': free(): invalid pointer: 0x00007fc100000000 ***
2015-08-21 09:04:58 CEST [13653-77] LOG: processus serveur (PID 13503) a été arrêté par le signal 6 : Aborted
2015-08-21 09:04:58 CEST [13653-78] DÉTAIL: Le processus qui a échoué exécutait : SELECT unaccent('utf-8','_');
2015-08-21 09:04:58 CEST [13653-79] LOG: arrêt des autres processus serveur actifs
2015-08-21 09:04:58 CEST [14091-1] postgres@[local] testperl [inconnu] FATAL: le système de bases de données est en cours de restauration
2015-08-21 09:04:58 CEST [12850-2] ATTENTION: arrêt de la connexion à cause de l'arrêt brutal d'un autre processus serveur
2015-08-21 09:04:58 CEST [12850-3] DÉTAIL: Le postmaster a commandé à ce processus serveur d'annuler la transaction
courante et de quitter car un autre processus serveur a quitté anormalement
et qu'il existe probablement de la mémoire partagée corrompue.
2015-08-21 09:04:58 CEST [12850-4] ASTUCE : Dans un moment, vous devriez être capable de vous reconnecter à la base de
données et de relancer votre commande.
2015-08-21 09:04:58 CEST [13653-80] LOG: tous les processus serveur se sont arrêtés, réinitialisation
2015-08-21 09:04:58 CEST [14092-1] LOG: le système de bases de données a été interrompu ; dernier lancement connu à 2015-08-21 08:56:43 CEST
2015-08-21 09:04:58 CEST [14092-2] LOG: le système de bases de données n'a pas été arrêté proprement ; restauration
automatique en cours
2015-08-21 09:04:58 CEST [14092-3] LOG: la ré-exécution commence à 0/61B0360
2015-08-21 09:04:58 CEST [14092-4] LOG: enregistrement de longueur nulle à 0/61B4F58
2015-08-21 09:04:58 CEST [14092-5] LOG: ré-exécution faite à 0/61B4F28
2015-08-21 09:04:58 CEST [14092-6] LOG: la dernière transaction a eu lieu à 2015-08-21 09:04:39.712487+02 (moment de la journalisation)
2015-08-21 09:04:58 CEST [13653-81] LOG: le système de bases de données est prêt pour accepter les connexions
2015-08-21 09:04:58 CEST [14096-1] LOG: lancement du processus autovacuum
Et en plus, il embarque toute la famille dans le tombeau !
La lib perl fonctionne bien hors postgresql:
$ cat test.perl
use Text::Unaccent;
print unac_string('utf-8','titanic ta mère');
$ perl test.perl
titanic ta mere
Pour reproduire:
create database testperl;
\c testperl
create extension plperlu;
CREATE or replace FUNCTION unaccent(the_charset text, the_string text) RETURNS text AS $_X$
use Text::Unaccent;
return unac_string($_[0],$_[1]);
$_X$
language plperlu;
SELECT unaccent('utf-8','');
unaccent
----------
(1 ligne)
Ca marche avec une chaine vide !
SELECT unaccent('utf-8','_');
la connexion au serveur a été coupée de façon inattendue
Le serveur s'est peut-être arrêté anormalement avant ou durant le
traitement de la requête.
La connexion au serveur a été perdue. Tentative de réinitialisation : Échec.
!>
Même avec un caractère "non utf8", ça plante !
J'ai un autre wrapper pour la fonction perl suivante:
use HTML::Entities;
return decode_entities($_[0]);
et celui ci fonctionne sans problème !
Une idée ?
Pages : 1