{"id":8001,"date":"2019-09-24T09:30:44","date_gmt":"2019-09-24T08:30:44","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=8001"},"modified":"2019-09-24T08:36:06","modified_gmt":"2019-09-24T07:36:06","slug":"postgresql-planifier-une-tache-avec-pg_cron","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/","title":{"rendered":"PostgreSQL : planifier une t\u00e2che avec pg_cron"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001&#038;title=PostgreSQL%20%3A%20planifier%20une%20t%C3%A2che%20avec%20pg_cron\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20%3A%20planifier%20une%20t%C3%A2che%20avec%20pg_cron&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-8004 size-full\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/Capture-d\u2019e\u0301cran-2016-02-10-a\u0300-11.46.56-e1455101531618.png\" alt=\"\" width=\"400\" height=\"289\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/Capture-d\u2019e\u0301cran-2016-02-10-a\u0300-11.46.56-e1455101531618.png 400w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/Capture-d\u2019e\u0301cran-2016-02-10-a\u0300-11.46.56-e1455101531618-300x217.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Hello<\/p>\n<p>nous avons vu auparavant, dans un <a href=\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\">pr\u00e9c\u00e9dent article<\/a> comment migrer une base Oracle vers PostgreSQL via un outil nomm\u00e9 ora2pg.<br \/>\nAu cours de cette migration, nous avons r\u00e9alis\u00e9 que certains packages Oracle ne pouvaient \u00eatre retranscrits pour PostgreSQL.<br \/>\nPar exemple, le package Oracle DBMS_JOB n&#8217;a pu \u00eatre migr\u00e9 sur l&#8217;instance PostgreSQL de destination. Il s&#8217;agit d&#8217;un package Oracle permettant de planifier des t\u00e2ches (proc\u00e9dures, ordres SQL, stats &#8230;.) qui seront ex\u00e9cut\u00e9es par le moteur Oracle.<\/p>\n<p>Il existe, pour PostgreSQL, une extension qui permet de faire ce travail au sein d&#8217;une instance PostgreSQL.<br \/>\nL&#8217;extension se nomme &#8220;pg_cron&#8221;.<\/p>\n<p>Cet article suit donc les \u00e9tapes de configuration qui permettront d&#8217;utiliser cette extension. Nous partirons d&#8217;un serveur Linux Debian avec une instance PostgreSQL 10.5.<\/p>\n<p>&nbsp;<\/p>\n<h2>Les extensions, qu&#8217;est ce donc ?<\/h2>\n<p>Une extension est un module compl\u00e9mentaire proposant un ensemble de proc\u00e9dures\/fonctions et tables permettant la gestion d&#8217;op\u00e9rations\u00a0 suppl\u00e9mentaires (ex pg_stat_statements, pg_cron, pgpsql\u2026.) en base.<\/p>\n<p>Ces modules, ou &#8220;plug-ins&#8221;,\u00a0 sont disponibles dans les \u00ab contribs \u00bb PostgreSQL (si installation depuis les d\u00e9p\u00f4ts syst\u00e8mes \u00ab yum \u00bb ou \u00ab aptitude \u00bb.<br \/>\nOu bien ces derniers seront \u00e0 t\u00e9l\u00e9charger sur le site postgresql :<\/p>\n<p><a href=\"https:\/\/www.postgresql.org\/download\/products\/6-postgresql-extensions\/\">https:\/\/www.postgresql.org\/download\/products\/6-postgresql-extensions\/<\/a><\/p>\n<p>Certaines extensions sont disponibles sur des sites communautaires\u00a0 comme Github , ex pour pg_cron :<\/p>\n<p><a href=\"https:\/\/github.com\/citusdata\/pg_cron\">https:\/\/github.com\/citusdata\/pg_cron<\/a><\/p>\n<p>&nbsp;<\/p>\n<h4><span style=\"color: #993366;\">Une extension : pg_cron<\/span><\/h4>\n<p>Cette extension, propos\u00e9e par Citusdata, permet de planifier des t\u00e2ches dans une instance PostgreSQL (le processus PostgreSQL s\u2019appuie sur la Crontab du serveur).<br \/>\nNous pourrons aller t\u00e9l\u00e9charger les sources depuis le site \u00ab github \u00bb par exemple.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8002 size-full\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/pg_cron.png\" alt=\"\" width=\"813\" height=\"193\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/pg_cron.png 813w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/pg_cron-300x71.png 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/pg_cron-768x182.png 768w\" sizes=\"auto, (max-width: 813px) 100vw, 813px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Il faudra ensuite dezipper le fichier sur un emplacement de destination sur le serveur.<\/p>\n<p>La plupart des extensions PostgreSQL sont \u00e9crites en C, il est donc imp\u00e9ratif de disposer d\u2019un compilateur C (gcc)<\/p>\n<h3><span style=\"color: #993366;\">Installation<\/span><\/h3>\n<p>Le contenu du zip pour cette extension, est le suivant. Attention, v\u00e9rifier qu&#8217;il s&#8217;agit bien de la version 1.2 ou &lt;, car celle ci est bien plus compl\u00e8te que les anciennes.<\/p>\n<p>&nbsp;<\/p>\n<pre>postgres@:~\/ora2pg\/REF\/sources\/pg_cron_master$ pg_cron-master]$ ls -l\r\ndrwxr-xr-x. 2 postgres postgres   95 Aug 28 12:19 src\r\ndrwxr-xr-x. 2 postgres postgres   30 Aug 28 12:19 sql\r\n-rw-r--r--. 1 postgres postgres 6293 Aug 28 12:19 README.md\r\n-rw-r--r--. 1 postgres postgres 2034 Aug 28 12:19 pg_cron.sql\r\n-rw-r--r--. 1 postgres postgres  121 Aug 28 12:19 pg_cron.control\r\n-rw-r--r--. 1 postgres postgres  155 Aug 28 12:19 pg_cron--1.1--1.2.sql\r\n-rw-r--r--. 1 postgres postgres  101 Aug 28 12:19 pg_cron--1.0--1.1.sql\r\n-rw-r--r--. 1 postgres postgres 1335 Aug 28 12:19 META.json\r\n-rw-r--r--. 1 postgres postgres  812 Aug 28 12:19 Makefile\r\n-rw-r--r--. 1 postgres postgres  918 Aug 28 12:19 LICENSE\r\ndrwxr-xr-x. 2 postgres postgres  136 Aug 28 12:19 include\r\n-rw-r--r--. 1 postgres postgres 4139 Aug 28 12:19 github-banner.png\r\ndrwxr-xr-x. 2 postgres postgres   30 Aug 28 12:19 expected\r\n-rw-r--r--. 1 postgres postgres 1632 Aug 28 12:19 CHANGELOG.md<\/pre>\n<p>&nbsp;<\/p>\n<p>Il s&#8217;agira maintenant de compiler nos sources.<\/p>\n<pre>postgres@:~\/ora2pg\/REF\/sources\/pg_cron_master$ <span style=\"color: #ff0000;\"><strong>make<\/strong><\/span>\r\ngcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security \r\n-fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2 -g -pipe -Wall \r\n-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches \r\n-specs=\/usr\/lib\/rpm\/redhat\/redhat-hardened-cc1 -specs=\/usr\/lib\/rpm\/redhat\/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables \r\n-fstack-clash-protection -fcf-protection -fPIC -std=c99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-maybe-uninitialized \r\n-I\/usr\/include -I. -I.\/ -I\/usr\/include\/pgsql\/server -I\/usr\/include\/pgsql\/internal  -D_GNU_SOURCE -I\/usr\/include\/libxml2   \r\n-c -o src\/pg_cron.o src\/pg_cron.c \u2026\u2026\u2026\u2026.\r\n\r\n<\/pre>\n<p>D\u00e8s \u00e0 pr\u00e9sent, nous voyons notre librairie &#8220;pg_cron.so&#8221; ainsi construite sur le r\u00e9pertoire courant.<\/p>\n<pre>postgres@:~\/ora2pg\/REF\/sources\/pg_cron_master $ ls -l\r\n-rw-r--r--. 1 postgres postgres   1632 Aug 28 12:19 CHANGELOG.md\r\ndrwxr-xr-x. 2 postgres postgres     30 Aug 28 12:19 expected\r\n-rw-r--r--. 1 postgres postgres   4139 Aug 28 12:19 github-banner.png\r\ndrwxr-xr-x. 2 postgres postgres    136 Aug 28 12:19 include\r\n-rw-r--r--. 1 postgres postgres    918 Aug 28 12:19 LICENSE\r\n-rw-r--r--. 1 postgres postgres    812 Aug 28 12:19 Makefile\r\n-rw-r--r--. 1 postgres postgres   1335 Aug 28 12:19 META.json\r\n-rw-r--r--. 1 postgres postgres    101 Aug 28 12:19 pg_cron--1.0--1.1.sql\r\n-rw-r--r--. 1 postgres postgres   2034 Sep 16 15:18 pg_cron--1.0.sql\r\n-rw-r--r--. 1 postgres postgres    155 Aug 28 12:19 pg_cron--1.1--1.2.sql\r\n-rw-r--r--. 1 postgres postgres    121 Aug 28 12:19 pg_cron.control\r\n<span style=\"color: #cc99ff;\">-rwxr-xr-x. 1 postgres postgres 223096 Sep 16 15:18 pg_cron.so<\/span>\r\n-rw-r--r--. 1 postgres postgres   2034 Aug 28 12:19 pg_cron.sql\r\n-rw-r--r--. 1 postgres postgres   6293 Aug 28 12:19 README.md\r\ndrwxr-xr-x. 2 postgres postgres     30 Aug 28 12:19 sql\r\ndrwxr-xr-x. 2 postgres postgres    184 Sep 16 15:18 src\r\n\r\n<\/pre>\n<p>Cette nouvelle librairie devra \u00eatre propag\u00e9e aux librairies partag\u00e9es du serveur auxquelles PostgreSQL sait acc\u00e9der.<br \/>\nSeul le user &#8220;root&#8221; est habilit\u00e9 \u00e0 effectuer cette modification et \u00e9crire dans le r\u00e9pertoire \/usr.<\/p>\n<pre>root@:~\/ora2pg\/REF\/sources\/pg_cron_master # <span style=\"color: #ff0000;\"><strong>make install<\/strong><\/span>\r\nusr\/bin\/mkdir -p '\/usr\/lib64\/pgsql'\r\n\/usr\/bin\/mkdir -p '\/usr\/share\/pgsql\/extension'\r\n\/usr\/bin\/mkdir -p '\/usr\/share\/pgsql\/extension'\r\n\/usr\/bin\/install -c -m 755  pg_cron.so '\/usr\/lib64\/pgsql\/pg_cron.so'\r\n\/usr\/bin\/install -c -m 644 .\/\/pg_cron.control '\/usr\/share\/pgsql\/extension\/'\r\n\/usr\/bin\/install -c -m 644 .\/\/pg_cron--1.0--1.1.sql .\/\/pg_cron--1.1--1.2.sql pg_cron--1.0.sql '\/usr\/share\/pgsql\/extension\/'\r\n\r\n<\/pre>\n<p>Notre librairie &#8220;pg_cron&#8221; est donc install\u00e9e sur le r\u00e9pertoire &#8220;\/usr\/lib64\/pgsql\/&#8221;. Les fichiers SQL relatifs \u00e0 cette extension sont pr\u00e9sents dans &#8220;\/usr\/share\/pgsql\/extension&#8221;.<br \/>\nLes noms de ces r\u00e9pertoires peuvent vari\u00e9s en fonction de votre distribution Linux. L&#8217;installation de votre instance PostgreSQL aura \u00e9galement une influence sur le nom de ces r\u00e9pertoires, selon que vous ayez utilis\u00e9 les d\u00e9p\u00f4ts OS ou bien les sources du site &#8220;postgresql.org&#8221;.<\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"color: #993366;\">Configuration en base<\/span><\/h3>\n<p>Une fois install\u00e9e, partie OS, il faudra modifier les param\u00e8tres base de donn\u00e9es dans PostgreSQL afin de pouvoir utiliser cette extension.<br \/>\nLe fichier &#8220;postgresql.conf&#8221; devra indiquer les \u00e9l\u00e9ments suivants pour permettre la cr\u00e9ation de cette extension en base<\/p>\n<ul>\n<li>share_preload_libraries<\/li>\n<li>cron.database_name.<\/li>\n<\/ul>\n<pre>postgres@:~\/ora2pg\/REF\/sources\/pg_cron_master $ <strong>cd $PGDATA<\/strong>\r\npostgres@:\/data $ <strong>vi postgresql.conf<\/strong>\r\n....\r\nshared_preload_libraries = 'pg_cron'          # (change requires restart)\r\ncron.database_name = 'capdata'\r\n....\r\n\r\n<\/pre>\n<p>Le param\u00e8tre &#8220;shared_preload_libraries&#8221; peut contenir plusieurs entr\u00e9es (si plusieurs extensions utilis\u00e9es).<\/p>\n<p>Il faudra red\u00e9marrer l&#8217;instance PostgreSQL pour la prise en compte des modifications. Une fois red\u00e9marr\u00e9e, la log PostgreSQL doit indiquer les informations suivantes<\/p>\n<pre>2019-09-16 15:32:24.410 UTC [2262] LOG:  last completed transaction was at log time 2019-09-16 15:29:49.397743+00\r\n2019-09-16 15:32:24.430 UTC [2260] LOG:  database system is ready to accept connections\r\n2019-09-16 15:32:24.433 UTC [2268] LOG:  pg_cron scheduler started\r\n\r\n<\/pre>\n<p>Notre process pg_cron scheduler est UP. Il reste \u00e0 d\u00e9clarer l&#8217;extension sur notre base &#8220;capdata&#8221;.<\/p>\n<pre>postgresql@:~\/ora2pg\/REF $ <strong>psql -U capdata -d capdata<\/strong>\r\n\r\n&gt;  <span style=\"color: #ff0000;\">select name, setting, sourcefile from pg_settings where name ='shared_preload_libraries';<\/span>\r\n           name           |             setting             |                sourcefile\r\n--------------------------+---------------------------------+-------------------------------------------\r\n shared_preload_libraries | pg_cron\t\t            | \/data\/postgresql\/10\/main2\/postgresql.conf\r\n\r\n&gt; <span style=\"color: #ff0000;\">create extension pg_cron ;<\/span>\r\nCREATE EXTENSION\r\n\r\n\r\n&gt; s<span style=\"color: #ff0000;\">elect * from pg_extension;<\/span>\r\n extname            | extowner | extnamespace | extrelocatable | extversion |   extconfig   | extcondition\r\n--------------------+----------+--------------+----------------+------------+---------------+--------------\r\n plpgsql            |       10 |           11 | f              | 1.0        | NULL          | NULL\r\n pg_stat_statements |       10 |         2200 | t              | 1.6        | NULL          | NULL\r\n pgcrypto           |       10 |         2200 | t              | 1.3        | NULL          | NULL\r\n pg_cron            |       10 |         2200 | f              | 1.2        | {24695,24693} | {\"\",\"\"}\r\n\r\n<\/pre>\n<p>L&#8217;ordre de cr\u00e9ation de l&#8217;extension va d\u00e9clarer un nouveau sch\u00e9ma nomm\u00e9 &#8220;cron&#8221; puis jouer les scripts SQL de cr\u00e9ation des objets relatifs \u00e0 son utilisation.<\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"color: #993366;\">L&#8217;utilisation<\/span><\/h3>\n<p>Afin de programmer une t\u00e2che , nous utiliserons la proc\u00e9dure &#8220;schedule&#8221; pr\u00e9sente dans le sch\u00e9ma &#8220;cron&#8221; de notre base &#8220;capdata&#8221;.<\/p>\n<p>Le mod\u00e8le de planification d&#8217;une t\u00e2che est comme celui d&#8217;une crontab Linux :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-8009 size-full\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/crontab.gif\" alt=\"\" width=\"400\" height=\"162\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>L&#8217;exemple ci dessous cr\u00e9e une t\u00e2che qui va ins\u00e9rer une ligne dans la table &#8220;employes&#8221; chaque minute.<\/p>\n<pre>$ <strong>psql -U capdata -d capdata<\/strong>\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from employes;<\/span>\r\n nom | poste | date_entree | societe\r\n-----+-------+-------------+---------\r\n(0 rows)\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from cron.schedule('* * * * *',$$insert into employes values ('Manu','DBA',now(),'Capdata')$$);<\/span>\r\n schedule\r\n----------\r\n        3\r\n(1 row)\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\n jobid | schedule  |                          command                           | nodename  | nodeport | database | username | active\r\n-------+-----------+------------------------------------------------------------+-----------+----------+----------+----------+--------\r\n     3 | * * * * * | insert into employes values ('Manu','DBA',now(),'Capdata') | localhost |     5432 | capdata  | capdata  | t\r\n(1 row)\r\n\r\n<\/pre>\n<p>La table &#8220;job&#8221; que l&#8217;on interroge donne les renseignements sur les jobs en cours sur cette base, avec notamment les informations de connexions utilis\u00e9es par le processus de scheduling (host, port, database). On s&#8217;assure que notre table &#8220;employes&#8221; est bien aliment\u00e9e.<\/p>\n<pre><strong>$ psql -U capdata -d capdata<\/strong>\r\n&gt; <span style=\"color: #ff0000;\">select now();<\/span>\r\n              now\r\n-------------------------------\r\n 2019-09-18 15:22:03.419635+00\r\n(1 row)\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from employes;<\/span>\r\n nom  | poste | date_entree | societe\r\n------+-------+-------------+---------\r\n Manu | DBA   | 2019-09-18  | Capdata\r\n Manu | DBA   | 2019-09-18  | Capdata\r\n Manu | DBA   | 2019-09-18  | Capdata\r\n Manu | DBA   | 2019-09-18  | Capdata\r\n Manu | DBA   | 2019-09-18  | Capdata\r\n(5 rows)\r\n\r\n<\/pre>\n<p>On pourra \u00e9galement cr\u00e9er une t\u00e2che qui supprime les lignes sur cette table<\/p>\n<pre>&gt; <span style=\"color: #ff0000;\">select * from cron.schedule('* * * * *',$$delete from employes where nom='Manu'$$)<\/span>;\r\n schedule\r\n----------\r\n        4\r\n(1 row)\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\n jobid | schedule  |                          command                           | nodename  | nodeport | database | username | active\r\n-------+-----------+------------------------------------------------------------+-----------+----------+----------+----------+--------\r\n     3 | * * * * * | insert into employes values ('Manu','DBA',now(),'Capdata') | localhost |     5432 | capdata  | capdata  | t\r\n     4 | * * * * * | delete from employes where nom='Manu'                      | localhost |     5432 | capdata  | capdata  | t\r\n(2 rows)\r\n\r\n<\/pre>\n<p>On peut tout aussi bien supprimer ces t\u00e2ches via la proc\u00e9dure &#8220;unschedule&#8221;<\/p>\n<pre>&gt; <span style=\"color: #ff9900;\">select * from cron.unschedule(3);<\/span>\r\n\r\n&gt; <span style=\"color: #ff9900;\">select * from cron.unschedule(4);<\/span>\r\n\r\n&gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\njobid | schedule | command | nodename | nodeport | database | username | active\r\n-------+----------+---------+----------+----------+----------+----------+--------\r\n(0 rows)\r\n\r\n<\/pre>\n<p>Il est \u00e9galement possible de mettre en &#8220;pause&#8221; le process en allant modifier son \u00e9tat dans la table &#8220;job&#8221;. S&#8217;il l&#8217;on reprend notre ancien job de suppression de lignes<\/p>\n<pre>&gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\n jobid | schedule  |                command                | nodename  | nodeport | database | username | active\r\n-------+-----------+---------------------------------------+-----------+----------+----------+----------+--------\r\n     4 | * * * * * | delete from employes where nom='Manu' | localhost |     5432 | capdata  | capdata  | t\r\n(1 row)\r\n\r\n<\/pre>\n<p>On voit que la colonne &#8220;active&#8221; est en fait un bool\u00e9en qui d\u00e9finit si ce job est actif, ou non. Il s&#8217;agira alors de passer \u00e0 FALSE ce job afin qu&#8217;il ne soit plus effectu\u00e9, tout en conservant son utilisation si besoin par la suite.<\/p>\n<pre>&gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\njobid | schedule  |                 command               | nodename  | nodeport | database | username | active\r\n------+-----------+---------------------------------------+-----------+----------+----------+----------+--------\r\n    4 | * * * * * | delete from employes where nom='Manu' | localhost |     5432 | capdata  | capdata  | t\r\n(1 row)\r\n\r\n\r\n(postgres@[local]:5432) [capdata] &gt; <span style=\"color: #ff0000;\">update cron.job set active='f' where jobid=4;<\/span>\r\nUPDATE 1\r\n\r\n(postgres@[local]:5432) [capdata] &gt; <span style=\"color: #ff0000;\">select * from cron.job;<\/span>\r\njobid  | schedule  |               command                 | nodename  | nodeport | database | username | active\r\n-------+-----------+---------------------------------------+-----------+----------+----------+----------+--------\r\n     4 | * * * * * | delete from employes where nom='Manu' | localhost |   5432   | capdata  | capdata  | f\r\n(1 row)<\/pre>\n<p>&nbsp;<\/p>\n<p>On s&#8217;assure par la suite que la table &#8220;employes&#8221; ne subit plus de suppression.<\/p>\n<p>Afin d&#8217;avoir un visu sur tous les objets li\u00e9s \u00e0 cette extension, on peut interroger psql<\/p>\n<pre> &gt; <span style=\"color: #ff0000;\">\\dx+ pg_cron<\/span>\r\nObjets dans l'extension \u00ab pg_cron \u00bb\r\nDescription d'objet\r\n--------------------------------------\r\nfonction cron.job_cache_invalidate()\r\nfonction cron.schedule(text,text)\r\nfonction cron.unschedule(bigint)\r\nsch\u00e9ma cron\r\ns\u00e9quence cron.jobid_seq\r\ntable cron.job\r\n(6 lignes)<\/pre>\n<p>&nbsp;<\/p>\n<p>\ud83d\ude42<\/p>\n<p>Emmanuel RAMI<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001&#038;title=PostgreSQL%20%3A%20planifier%20une%20t%C3%A2che%20avec%20pg_cron\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PostgreSQL%20%3A%20planifier%20une%20t%C3%A2che%20avec%20pg_cron&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F8001\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Hello nous avons vu auparavant, dans un pr\u00e9c\u00e9dent article comment migrer une base Oracle vers PostgreSQL via un outil nomm\u00e9 ora2pg. Au cours de cette migration, nous avons r\u00e9alis\u00e9 que certains packages Oracle ne pouvaient \u00eatre retranscrits pour PostgreSQL. Par&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":32,"featured_media":8004,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,266],"tags":[],"class_list":["post-8001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-non-classe","category-postgresql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Hello nous avons vu auparavant, dans un pr\u00e9c\u00e9dent article comment migrer une base Oracle vers PostgreSQL via un outil nomm\u00e9 ora2pg. Au cours de cette migration, nous avons r\u00e9alis\u00e9 que certains packages Oracle ne pouvaient \u00eatre retranscrits pour PostgreSQL. Par&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-24T08:30:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-24T07:36:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/Capture-d\u2019e\u0301cran-2016-02-10-a\u0300-11.46.56-e1455101531618.png\" \/>\n\t<meta property=\"og:image:width\" content=\"400\" \/>\n\t<meta property=\"og:image:height\" content=\"289\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Emmanuel RAMI\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Emmanuel RAMI\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\"},\"author\":{\"name\":\"Emmanuel RAMI\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\"},\"headline\":\"PostgreSQL : planifier une t\u00e2che avec pg_cron\",\"datePublished\":\"2019-09-24T08:30:44+00:00\",\"dateModified\":\"2019-09-24T07:36:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\"},\"wordCount\":871,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"articleSection\":{\"1\":\"PostgreSQL\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\",\"name\":\"PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2019-09-24T08:30:44+00:00\",\"dateModified\":\"2019-09-24T07:36:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL : planifier une t\u00e2che avec pg_cron\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\",\"name\":\"Emmanuel RAMI\",\"sameAs\":[\"https:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/","og_locale":"fr_FR","og_type":"article","og_title":"PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG","og_description":"Hello nous avons vu auparavant, dans un pr\u00e9c\u00e9dent article comment migrer une base Oracle vers PostgreSQL via un outil nomm\u00e9 ora2pg. Au cours de cette migration, nous avons r\u00e9alis\u00e9 que certains packages Oracle ne pouvaient \u00eatre retranscrits pour PostgreSQL. Par&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2019-09-24T08:30:44+00:00","article_modified_time":"2019-09-24T07:36:06+00:00","og_image":[{"width":400,"height":289,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/09\/Capture-d\u2019e\u0301cran-2016-02-10-a\u0300-11.46.56-e1455101531618.png","type":"image\/png"}],"author":"Emmanuel RAMI","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Emmanuel RAMI","Dur\u00e9e de lecture estim\u00e9e":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/"},"author":{"name":"Emmanuel RAMI","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae"},"headline":"PostgreSQL : planifier une t\u00e2che avec pg_cron","datePublished":"2019-09-24T08:30:44+00:00","dateModified":"2019-09-24T07:36:06+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/"},"wordCount":871,"commentCount":2,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"articleSection":{"1":"PostgreSQL"},"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/","url":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/","name":"PostgreSQL : planifier une t\u00e2che avec pg_cron - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2019-09-24T08:30:44+00:00","dateModified":"2019-09-24T07:36:06+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL : planifier une t\u00e2che avec pg_cron"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae","name":"Emmanuel RAMI","sameAs":["https:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8001","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=8001"}],"version-history":[{"count":15,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8001\/revisions"}],"predecessor-version":[{"id":8284,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/8001\/revisions\/8284"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/8004"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=8001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=8001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=8001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}