
{"id":4430,"date":"2023-09-13T08:58:15","date_gmt":"2023-09-13T08:58:15","guid":{"rendered":"https:\/\/test.opensource-db.in\/wp1\/?p=4430"},"modified":"2023-09-13T08:58:16","modified_gmt":"2023-09-13T08:58:16","slug":"postgres-beyond-the-basics-exploring-extensibility-part-iii","status":"publish","type":"post","link":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/","title":{"rendered":"Postgres Beyond the Basics: Exploring Extensibility &#8211; Part III"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\" alt=\"\" class=\"wp-image-4439\" srcset=\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png 1024w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-300x158.png 300w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-768x404.png 768w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-188x99.png 188w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-152x80.png 152w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-394x207.png 394w, https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image-915x481.png 915w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the earlier posts, we\u2019ve had an <a href=\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility\/\">Overview of Postgres Extensions<\/a>, and we\u2019ve also looked at the <a href=\"https:\/\/test.opensource-db.in\/wp1\/introducing-pg_cron-the-automation-task-master\/\">pg_cron<\/a> extension in some detail. In today\u2019s post, we shall examine the pg_stat_statements, pgstattuple, and pg_buffercache extensions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using pg_stat_statements extension<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>pg_stat_statements<\/code> view is a valuable PostgreSQL extension that offers insights into the execution statistics of SQL statements processed by the PostgreSQL server. This information can be instrumental in identifying and addressing performance issues within your database system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can leverage the <code>pg_stat_statements<\/code> View in several ways to trace and tackle performance problems:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Identifying Slow Queries:<\/strong> To pinpoint queries that consume significant time during execution, sort the view by the <code>total_time <\/code>column in descending order:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pg_stat_statements\nORDER BY total_time DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This reveals which queries are likely culprits for performance bottlenecks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Identifying Frequently Executed Queries:<\/strong> Use the<code> calls<\/code> column to discover queries that are executed frequently. These queries may not individually be time-consuming, but their high frequency can impact performance:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pg_stat_statements\nORDER BY calls DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Addressing frequently executed queries is crucial for overall system optimization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Analyzing Resource Usage:<\/strong> By examining the<code> rows <\/code>and <code>memory <\/code>columns, you can determine which queries consume significant resources. Queries with high <code>row<\/code> values process substantial data, while those with high <code>memory<\/code> values utilize extensive memory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pg_stat_statements\nORDER BY rows DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pg_stat_statements\nORDER BY memory DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Identifying resource-intensive queries aids in resource management.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Detecting Query Plan Changes:<\/strong> The<code> plan_changes <\/code>column highlights queries that frequently alter their execution plans. Queries exhibiting many plan changes can pose optimization challenges for PostgreSQL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pg_stat_statements\nORDER BY plan_changes DESC;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Understanding such queries is essential for query plan stability.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once problematic queries are identified, you can harness the data from the <code>pg_stat_statements<\/code> view to scrutinize their execution plans. This analysis offers insights into the reasons behind slow performance and provides guidance on optimizing query execution for improved database efficiency.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using pgstattuple extension<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The pgstattuple module provides various functions to obtain tuple-level statistics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because these functions return detailed page-level information, access is restricted by default. By default, only the role <code>pg_stat_scan_tables <\/code>has <code>EXECUTE<\/code> privilege. Superusers of course bypass this restriction. After the extension has been installed, users may issue <code>GRANT <\/code>commands to change the privileges of the functions to allow others to execute them. However, it might be preferable to add those users to the <code>pg_stat_scan_tables <\/code>role instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create the extension using the CREATE EXTENSION command as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osdb=# CREATE EXTENSION pgstattuple;\nCREATE EXTENSION<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" width=\"290\" height=\"37\" src=\"https:\/\/lh3.googleusercontent.com\/2E-YfZB-we9y7KGXtUM7Yvhm-NKrjNdKGu1rvS9o16O84w553YO1sGleXy2vpUkbrnNKi2EgdlCiXNUUQLNA__6yZjfJHJWAbxaD3vdVLUxp-AYEieYZH0-iXYvz1yWecXpFVk0GJdEiJ1eh2sLvs3Pex-ne_UKA\" alt=\"C:\\Users\\lenovo\\Desktop\\create_pgstattupple.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can check the installed pgstattuple extension from the <code>PSQL <\/code>prompt as follows:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" width=\"538\" height=\"86\" src=\"https:\/\/lh5.googleusercontent.com\/ym8GG6nw2ctwjfUQNUiL6P_g6Uhs7RsPn8Wraxa11Yp4R-eQpaRzca578YswKWy8oUWuuCMq8tL2WQ6Q7zzYKRMweI-kRGKiJC12-4hP4PMrZZTJkO9KcsW37kAL6B72DRgJu7V95BYGfWZKNqrS3frxXiHzcMQC\" alt=\"C:\\Users\\lenovo\\Desktop\\pgstattupple_dx.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">pgstattuple returns a relation&#8217;s physical length, percentage of \u201cdead\u201d tuples, and other info. This may help users determine whether a vacuum is necessary or not. The argument is the target relation&#8217;s name (optionally schema-qualified) or OID.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For example:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a table named &#8216;t1&#8217; and insert 10,000 rows of random data into the &#8216;t1&#8217; table using the following SQL commands.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osdb=# CRATE TABLE t1 (id int, name varchar);\nCREATE TABLE\nosdb=#INSERT INTO t1 SELECT generate_series (1,10000),md5(generate_series(1,10000)::text);\nINSERT 0 10000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"372\" height=\"34\" src=\"https:\/\/lh6.googleusercontent.com\/LrjTzCAD0bb6mbNHTbPfL_vU67iX_7Sof738p5fMPi9w_JqiBcrLZhxMonYgu3pQgY5eP0b_e247Cq2QtvMas7JKsM8LHPfIWvPFrLqZ1PdYHBtuA87NprbGBVBcv0pDVL88fL8rkArkd9EbrbI3EOxHvzD0n-AD\" alt=\"C:\\Users\\lenovo\\Desktop\\create_table_t1.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"33\" src=\"https:\/\/lh3.googleusercontent.com\/DpVFdQTFGEcxHvekfl9V0RXQrS4OMQHjlHDJyjO5qKjPOYm7bnlktWRYcdDkHO6jB2dy0b47190y3th3EPtks8RiRDUEC62lwl8Ih5mspAHpl332akkA_fDeBq3GGSESV0ZN9ynZyM96B4hntUrEealhG1fxkq5A\" alt=\"C:\\Users\\lenovo\\Desktop\\insert_into_t1.png\"><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/DpVFdQTFGEcxHvekfl9V0RXQrS4OMQHjlHDJyjO5qKjPOYm7bnlktWRYcdDkHO6jB2dy0b47190y3th3EPtks8RiRDUEC62lwl8Ih5mspAHpl332akkA_fDeBq3GGSESV0ZN9ynZyM96B4hntUrEealhG1fxkq5A\" alt=\"C:\\Users\\lenovo\\Desktop\\insert_into_t1.png\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We can check the table t1 tuple data as following<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"314\" height=\"193\" src=\"https:\/\/lh4.googleusercontent.com\/JwwEal0_01FvDOlBQbHTTGO_RpwHSvMyKhk6RTgES9i48AJYujxOFJpiaNBJcWXGjym-sxRZnT2jj2Gnzj5rVu5I---styTmhdL4iu2WPuOAarO7lQIHc-GiB1Ot2zdhHBHpvQn8ebHLtsI0cQtv95MD4ngHg2HV\" alt=\"C:\\Users\\lenovo\\Desktop\\t1_tupples_data.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Delete a portion of the data from the &#8216;t1&#8217; table to intentionally generate some dead tuples.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"418\" height=\"40\" src=\"https:\/\/lh5.googleusercontent.com\/HyUugXvr8CMM8gALlz2SLoHlTvOa8jwoP7x_VUwHAlLbEQARbINIBWRrZL44YLuyBsy1datSZKhw5dmvUxW_cbZWZKem7Fz51_EcRAJ--xG7hrpgwHPa6fO7IfXZFVgXI-NRf_PcEyNsmIcF_YVIsXln9TRkfXe2\" alt=\"C:\\Users\\lenovo\\Desktop\\del_some_rows.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can assess table-level bloat by executing the following command:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"318\" height=\"214\" src=\"https:\/\/lh3.googleusercontent.com\/SgRkIswG50YZ-haUa8xRWhxxUlgr-DxCWvFkYZ5_ujGefBDAVy9rFtj6so8w3-6SYZhl72QYT3c7TH48z3LDL3_XBGEL_OaKkqJ6HRwAjaTxU58Mro3qp2fmGp3jrkU1bcgsRlSD2Rfr8zZZrR-LWFuBigDeIQRD\" alt=\"C:\\Users\\lenovo\\Desktop\\after_delete_rows.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To reclaim space and remove dead tuples, you can perform an <code>VACUUM <\/code>operation on the &#8216;t1&#8217; table. This will free up space previously occupied by the dead tuples.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"141\" height=\"38\" src=\"https:\/\/lh3.googleusercontent.com\/vlpFdRCTGYP6vh9CMwz_kIZjQwUW2Ojrvzh4WvSMdf8wsxcDWTucYLsc2kJKIOioEIW2aAt_glht6myzwu2JY4PqGyo7NeRocc327wpqeANwVRpM3lZ9DGLpGO61HezSjyO2jsW_He0Fl031YjwkZiYBWcI8Gzxi\" alt=\"C:\\Users\\lenovo\\Desktop\\vacuum.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we can check the dead tuple count, length, and percentage after completion of the vacuum.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This free space can now be used to store new rows inside your table.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"316\" height=\"193\" src=\"https:\/\/lh3.googleusercontent.com\/KXNbYBBeS6h6OFGKy7zDOZcYkvKc67VNOPfe64ZrXvwAMI8YYjZ4k4q30wyGZF2iu_76keJeM4323zxI1M41NhOFrU_PuAqlNVBCO0Ad5TZoQSMSeiOu3wA7Si6mDrgSHMdIwyESo2JGvQlqXqBKNGPYCxvjWVe_\" alt=\"C:\\Users\\lenovo\\Desktop\\after_vacuum.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Conclusion:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, we have demonstrated the process for checking and addressing bloat in a single table. You can now apply sorting and filtering techniques as needed to identify and address bloat in other tables within your PostgreSQL database.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using pg_buffercache extension<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The pg_buffercache module provides a means for examining what&#8217;s happening in the shared buffer cache in real-time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create the extension using the<code> CREATE EXTENSION <\/code>command as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osdb=# create extension pg_buffercache;\nCREATE EXTENSION<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"330\" height=\"38\" src=\"https:\/\/lh5.googleusercontent.com\/icxfMQg-h9Z9EFTM1Gf5-VXOJ8-yUQYH3BaG-ZwXIUfX3TSMd5UM82GtjnmRuQdZVxF1asbscls691HDHyHmhi0We5ZDAj7g9hd0OccVLpIOlG23bY78OW2XLmZAMXi7ZVcTEZbFXBj7dywlHAQBiPOtyRgfpQKL\" alt=\"C:\\Users\\lenovo\\Desktop\\create_buffer_ext.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can check the installed extension from the <code>PSQL<\/code> prompt as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osdb=# \\dx pg_buffercache <\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>                    List of installed extensions\n      Name      | Version | Schema |           Description           \n----------------+---------+--------+---------------------------------\n pg_buffercache | 1.3     | public | examine the shared buffer cache\n\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"561\" height=\"109\" src=\"https:\/\/lh6.googleusercontent.com\/4D7-ZQ8Ma3Vtjo2Fq6dzwN6U7lQ0kVsK4rhH1g0nxiD2r3_cjxzwQwzY68PCVhT2cfaF3COF0WMhEk4zheW8f_Y1Zp2tG5dOrhbVenKOlZubaU3VrsrJBAod1yYnGORAWqI82OzOYVUvS3-F_x641ydpCCtI7rc3\" alt=\"C:\\Users\\lenovo\\Desktop\\buffer_dx.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After the creation of the pg_buffercache extension, it will create a view called<code> pg_buffercache <\/code>with the following structure:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"229\" src=\"https:\/\/lh3.googleusercontent.com\/TCB6YJga6SqT28kgFKitQWbI5Eot8KMoYymoWo3NpihJKOO140EupaVMHo9xGojb_sL4vuRaqjgwxzUBLd5vmHXwpPgJv-_rc5p5t-bU412dqTTF7CFR6Fmd3Ey-5TeNwoC89_XJUG_j0tHcwJWrZgDYafT_t8Gs\" alt=\"C:\\Users\\lenovo\\Desktop\\buffer_view.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The view created after the installation of the extension called <code>pg_buffercache <\/code>has several columns.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>bufferid,<\/strong> the block ID in the server buffer cache<\/li>\n\n\n\n<li><strong>relfilenode,<\/strong> which is the folder name where data is located in relation<\/li>\n\n\n\n<li><strong>reltablespace,<\/strong> Oid of the tablespace relation uses<\/li>\n\n\n\n<li><strong>reldatabase,<\/strong> Oid of database where location is located<\/li>\n\n\n\n<li><strong>relforknumber,<\/strong> fork number within the relation<\/li>\n\n\n\n<li><strong>relblocknumber,<\/strong> age number within the relation<\/li>\n\n\n\n<li><strong>isdirty,<\/strong> true if the page is dirty<\/li>\n\n\n\n<li><strong>usagecount,<\/strong> page LRU (least-recently-used) count<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">With a configuration using 128MB of shared_buffers and an 8kB block size, PostgreSQL allocates 16,384 buffers in the shared buffer cache. Consequently, the pg_buffercache extension provides information on the same number of 16,384 rows, each representing a buffer in the cache.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The below query provides the number of buffers used by each relation of the current \u201cosdb\u201d database.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>osdb=# SELECT c.relname, count(*) AS buffers\nFROM pg_buffercache b INNER JOIN pg_class c\nON b.relfilenode = pg_relation_filenode(c.oid) AND\nb.reldatabase IN (0, (SELECT oid FROM pg_database\nWHERE datname = current_database()))\nGROUP BY c.relname\nORDER BY 2 DESC\nLIMIT 10;\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>            relname             | buffers \n--------------------------------+---------\n t1                             |      88\n pg_proc                        |      46\n pg_attribute                   |      34\n pg_statistic                   |      23\n pg_type                        |      19\n pg_class                       |      17\n pg_depend                      |      15\n pg_depend_reference_index      |      15\n pg_operator                    |      14\n pg_proc_proname_args_nsp_index |      14\n(10 rows)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"358\" src=\"https:\/\/lh3.googleusercontent.com\/Dci0Lbqhx1FLBhRDF86lOI385hu0_BScbI0HfAq8Ffz9TWGBkMXsoMeupUPOnT7Bxj7WD4b65cnRHO4CidZYvGWX3s6_pBkKhAaqOPaXRsU90IgPZKHiOFGQRBXECWOTNtg9qFIwVhBOq98iRVIpoKerOJq13Ar6\" alt=\"C:\\Users\\lenovo\\Desktop\\buffer_ouput.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As part of this series, below are a couple of other blog posts we&#8217;ve posted before:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility\/\" target=\"_blank\" rel=\"noreferrer noopener\">Postgres Beyond the Basics: Exploring Extensibility<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/test.opensource-db.in\/wp1\/introducing-pg_cron-the-automation-task-master\/\" target=\"_blank\" rel=\"noreferrer noopener\">Introducing pg_cron \u2013 The Automation task master<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Conclusion:<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>pg_stat_statements<\/code>, <code>pgstattuple,<\/code> and <code>pg_buffercache <\/code>are powerful extensions for PostgreSQL that aid in fine-tuning your database system, optimizing query performance, and ensuring efficient memory usage. They would serve as a valuable addition to your toolkit for database management and optimization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the earlier posts, we\u2019ve had an Overview of Postgres Extensions, and we\u2019ve also looked at the pg_cron extension in [&hellip;]<\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[23,42],"tags":[88,86,87],"class_list":["post-4430","post","type-post","status-publish","format-standard","hentry","category-postgresql-14","category-postgresql-15","tag-extensions","tag-postgresql14","tag-postgresql15"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB\" \/>\n<meta property=\"og:description\" content=\"In the earlier posts, we\u2019ve had an Overview of Postgres Extensions, and we\u2019ve also looked at the pg_cron extension in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\" \/>\n<meta property=\"og:site_name\" content=\"OpenSource DB\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/people\/OpenSource-DB\/100072970755470\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-13T08:58:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-09-13T08:58:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\" \/>\n<meta name=\"author\" content=\"Venkat Akhil\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@opensource_db\" \/>\n<meta name=\"twitter:site\" content=\"@opensource_db\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Venkat Akhil\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\"},\"author\":{\"name\":\"Venkat Akhil\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/a37b142ecbf953189a4f9209b0b8d328\"},\"headline\":\"Postgres Beyond the Basics: Exploring Extensibility &#8211; Part III\",\"datePublished\":\"2023-09-13T08:58:15+00:00\",\"dateModified\":\"2023-09-13T08:58:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\"},\"wordCount\":830,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#organization\"},\"image\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\",\"keywords\":[\"extensions\",\"postgresql14\",\"postgresql15\"],\"articleSection\":[\"PostgreSQL 14\",\"PostgreSQL 15\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\",\"url\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\",\"name\":\"Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB\",\"isPartOf\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\",\"datePublished\":\"2023-09-13T08:58:15+00:00\",\"dateModified\":\"2023-09-13T08:58:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage\",\"url\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\",\"contentUrl\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png\",\"width\":1024,\"height\":538},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/test.opensource-db.in\/wp1\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Postgres Beyond the Basics: Exploring Extensibility &#8211; Part III\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#website\",\"url\":\"https:\/\/test.opensource-db.in\/wp1\/\",\"name\":\"OpenSource DB\",\"description\":\"Your Trusted OpenSource Databases partner\",\"publisher\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/test.opensource-db.in\/wp1\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#organization\",\"name\":\"OPENSOURCE DB PRIVATE LIMITED\",\"url\":\"https:\/\/test.opensource-db.in\/wp1\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2021\/10\/osdb-logo-tm-2.png\",\"contentUrl\":\"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2021\/10\/osdb-logo-tm-2.png\",\"width\":368,\"height\":120,\"caption\":\"OPENSOURCE DB PRIVATE LIMITED\"},\"image\":{\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/people\/OpenSource-DB\/100072970755470\/\",\"https:\/\/x.com\/opensource_db\",\"https:\/\/www.youtube.com\/channel\/UCmTI5h\",\"https:\/\/www.linkedin.com\/company\/opensource-db\",\"https:\/\/www.instagram.com\/opensource_db\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/a37b142ecbf953189a4f9209b0b8d328\",\"name\":\"Venkat Akhil\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/522c0947d21b2c2c89f10698fd9131f9db4110f65c8d02b53d9b4559c7650865?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/522c0947d21b2c2c89f10698fd9131f9db4110f65c8d02b53d9b4559c7650865?s=96&d=mm&r=g\",\"caption\":\"Venkat Akhil\"},\"url\":\"https:\/\/test.opensource-db.in\/wp1\/author\/sudheer-sopensource-db-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB","og_description":"In the earlier posts, we\u2019ve had an Overview of Postgres Extensions, and we\u2019ve also looked at the pg_cron extension in [&hellip;]","og_url":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/","og_site_name":"OpenSource DB","article_publisher":"https:\/\/www.facebook.com\/people\/OpenSource-DB\/100072970755470\/","article_published_time":"2023-09-13T08:58:15+00:00","article_modified_time":"2023-09-13T08:58:16+00:00","og_image":[{"url":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png","type":"","width":"","height":""}],"author":"Venkat Akhil","twitter_card":"summary_large_image","twitter_creator":"@opensource_db","twitter_site":"@opensource_db","twitter_misc":{"Written by":"Venkat Akhil","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#article","isPartOf":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/"},"author":{"name":"Venkat Akhil","@id":"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/a37b142ecbf953189a4f9209b0b8d328"},"headline":"Postgres Beyond the Basics: Exploring Extensibility &#8211; Part III","datePublished":"2023-09-13T08:58:15+00:00","dateModified":"2023-09-13T08:58:16+00:00","mainEntityOfPage":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/"},"wordCount":830,"commentCount":0,"publisher":{"@id":"https:\/\/test.opensource-db.in\/wp1\/#organization"},"image":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage"},"thumbnailUrl":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png","keywords":["extensions","postgresql14","postgresql15"],"articleSection":["PostgreSQL 14","PostgreSQL 15"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/","url":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/","name":"Postgres Beyond the Basics: Exploring Extensibility - Part III - OpenSource DB","isPartOf":{"@id":"https:\/\/test.opensource-db.in\/wp1\/#website"},"primaryImageOfPage":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage"},"image":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage"},"thumbnailUrl":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png","datePublished":"2023-09-13T08:58:15+00:00","dateModified":"2023-09-13T08:58:16+00:00","breadcrumb":{"@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#primaryimage","url":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png","contentUrl":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2023\/09\/image.png","width":1024,"height":538},{"@type":"BreadcrumbList","@id":"https:\/\/test.opensource-db.in\/wp1\/postgres-beyond-the-basics-exploring-extensibility-part-iii\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/test.opensource-db.in\/wp1\/"},{"@type":"ListItem","position":2,"name":"Postgres Beyond the Basics: Exploring Extensibility &#8211; Part III"}]},{"@type":"WebSite","@id":"https:\/\/test.opensource-db.in\/wp1\/#website","url":"https:\/\/test.opensource-db.in\/wp1\/","name":"OpenSource DB","description":"Your Trusted OpenSource Databases partner","publisher":{"@id":"https:\/\/test.opensource-db.in\/wp1\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/test.opensource-db.in\/wp1\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/test.opensource-db.in\/wp1\/#organization","name":"OPENSOURCE DB PRIVATE LIMITED","url":"https:\/\/test.opensource-db.in\/wp1\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/logo\/image\/","url":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2021\/10\/osdb-logo-tm-2.png","contentUrl":"https:\/\/test.opensource-db.in\/wp1\/wp-content\/uploads\/2021\/10\/osdb-logo-tm-2.png","width":368,"height":120,"caption":"OPENSOURCE DB PRIVATE LIMITED"},"image":{"@id":"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/people\/OpenSource-DB\/100072970755470\/","https:\/\/x.com\/opensource_db","https:\/\/www.youtube.com\/channel\/UCmTI5h","https:\/\/www.linkedin.com\/company\/opensource-db","https:\/\/www.instagram.com\/opensource_db\/"]},{"@type":"Person","@id":"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/a37b142ecbf953189a4f9209b0b8d328","name":"Venkat Akhil","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/test.opensource-db.in\/wp1\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/522c0947d21b2c2c89f10698fd9131f9db4110f65c8d02b53d9b4559c7650865?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/522c0947d21b2c2c89f10698fd9131f9db4110f65c8d02b53d9b4559c7650865?s=96&d=mm&r=g","caption":"Venkat Akhil"},"url":"https:\/\/test.opensource-db.in\/wp1\/author\/sudheer-sopensource-db-com\/"}]}},"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"Venkat Akhil","author_link":"https:\/\/test.opensource-db.in\/wp1\/author\/sudheer-sopensource-db-com\/"},"rttpg_comment":0,"rttpg_category":"<a href=\"https:\/\/test.opensource-db.in\/wp1\/category\/postgres\/postgresql-14\/\" rel=\"category tag\">PostgreSQL 14<\/a> <a href=\"https:\/\/test.opensource-db.in\/wp1\/category\/postgres\/postgresql-15\/\" rel=\"category tag\">PostgreSQL 15<\/a>","rttpg_excerpt":"In the earlier posts, we\u2019ve had an Overview of Postgres Extensions, and we\u2019ve also looked at the pg_cron extension in [&hellip;]","_links":{"self":[{"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/posts\/4430","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/comments?post=4430"}],"version-history":[{"count":6,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/posts\/4430\/revisions"}],"predecessor-version":[{"id":4440,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/posts\/4430\/revisions\/4440"}],"wp:attachment":[{"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/media?parent=4430"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/categories?post=4430"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/test.opensource-db.in\/wp1\/wp-json\/wp\/v2\/tags?post=4430"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}