Pytong2015

26
SQL debug avec Django Rodolphe Quiédeville PyTong 2015 26 septembre 2015

Transcript of Pytong2015

Page 1: Pytong2015

SQL debug avec Django

Rodolphe Quiédeville

PyTong 2015

26 septembre 2015

Page 2: Pytong2015

#mylife

I Admin/Sys tendance DevOps depuis 20 ansI Nourri au logiciel libre exclusivementI Python adepte depuis 10 ansI Consultant en performance des SI(G)I Senior Performance Engineer @PeopleDoc à temps partiel

Page 3: Pytong2015

2 mots sur PeopleDoc

I Dématérialisation des documents RHI Conservation des documents 50 ansI Dizaine de projets Django internesI 7 plateformesI 3 clusters PostgreSQL par plateformeI une centaine de bases de donnéesI 50 Millions de documents, +100% tous les ans

Page 4: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)I Instrumenter la productionI Proposer des pistes d’amélioration à la R&D basées sur

les mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 5: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)I Instrumenter la productionI Proposer des pistes d’amélioration à la R&D basées sur

les mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 6: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)

I Instrumenter la productionI Proposer des pistes d’amélioration à la R&D basées sur

les mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 7: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)I Instrumenter la production

I Proposer des pistes d’amélioration à la R&D basées surles mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 8: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)I Instrumenter la productionI Proposer des pistes d’amélioration à la R&D basées sur

les mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 9: Pytong2015

Démarche

Créer un cercle vertueux entre le métier, la R&D et laproduction

I Intervenir en développement au plus tôt (modification deschéma, nouvelles fonctionnalités, ...)

I Suivre le métier (nouveaux clients, import d’historique, ...)I Instrumenter la productionI Proposer des pistes d’amélioration à la R&D basées sur

les mesures de production (nouveaux index, ré-écriture derequêtes, ...)

I Anticiper la croissance et les nouvelles fonctionnalitésdemandées par le métier

Page 10: Pytong2015

Mise en oeuvre de la démarche

I sensibilisation à l’utilisation de DDT et query-inspectorI configuration des différentes briques pour identification des

sourcesI analyse des logs SQL des instances de testI analyse des logs SQL en intégrationI formation des dev à EXPLAINI tirs de performance tous les jours

I L’ORM n’est pas la solution ultime ni le mal absolu

Page 11: Pytong2015

Mise en oeuvre de la démarche

I sensibilisation à l’utilisation de DDT et query-inspectorI configuration des différentes briques pour identification des

sourcesI analyse des logs SQL des instances de testI analyse des logs SQL en intégrationI formation des dev à EXPLAINI tirs de performance tous les joursI L’ORM n’est pas la solution ultime ni le mal absolu

Page 12: Pytong2015

Problématique

Identifier la source des requêtes SQL relevées dans les logs deproduction avec pgbadger

SELECT "fish_fish"."id", "fish_fish"."title","fish_fish"."body", "fish_fish"."body_size","fish_fish"."title_size", "fish_fish"."lang_id","fish_fish"."lang"

FROM "fish_fish"

ORDER BY "fish_fish"."body" DESC

Page 13: Pytong2015

pgbadger

Page 14: Pytong2015

Les outils développés

Une offre logicielle insuffisante (pour qui ne manipule pas grep,awk, sed, ...)

I django-sql-logI pgstat

Page 15: Pytong2015

django-sql-log

Tracer dans les logs de la base de données la view source dela QuerySet.

I fournit un middleware configurableI log l’entrée et la sortie dans une vueI publié sur Github @Novafloss

Page 16: Pytong2015

django-sql-log

log de PostgreSQL

duration: 0.174 ms statement: BEGINduration: 0.502 ms statement: SET TIME ZONE ’UTC’duration: 0.053 ms statement: COMMITduration: 0.228 ms statement: SHOW default_transaction_isolationduration: 0.043 ms statement: BEGINduration: 0.354 ms statement: SELECT ’django_sql_log_demo.views.Index_START’duration: 1.221 ms statement: SELECT "dummy_article"."id", "dummy_article"."title", "dummy_article"."body" FROM "dummy_article"duration: 0.118 ms statement: SELECT ’django_sql_log_demo.views.Index_STOP’duration: 0.067 ms statement: ROLLBACKduration: 0.179 ms statement: BEGINduration: 0.513 ms statement: SET TIME ZONE ’UTC’duration: 0.054 ms statement: COMMITduration: 0.231 ms statement: SHOW default_transaction_isolation

Page 17: Pytong2015

pgstat

pgstat.py donne une vision de l’activité SQL

I script python monolithiqueI sortie standard parsableI pour PostgreSQL à partir de 9.4I basé sur l’extension pg_stat_statementI analyse les données des tables catalogueI nécessite un accés exclusif à la baseI développement en coursI utilisé chez PeopleDoc dans des jobs Jenkins/GatlingI publié sur gitlab.com:rodo/pg_tools.git

