{"id":460650,"date":"2025-05-22T22:32:46","date_gmt":"2025-05-22T22:32:46","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=460650"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=460650","title":{"rendered":"<span>Database performance analysis using pg_profile and pgpro_pwr<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><code>pgpro_pwr<\/code> is a strategic database workload monitoring tool that helps DBAs identify the most resource-intensive operations. The first version of this module, designed for PostgreSQL, was released in 2017 under the name <code>pg_profile<\/code>, developed by Andrey Zubkov \u2014 then a database administrator, now an engineer at Postgres Professional.<\/p>\n<p>The key difference between <code>pg_profile<\/code> and <code>pgpro_pwr<\/code> is that the former works with open-source PostgreSQL (as of 2024, the <code>pg_profile<\/code> package has been included in PostgreSQL 17), while the latter collects advanced statistics and is integrated into Postgres Pro releases.<\/p>\n<h2>How it all began<\/h2>\n<p>We didn&#8217;t reinvent the wheel \u2014 similar tools existed before. However, using them in web applications was inconvenient, as they required separate deployment from the DBMS. Database administrators, especially those familiar with Oracle AWR, longed for a tool that could work directly within Postgres. Andrey responded to this need by developing a platform-independent extension in pl\/pgSQL.<\/p>\n<h2>How pg_profile and pgpro_pwr work<\/h2>\n<p>Our tools do not provide alerting capabilities. Instead, they monitor database workload metrics using counters that continuously increment from the last reset\u2014often from the time the cluster was created. While raw counter values are not very useful, their increments over time, across different perspectives \u2014 such as clusters, databases, individual functions, or tables \u2014 offer valuable insights. The tools capture counter values at specified intervals and store the differences in their repository.<\/p>\n<h2>A quick test: do you need this tool?<\/h2>\n<p>Consider using <code>pg_profile<\/code> or <code>pgpro_pwr<\/code> if you:<\/p>\n<ol>\n<li>\n<p>Want to assess the stability of a long-running system \u2014 for instance, before adding a new feature.<\/p>\n<\/li>\n<li>\n<p>Need to analyze the results of load testing.<\/p>\n<\/li>\n<li>\n<p>Aim to identify system-intensive activities, such as:<\/p>\n<ul>\n<li>\n<p>Frequently used tables requiring constant VACUUM operations.<\/p>\n<\/li>\n<li>\n<p>Queries that run too frequently or take too long to execute.<\/p>\n<\/li>\n<li>\n<p>Inefficient execution plans.<\/p>\n<\/li>\n<li>\n<p><strong>Spoiler<br \/><\/strong><span class=\"habrahidden\">Currently, only pgpro_pwr can detect \u201cinefficient\u201d execution plans, but we hope to teach pg_profile this capability as well.<\/span><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>If you answered \u201cyes\u201d to any of these questions, you will definitely need <code>pg_profile<\/code> or <code>pgpro_pwr<\/code>.<\/p>\n<p>Now, let\u2019s take a closer look at what our <code>pg_profile<\/code> and <code>pgpro_pwr<\/code> tools consist of and what they can do.<\/p>\n<h2>Tool structure<\/h2>\n<p><code>pg_profile<\/code> and <code>pgpro_pwr<\/code> include the following components:<\/p>\n<ul>\n<li>\n<p>Repository tables for storing snapshot data<\/p>\n<\/li>\n<li>\n<p>Data collection functions for snapshots<\/p>\n<\/li>\n<li>\n<p>Reporting functions<\/p>\n<\/li>\n<li>\n<p>Service tables and functions<\/p>\n<\/li>\n<\/ul>\n<p>The tools serve two primary purposes:<\/p>\n<ol>\n<li>\n<p>Taking snapshots. These tools maintain independently of the operating system and cannot configure anything on their own, so a dedicated scheduler must be set up to perform snapshots.<\/p>\n<\/li>\n<li>\n<p>Generating reports, which are HTML documents providing summarized statistics over a specific time period. The reports include a variety of metrics, some of which are exclusive to pgpro_pwr, such as database cleanup statistics, per-plan statistics, expression-level statistics, workload distribution, and invalidation statistics.<\/p>\n<\/li>\n<\/ol>\n<h2>How to monitor performance<\/h2>\n<p>To prepare for monitoring, follow a few steps detailed in the documentation:<\/p>\n<ol>\n<li>\n<p>Install the extension (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#installation\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SIMPLE-INSTALL\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<li>\n<p>Configure roles (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#privileges\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-ROLES\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<li>\n<p>Set up the extension parameters (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#setting-extension-parameters\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SETTING-EXTENSION-PARAMETERS\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<\/ol>\n<p>Once installed, both extensions create a single active server called local, corresponding to the current cluster. The server can be managed using functions (a complete list is available for both <a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#managing-servers\">pg_profile<\/a> and <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SERVER-MANAGEMENT-FUNCTIONS\">pgpro_pwr<\/a>). For example, the create_server function creates a server definition:<\/p>\n<pre><code class=\"sql\">create_server(server_name text, server_connstr text, server_enabled boolean DEFAULT TRUE, max_sample_age integer DEFAULT NULL, description text DEFAULT NULL);<\/code><\/pre>\n<p>Here\u2019s an example of this function in action:<\/p>\n<pre><code class=\"sql\">SELECT profile.create_server('omega', 'host=name_or_ip dbname=postgres port=5432');<\/code><\/pre>\n<p>The database load statistics are stored in snapshots, which can also be managed (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#samples\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SAMPLES\">pgpro_pwr<\/a>). Collected snapshots can be exported from one instance of the extension and imported into another, allowing you to transfer accumulated server information or share it with support specialists for analysis.<\/p>\n<h2>Generating reports<\/h2>\n<p>Once the extensions, servers, and snapshots are set up, you can generate reports. Reports are divided into:<\/p>\n<ul>\n<li>\n<p>Standard reports (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#regular-report-functions\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-REGULAR-REPORT-FUNCTIONS\">pgpro_pwr<\/a>) \u2013 provide workload statistics for a specified time period.<\/p>\n<\/li>\n<li>\n<p>Comparison reports (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#differential-report-functions\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-DIFFERENTIAL-REPORT-FUNCTIONS\">pgpro_pwr<\/a>) \u2013 compare statistics for the same objects across two different time intervals.<\/p>\n<\/li>\n<\/ul>\n<p>Example of generating a report for the local server over a specific interval:<\/p>\n<pre><code class=\"sql\">psql -Aqtc \"SELECT profile.get_report(480,482)\" -o report_480_482.html<\/code><\/pre>\n<p>Generating a report for another server:<\/p>\n<pre><code>psql -Aqtc \"SELECT profile.get_report('omega',12,14)\" -o report_omega_12_14.html<\/code><\/pre>\n<p>Generating a report for a time range:<\/p>\n<pre><code>psql -Aqtc \"SELECT profile.get_report(tstzrange('2020-05-13 11:51:35+03','2020-05-13 11:52:18+03'))\" -o report_range.html<\/code><\/pre>\n<p>Reports can be opened in any web browser. Detailed descriptions of the types of reports and statistics included in each are available in the documentation (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#sections-of-a-report\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SECTIONS-OF-A-REPORT\">pgpro_pwr<\/a>).<\/p>\n<p>Some examples are:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7ff\/21d\/d9a\/7ff21dd9aeb3394c7c75e82cb94154b3.png\" alt=\"Wait event statistics\" title=\"Wait event statistics\" width=\"1560\" height=\"648\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/7ff\/21d\/d9a\/7ff21dd9aeb3394c7c75e82cb94154b3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7ff\/21d\/d9a\/7ff21dd9aeb3394c7c75e82cb94154b3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Wait event statistics<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/57f\/1be\/9e9\/57f1be9e9411666f82648ed7b7438d1a.png\" alt=\"Advanced vacuum statistics\" title=\"Advanced vacuum statistics\" width=\"1560\" height=\"368\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/57f\/1be\/9e9\/57f1be9e9411666f82648ed7b7438d1a.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/57f\/1be\/9e9\/57f1be9e9411666f82648ed7b7438d1a.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Advanced vacuum statistics<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/48e\/9a4\/92e\/48e9a492e88f71266abf011809004026.png\" alt=\"Workload distribution\" title=\"Workload distribution\" width=\"1560\" height=\"884\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/48e\/9a4\/92e\/48e9a492e88f71266abf011809004026.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/48e\/9a4\/92e\/48e9a492e88f71266abf011809004026.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Workload distribution<\/figcaption><\/div>\n<\/figure>\n<h2>What\u2019s next<\/h2>\n<p>We are currently working on submitting a patch with vacuum statistics to vanilla PostgreSQL. We strive to upstream as much as possible, as resolving future merge conflicts can be quite challenging.<\/p>\n<p>If you have any questions or difficulties while using the monitoring tools, we are happy to help. Share your thoughts and ideas in the comments!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/895520\/\"> https:\/\/habr.com\/ru\/articles\/895520\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><code>pgpro_pwr<\/code> is a strategic database workload monitoring tool that helps DBAs identify the most resource-intensive operations. The first version of this module, designed for PostgreSQL, was released in 2017 under the name <code>pg_profile<\/code>, developed by Andrey Zubkov \u2014 then a database administrator, now an engineer at Postgres Professional.<\/p>\n<p>The key difference between <code>pg_profile<\/code> and <code>pgpro_pwr<\/code> is that the former works with open-source PostgreSQL (as of 2024, the <code>pg_profile<\/code> package has been included in PostgreSQL 17), while the latter collects advanced statistics and is integrated into Postgres Pro releases.<\/p>\n<h2>How it all began<\/h2>\n<p>We didn&#8217;t reinvent the wheel \u2014 similar tools existed before. However, using them in web applications was inconvenient, as they required separate deployment from the DBMS. Database administrators, especially those familiar with Oracle AWR, longed for a tool that could work directly within Postgres. Andrey responded to this need by developing a platform-independent extension in pl\/pgSQL.<\/p>\n<h2>How pg_profile and pgpro_pwr work<\/h2>\n<p>Our tools do not provide alerting capabilities. Instead, they monitor database workload metrics using counters that continuously increment from the last reset\u2014often from the time the cluster was created. While raw counter values are not very useful, their increments over time, across different perspectives \u2014 such as clusters, databases, individual functions, or tables \u2014 offer valuable insights. The tools capture counter values at specified intervals and store the differences in their repository.<\/p>\n<h2>A quick test: do you need this tool?<\/h2>\n<p>Consider using <code>pg_profile<\/code> or <code>pgpro_pwr<\/code> if you:<\/p>\n<ol>\n<li>\n<p>Want to assess the stability of a long-running system \u2014 for instance, before adding a new feature.<\/p>\n<\/li>\n<li>\n<p>Need to analyze the results of load testing.<\/p>\n<\/li>\n<li>\n<p>Aim to identify system-intensive activities, such as:<\/p>\n<ul>\n<li>\n<p>Frequently used tables requiring constant VACUUM operations.<\/p>\n<\/li>\n<li>\n<p>Queries that run too frequently or take too long to execute.<\/p>\n<\/li>\n<li>\n<p>Inefficient execution plans.<\/p>\n<\/li>\n<li>\n<p><strong>Spoiler<br \/><\/strong><span class=\"habrahidden\">Currently, only pgpro_pwr can detect \u201cinefficient\u201d execution plans, but we hope to teach pg_profile this capability as well.<\/span><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>If you answered \u201cyes\u201d to any of these questions, you will definitely need <code>pg_profile<\/code> or <code>pgpro_pwr<\/code>.<\/p>\n<p>Now, let\u2019s take a closer look at what our <code>pg_profile<\/code> and <code>pgpro_pwr<\/code> tools consist of and what they can do.<\/p>\n<h2>Tool structure<\/h2>\n<p><code>pg_profile<\/code> and <code>pgpro_pwr<\/code> include the following components:<\/p>\n<ul>\n<li>\n<p>Repository tables for storing snapshot data<\/p>\n<\/li>\n<li>\n<p>Data collection functions for snapshots<\/p>\n<\/li>\n<li>\n<p>Reporting functions<\/p>\n<\/li>\n<li>\n<p>Service tables and functions<\/p>\n<\/li>\n<\/ul>\n<p>The tools serve two primary purposes:<\/p>\n<ol>\n<li>\n<p>Taking snapshots. These tools maintain independently of the operating system and cannot configure anything on their own, so a dedicated scheduler must be set up to perform snapshots.<\/p>\n<\/li>\n<li>\n<p>Generating reports, which are HTML documents providing summarized statistics over a specific time period. The reports include a variety of metrics, some of which are exclusive to pgpro_pwr, such as database cleanup statistics, per-plan statistics, expression-level statistics, workload distribution, and invalidation statistics.<\/p>\n<\/li>\n<\/ol>\n<h2>How to monitor performance<\/h2>\n<p>To prepare for monitoring, follow a few steps detailed in the documentation:<\/p>\n<ol>\n<li>\n<p>Install the extension (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#installation\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SIMPLE-INSTALL\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<li>\n<p>Configure roles (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#privileges\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-ROLES\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<li>\n<p>Set up the extension parameters (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#setting-extension-parameters\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SETTING-EXTENSION-PARAMETERS\">pgpro_pwr<\/a>).<\/p>\n<\/li>\n<\/ol>\n<p>Once installed, both extensions create a single active server called local, corresponding to the current cluster. The server can be managed using functions (a complete list is available for both <a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#managing-servers\">pg_profile<\/a> and <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SERVER-MANAGEMENT-FUNCTIONS\">pgpro_pwr<\/a>). For example, the create_server function creates a server definition:<\/p>\n<pre><code class=\"sql\">create_server(server_name text, server_connstr text, server_enabled boolean DEFAULT TRUE, max_sample_age integer DEFAULT NULL, description text DEFAULT NULL);<\/code><\/pre>\n<p>Here\u2019s an example of this function in action:<\/p>\n<pre><code class=\"sql\">SELECT profile.create_server('omega', 'host=name_or_ip dbname=postgres port=5432');<\/code><\/pre>\n<p>The database load statistics are stored in snapshots, which can also be managed (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#samples\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SAMPLES\">pgpro_pwr<\/a>). Collected snapshots can be exported from one instance of the extension and imported into another, allowing you to transfer accumulated server information or share it with support specialists for analysis.<\/p>\n<h2>Generating reports<\/h2>\n<p>Once the extensions, servers, and snapshots are set up, you can generate reports. Reports are divided into:<\/p>\n<ul>\n<li>\n<p>Standard reports (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#regular-report-functions\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-REGULAR-REPORT-FUNCTIONS\">pgpro_pwr<\/a>) \u2013 provide workload statistics for a specified time period.<\/p>\n<\/li>\n<li>\n<p>Comparison reports (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#differential-report-functions\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-DIFFERENTIAL-REPORT-FUNCTIONS\">pgpro_pwr<\/a>) \u2013 compare statistics for the same objects across two different time intervals.<\/p>\n<\/li>\n<\/ul>\n<p>Example of generating a report for the local server over a specific interval:<\/p>\n<pre><code class=\"sql\">psql -Aqtc \"SELECT profile.get_report(480,482)\" -o report_480_482.html<\/code><\/pre>\n<p>Generating a report for another server:<\/p>\n<pre><code>psql -Aqtc \"SELECT profile.get_report('omega',12,14)\" -o report_omega_12_14.html<\/code><\/pre>\n<p>Generating a report for a time range:<\/p>\n<pre><code>psql -Aqtc \"SELECT profile.get_report(tstzrange('2020-05-13 11:51:35+03','2020-05-13 11:52:18+03'))\" -o report_range.html<\/code><\/pre>\n<p>Reports can be opened in any web browser. Detailed descriptions of the types of reports and statistics included in each are available in the documentation (<a href=\"https:\/\/github.com\/zubkov-andrei\/pg_profile\/blob\/master\/doc\/pg_profile.md#sections-of-a-report\">pg_profile<\/a> \/ <a href=\"https:\/\/postgrespro.ru\/docs\/postgrespro\/17\/pgpro-pwr#PGPRO-PWR-SECTIONS-OF-A-REPORT\">pgpro_pwr<\/a>).<\/p>\n<p>Some examples are:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Wait event statistics<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>Advanced vacuum statistics<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>Workload distribution<\/figcaption><\/div>\n<\/figure>\n<h2>What\u2019s next<\/h2>\n<p>We are currently working on submitting a patch with vacuum statistics to vanilla PostgreSQL. We strive to upstream as much as possible, as resolving future merge conflicts can be quite challenging.<\/p>\n<p>If you have any questions or difficulties while using the monitoring tools, we are happy to help. Share your thoughts and ideas in the comments!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/895520\/\"> https:\/\/habr.com\/ru\/articles\/895520\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-460650","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/460650","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=460650"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/460650\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=460650"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=460650"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=460650"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}