Le 15 septembre, une rĂ©union s'est tenue Ă Avito, oĂč nous avons discutĂ© de la mise Ă l'Ă©chelle des applications sur PostgreSQL. Aujourd'hui, je veux partager des documents de lui - vidĂ©os, prĂ©sentations de confĂ©renciers, montrer des photos. Aussi, sous la coupe, je publie une discussion sur les questions du quiz que nous avons menĂ©es ici sur HabrĂ©, avant le mitap. Et je parle de mes impressions sur la rĂ©union.

Rapports
Transactions distribuées et voyages dans le temps. Stas Kelvich, Postgres Professional
Stas a parlé des transactions distribuées et des voyages dans le temps.
Présentation
Avis:
Stas et son équipe ont fait un excellent travail! J'espÚre que leur communauté approuvera leur décision et nous verrons cette solution dans la nouvelle version de Postgres.
Mise à l'échelle d'une application sur PostgreSQL dans Avito: trucs et astuces. Konstantin Evteev, Avito
J'ai fait une présentation sur la mise à l'échelle d'une application sur PostgreSQL dans Avito et partagé nos conseils et astuces.
Présentation
Avis:
Une approche intéressante: dans laquelle Kostantin a expliqué de maniÚre trÚs intéressante et intelligible quels problÚmes vous pourriez rencontrer lorsque vous travaillez avec des données dans une architecture de microservice, et a également suggéré des solutions pour faire évoluer l'IP. On se souvient de la saga :)
Niveaux de réplication logique et d'isolement des transactions PostgreSQL. Mikhail Tyurin
Michael a préparé un rapport sur la réplication logique et les niveaux d'isolement des transactions PostgreSQL.
Présentation
Avis:
Michael a soulignĂ© les moments subtils des transactions, qui sont loin d'ĂȘtre immĂ©diatement visibles non seulement pour les dĂ©butants. Tout le monde doit savoir cela.
OZO est une bibliothÚque client PostgreSQL asynchrone de type sécurisé uniquement pour C ++ 17. Sergey Handrikov, Yandex
Sergey a expliqué au public comment OZO, la bibliothÚque cliente PostgreSQL asynchrone de type sécurisé uniquement pour C ++ 17 est organisée, et a été invité à y contribuer.
Présentation
Avis:
L'auteur, à mon avis, a réussi à révéler rapidement les problÚmes dans les bibliothÚques existantes et les solutions dans les nouvelles bibliothÚques C ++ en peu de temps. Par conséquent, je serai heureux si ces bibliothÚques sont développées en open source, les choses les plus basiques sont déjà implémentées, ce qui ne peut que se réjouir.
Réponses aux questions du quiz
Avant la rĂ©union, nous vous avons invitĂ© Ă rĂ©pondre aux questions sur Postgres. Aujourd'hui, je veux montrer les bonnes rĂ©ponses. Ils sont sous les spoilers (juste au cas oĂč).
Il existe une table vide sans enregistrements d'utilisateurs ("UserId" int, "balance" int). Que renverra Ă la suite de la requĂȘte?
with ins as ( insert into users select gs, gs * 10 from generate_series(1, 4) gs where gs%2 = 0) select * from users;
Ce qui renverra la demande, select * from users where UserId = 10;
lors de l'accÚs à la table des utilisateurs aprÚs avoir terminé le travail précédent?
La réponseERREUR: la colonne "id_utilisateur" n'existe pas.
Défini par Enum CREATE TYPE status AS ENUM ('wait', 'init', 'run', 'stop'); Quelle commande peut supprimer la valeur de 'init'?
La réponseIl n'existe aucun moyen standard de supprimer une valeur d'énumération.
Comment obtenir une liste de fonctions dans PostgreSQL?
La réponsesélectionnez * From pg_proc;
Que renverra Ă la suite de la requĂȘte?
select null = null, null is null, 1::smallint::boolean is true, null::bigint > 1
La réponseERREUR: impossible de convertir le type smallint en booléen.
Le dĂ©veloppeur junior Vasya a Ă©tĂ© chargĂ© d'Ă©crire une requĂȘte qui affiche toutes les entrĂ©es de la table parent
pour lesquelles il n'y a aucune entrée dans la table child
.
Schéma de données:
create table parent (parent_id serial primary key, payload text); create table child (child_id serial primary key, parent_id integer unique references parent (parent_id));
Vasya a essayĂ© trĂšs fort et ne voulait pas faire face Ă la saletĂ©, il a donc trouvĂ© huit requĂȘtes diffĂ©rentes pour rĂ©soudre le problĂšme:
-- 0 select p.parent_id, p.payload from parent p where not exists(select from child c where c.parent_id = p.parent_id); -- 1 select p.parent_id, p.payload from parent p where not (array[p.parent_id] && array(select c.parent_id from child c)); -- 2 select distinct p.parent_id, p.payload from parent p full join child c on (c.parent_id = p.parent_id) where c.parent_id is null; -- 3 select p.parent_id, p.payload from parent p where p.parent_id not in (select c.parent_id from child c); -- 4 select p.parent_id, p.payload from parent p left join child c on (c.parent_id = p.parent_id) where c.parent_id is null; -- 5 with w_child_with_parents as ( select c.parent_id, ( select count(*) from parent p where c.parent_id = p.parent_id) = 1 as parent_exists from child c) select p.parent_id, p.payload from parent p where p.parent_id in (select pc.parent_id from w_child_with_parents pc where not pc.parent_exists); -- 6 select p.parent_id, p.payload from parent p full join child c on (c.parent_id = p.parent_id) group by p.parent_id, p.payload having count(c) = 0; -- 7 select p.parent_id, p.payload from parent p where p.parent_id in ( select p2.parent_id from parent p2 except all select c2.parent_id from child c2);
Vasya vous a prĂ©sentĂ© ses options afin que vous puissiez l'aider Ă choisir la meilleure. Il affirme que toutes les requĂȘtes fonctionnent de la mĂȘme maniĂšre: les tables sont placĂ©es en mĂ©moire et la diffĂ©rence de performances n'est pas significative (ni mĂȘme invisible). Cependant, en tant que dĂ©veloppeur plus expĂ©rimentĂ©, vous avez remarquĂ© que toutes les demandes ne rĂ©solvent peut-ĂȘtre pas la tĂąche. ĂnumĂ©rez les requĂȘtes qui ne rĂ©solvent pas la tĂąche (et expliquez pourquoi).
Réponse courteLes tùches 2, 3 et 5 ne résolvent pas ce problÚme (dans certains cas, demandez également 1).
La réponse au résultat de l'expérienceDonnées de test:
Le «caractÚre incorrect» du comportement se manifeste lorsqu'il existe des enregistrements dans la table enfant avec parent_id est null.
insert into parent (parent_id, payload) values (1, 'payload 1'), (2, 'payload 2'), (3, 'payload 3'), (4, 'payload 4'), (5, 'payload 5'); insert into child (child_id, parent_id) values (1, 1), (2, 3), (3, null), (5, 5);
Sur les données de test données
- La requĂȘte 1, selon que l'extension intarray est installĂ©e, peut ou non fonctionner.
- La requĂȘte 2 renvoie une chaĂźne supplĂ©mentaire (null, null).
- Les requĂȘtes 3 et 5 renvoient un jeu de rĂ©sultats vide.
Interprétation des résultats expérimentaux
RequĂȘte 1: si l'extension intarray est installĂ©e dans la base de donnĂ©es ( https://www.postgresql.org/docs/current/static/intarray.html ), la requĂȘte se bloque avec l'erreur "ERREUR: le tableau ne doit pas contenir de null". Ce comportement est dĂ» au fait que l'extension remplace les opĂ©rateurs standard et modifie le comportement des tableaux contenant des Ă©lĂ©ments nuls.
La documentation indique ce qui suit:
Les opĂ©rateurs &&, @> et <@ sont Ă©quivalents aux opĂ©rateurs intĂ©grĂ©s PostgreSQL des mĂȘmes noms, sauf qu'ils ne fonctionnent que sur des tableaux entiers qui ne contiennent pas de valeurs nulles, tandis que les opĂ©rateurs intĂ©grĂ©s fonctionnent pour tout type de tableau. Cette restriction les rend plus rapides que les opĂ©rateurs intĂ©grĂ©s dans de nombreux cas.
RequĂȘte 2: en raison d'une jointure complĂšte, une chaĂźne supplĂ©mentaire (null, null) apparaĂźt en consĂ©quence.
RequĂȘte 3: renvoie un jeu de rĂ©sultats vide car le jeu formĂ© par la sous-requĂȘte a des Ă©lĂ©ments nuls.
Documentation ( https://www.postgresql.org/docs/current/static/functions-subquery.html#FUNCTIONS-SUBQUERY-NOTIN ):
Notez que si l'expression de gauche donne null, ou s'il n'y a pas de valeurs égales à droite et qu'au moins une ligne de droite donne null, le résultat de la construction NOT IN sera nul, pas vrai. Ceci est conforme aux rÚgles normales de SQL pour les combinaisons booléennes de valeurs nulles.
RequĂȘte 5: renvoie un ensemble de rĂ©sultats vide car la section w_child_with_parents est appelĂ©e, les tables enfant et parent_id sont vides ou ne sont pas du tout reflĂ©tĂ©es dans la section.
Toutes les questions du quiz ont été correctement répondues par trois participants. Nous en avons remis un au prix lors de la réunion, deux autres ensembles de souvenirs ont été envoyés par la poste.

Postface
Plus d'une centaine de personnes sont venues Ă la rĂ©union. C'Ă©tait trĂšs agrĂ©able de rencontrer un tel public. Selon une enquĂȘte, plus de 60% des clients mitap ont une expĂ©rience de travail avec les bases de donnĂ©es depuis plus de cinq ans. Et c'est trĂšs agrĂ©able lorsque les reportages reçoivent une rĂ©action aussi vive du public:

En marge des rĂ©unions, il a Ă©tĂ© beaucoup question que PostgreSQL devienne un outil de plus en plus courant. Ăa l'est vraiment. Je profite de l'occasion pour dire que nous, Ă Avito, prĂ©voyons d'Ă©largir l'Ă©quipe DBA, et si vous ĂȘtes intĂ©ressĂ© par des tĂąches ambitieuses sur un grand projet, consultez le poste vacant sur My Circle ou Ă©crivez-moi.

En conclusion, je tiens à remercier mes collÚgues de Yandex, Postgres Professional et, bien sûr, Avito pour les merveilleux rapports que nous avons entendus. Merci aux invités qui sont venus nous voir ce samedi et aux téléspectateurs en direct. Et bien sûr, la communauté #RuPostgres pour la confiance.
Playlist avec tous les rapports ici .
Nous avons publié des reportages photo sur Facebook et VKontakte .

A trĂšs bientĂŽt!