Page 18: Pytong2015

Rapport Gatling

Le rapport de Gatling comme source d’inspiration

================================================================================---- Global Information--------------------------------------------------------> request count 185 (OK=185 KO=0 )> min response time 13 (OK=13 KO=- )> max response time 3468 (OK=3468 KO=- )> mean response time 348 (OK=348 KO=- )> std deviation 278 (OK=278 KO=- )> response time 50th percentile 322 (OK=322 KO=- )> response time 75th percentile 431 (OK=431 KO=- )> mean requests/sec 1.84 (OK=1.84 KO=- )---- Response Time Distribution------------------------------------------------> t < 800 ms 184 ( 99%)> 800 ms < t < 1200 ms 0 ( 0%)> t > 1200 ms 1 ( 1%)> failed 0 ( 0%)================================================================================

Page 19: Pytong2015

pgstat

================================================================================pgstat start, version 1.4.3pgstat limit : 100pgstat ratio : 10================================================================================queries that returned more than 100 rows----------------------------------------1 ignored queries on 4 signaturescalls 10, rows 80090, rpc 8009.00 (rpc means rows per call)user : peopleask, sign 7887422347665ceddfe912ce7d0ad776--------------------------------------SELECT "user_right"."id", "user_right"."password","user_right"."is_superuser", "user_right"."username","user_right"."first_name", "user_right"."last_name","user_right"."email", "user_right"."is_staff","user_right"."is_active", "user_right"."date_joined","user_right"."language_code", "user_right"."user_type","user_right"."tech_id", "user_right"."timezone","user_right"."country_id" FROM "user_right" WHERE (NOT("user_right"."user_type" = ?) AND "user_right"."is_active" = ?)================================================================================pgstat status : KO================================================================================

Page 20: Pytong2015

Filtre manquant

Détection des requêtes sans clause WHERE

================================================================================queries without where clause----------------------------calls 2, rows 19458, rpc 9729.00 (rpc means rows per call)user : rodo, sign 6430b76b90ca0fa534d1cf382e535818--------------------------------------SELECT "fish_fish"."id", "fish_fish"."title" FROM"fish_fish"================================================================================calls 1, rows 9729, rpc 9729.00 (rpc means rows per call)user : rodo, sign 23e2a60edd4fdb127730b8150d352ffd--------------------------------------SELECT "fish_fish"."id", "fish_fish"."title","fish_fish"."body", "fish_fish"."body_size","fish_fish"."title_size", "fish_fish"."lang_id","fish_fish"."lang" FROM "fish_fish" ORDER BY"fish_fish"."body" DESC================================================================================

Page 21: Pytong2015

Indexation

Quelques statistiques de volumétrie (basées sur lesestimations de PostgreSQL)

================================================================================10 biggest tables--------------------------------------------------------------------------------indexes_tem 387973 publichotel_hotelcompany 110004 publicduck_duck 44000 publicplum_plum 38342 publichotel_hotel 30000 publicdali_fishon 20600 publicdali_fish_fishon 15223 publichotel_hotelskin 12090 publichotel_hoteldoor 12090 publichotel_hotelcolor 12090 public================================================================================

Page 22: Pytong2015

Statistiques

pour apprécier la lecture de

main stats, ratio=10------------------------------------------------------------pgstat rows total : 7591pgstat rows / qry : 759pgstat calls total : 79, limit 200 OKpgstat calls / qry : 7pgstat time total : 4547pgstat time / qry : 454, limit 3000 OKpgstat rows delta : 19pgstat rows deltap : 0.25%pgstat calls delta : 9pgstat calls deltap : 12.86%pgstat time delta : 524pgstat time deltap : 13.02%pgstat status : OK------------------------------------------------------------

Page 23: Pytong2015

Indexation

Colonnes qui méritent attention

------------------------------------------------------------column may be indexed---------------------score 260 for processes_task.action_needed_companyscore 120 for processes_task.action_done_employeescore 180 for processes_task.action_needed_employeescore 20 for user_right.user_typescore 30 for ticket_ticketvisibleby.need_actionscore 160 for processes_task.action_done_companyscore 10 for processes_process.published================================================================================pgstat stop

Page 24: Pytong2015

Autres informations

I statistiques par type de commande par utilisateurI queries with LIMIT 21 clause

Page 25: Pytong2015

Application name

Travail sur la configuration des workers avec supervisor,utilisation de l’application name de la libpq

I environment=PGAPPNAME=mytaskI log_line_prefix = ’%t user=%u,db=%d,app=%a ’ dans

postgresql.conf

Page 26: Pytong2015

Questions ?

On recrute

Rodolphe Quiédeville

[email protected]

Document publié sous Licence Creative Commons BY-SA 2.0