{"id":2697,"date":"2024-11-05T02:41:36","date_gmt":"2024-11-05T02:41:36","guid":{"rendered":"https:\/\/bynatree.com\/?p=2697"},"modified":"2024-11-05T02:41:36","modified_gmt":"2024-11-05T02:41:36","slug":"postgresql-17s-new-backup-feature-incremental-backups","status":"publish","type":"post","link":"https:\/\/divaind.com\/ie1\/2024\/11\/05\/postgresql-17s-new-backup-feature-incremental-backups\/","title":{"rendered":"PostgreSQL 17&#8217;s New Backup Feature: Incremental Backups"},"content":{"rendered":"<h2><span style=\"font-weight: 400;\">Introduction<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">With the release of PostgreSQL 17, a game-changing feature has arrived: <\/span><b>incremental backups<\/b><span style=\"font-weight: 400;\">. In prior versions, such as PostgreSQL 16 and earlier, users could only perform full backups. This approach, while reliable, had its drawbacks\u2014particularly the time it took to complete these backups and the storage they required.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Previously, users relied on <\/span><b>WAL (Write-Ahead Logging)<\/b><span style=\"font-weight: 400;\"> or archive logs as a workaround to achieve incremental-style backups. However, this method comes with a major downside: <\/span><b>slow recovery times<\/b><span style=\"font-weight: 400;\">. During restoration, each archived WAL segment had to be processed in sequence to replay every transaction, which extended the time required for a full database recovery.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">PostgreSQL 17\u2019s native support for incremental backups is designed to address these challenges by streamlining backup processes and enhancing recovery speed.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">How the incremental backups works<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">In PostgreSQL 17, incremental backups are designed to back up only the data changed since the last full backup, making backups faster and more efficient. This is achieved using the <\/span><strong>pg_basebackup<\/strong><span style=\"font-weight: 400;\"> tool with the <\/span><strong>&#8211;incremental<\/strong><span style=\"font-weight: 400;\"> option, which backs up all non-relation files completely while only capturing modified blocks and metadata required to reconstruct changed database blocks.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">How it Works<\/span><\/h3>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">PostgreSQL uses <\/span><b>WAL summaries<\/b><span style=\"font-weight: 400;\">, which are stored in the <\/span><span style=\"font-weight: 400;\">pg_wal\/summaries<\/span><span style=\"font-weight: 400;\"> directory, to determine which blocks have changed since the last backup. These summaries cover the Log Sequence Numbers (LSNs) from the start of the previous backup to the start of the current one.<\/span><\/li>\n<\/ul>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">By analyzing these WAL summaries, PostgreSQL identifies the modified blocks that need to be backed up, ensuring efficient incremental backups without re-backing up unchanged data.<\/span><\/li>\n<\/ul>\n<h2><span style=\"font-weight: 400;\">Restoration Requirements<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">To restore an incremental backup, all previous backups in the sequence are required to reconstruct the database. Each incremental backup builds on its predecessors, allowing PostgreSQL to recreate the database state efficiently by including only the necessary blocks in each backup.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">PostgreSQL does not automatically track which backups are required as a foundation for restoring future incremental backups. This means that users must manage the relationships between their full and incremental backups manually, ensuring that earlier backups are retained if they may be needed for restoration.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">When to Use Incremental Backups<\/span><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><b>Large Databases with Minimal Changes<\/b><span style=\"font-weight: 400;\">: Incremental backups are most beneficial for sizable databases where a significant portion of the data remains unchanged or changes gradually. In these cases, incremental backups can save both time and storage.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Small Databases<\/b><span style=\"font-weight: 400;\">: For smaller databases, full backups are often simpler to manage and sufficient for most recovery needs, making incremental backups unnecessary.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Heavily Modified Large Databases<\/b><span style=\"font-weight: 400;\">: If a large database undergoes frequent, widespread modifications, incremental backups might offer limited benefits, as they won\u2019t be substantially smaller than full backups.<\/span><\/li>\n<\/ul>\n<h2><span style=\"font-weight: 400;\">How to take incremental backups and restore<\/span><\/h2>\n<h3><span style=\"font-weight: 400;\">Prerequisites<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">To perform the incremental backups below configuration parameters need to be set<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">wal_level<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">max_wal_senders<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">summarize_wal<\/span><\/li>\n<\/ul>\n<pre class=\"lang:tsql decode:true \">[postgres@localhost ~]$ psql\npsql (17.0)\nType \"help\" for help.\n\npostgres=# alter system set summarize_wal to true ;\nALTER SYSTEM\npostgres=# select pg_reload_conf();\n pg_reload_conf\n----------------\n t\n(1 row)\n\npostgres=#\npostgres=# show summarize_wal ;\n summarize_wal\n---------------\n on\n(1 row)\n\npostgres=# show wal_level ;\n wal_level\n-----------\n replica\n(1 row)\n\npostgres=# show max_wal_senders ;\n max_wal_senders\n-----------------\n 10\n(1 row)\n\npostgres=#<\/pre>\n<h3><span style=\"font-weight: 400;\">Steps to perform incremental backup and restore<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">For this test I am creating a test table with some data.<\/span><\/p>\n<pre class=\"lang:tsql decode:true \">template1=# create table test(id int, name varchar);\nCREATE TABLE\ntemplate1=#\ntemplate1=# insert into test values (1,'Anurag');\nINSERT 0 1\n\ntemplate1=# select * from test;\n id |  name\n----+--------\n  1 | Anurag\n(1 row)\n<\/pre>\n<h4><span style=\"font-weight: 400;\">Take a full backup<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">Now taking full backup using the pg_basebackup command. Pg_basebackup is a command line tool used to take online backups in PostgreSQL .<\/span><\/p>\n<pre class=\"lang:sh decode:true \">[postgres@localhost ~]$ pg_basebackup -D full_backup --verbose\npg_basebackup: initiating base backup, waiting for checkpoint to complete\npg_basebackup: checkpoint completed\npg_basebackup: write-ahead log start point: 3\/2000028 on timeline 1\npg_basebackup: starting background WAL receiver\npg_basebackup: created temporary replication slot \"pg_basebackup_209564\"\npg_basebackup: write-ahead log end point: 3\/200A2C0\npg_basebackup: waiting for background process to finish streaming ...\npg_basebackup: syncing data to disk ...\npg_basebackup: renaming backup_manifest.tmp to backup_manifest\npg_basebackup: base backup completed\n<\/pre>\n<p><span style=\"font-weight: 400;\">Now the full backup is completed. Logged into the database and inserted some more records to make changes to the database.<\/span><\/p>\n<pre class=\"lang:tsql decode:true \">template1=# insert into test values (2,'Prathap');\nINSERT 0 1\ntemplate1=#\n\ntemplate1=# select * from test;\n id |  name\n----+---------\n  1 | Anurag\n  2 | Prathap\n(2 rows)\n<\/pre>\n<h4><span style=\"font-weight: 400;\">Take an incremental backup<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">To backup the changes made in the previous setup, take the incremental backup using the pg_basebackup command line tool. While taking the incremental backup the backup_manifest of the previous backup needs to be passed to the \u201c&#8211;incremental\u201d option.<\/span><\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:sh decode:true \">[postgres@localhost ~]$ pg_basebackup -D incremental_backup --incremental=full_backup\/backup_manifest --verbose\npg_basebackup: initiating base backup, waiting for checkpoint to complete\npg_basebackup: checkpoint completed\npg_basebackup: write-ahead log start point: 3\/4000028 on timeline 1\npg_basebackup: starting background WAL receiver\npg_basebackup: created temporary replication slot \"pg_basebackup_209755\"\npg_basebackup: write-ahead log end point: 3\/4000120\npg_basebackup: waiting for background process to finish streaming ...\npg_basebackup: syncing data to disk ...\npg_basebackup: renaming backup_manifest.tmp to backup_manifest\npg_basebackup: base backup completed\n<\/pre>\n<h4><span style=\"font-weight: 400;\">Restore the backup<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">To restore an incremental backup, you\u2019ll need to combine all previous backups since the last full backup using the <\/span><span style=\"font-weight: 400;\">pg_combinebackup<\/span><span style=\"font-weight: 400;\"> tool. This tool rebuilds a complete backup by merging the full backup with each subsequent incremental backup.<\/span><\/p>\n<h4>Key Considerations for Restoration:<\/h4>\n<p>Maintain Backup Sequence: Ensure backups are provided in the correct sequence, starting with the full backup followed by each incremental backup in order. Any deviation from this order will cause an error.<\/p>\n<p>Complete Backup Chain Required: All incremental backups, starting with the initial full backup, must be available for successful restoration. Omitting any part of the sequence or skipping the full backup will result in an error<\/p>\n<p><b>How to Use <\/b><b>pg_combinebackup<\/b><b>:<\/b><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">List all backups in sequence from oldest to newest, starting with the full backup, followed by each incremental backup in the order they were taken.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Specify the output directory where the combined full backup will be stored.<\/span><\/li>\n<\/ol>\n<pre class=\"lang:sh decode:true \">[postgres@localhost ~]$ pg_combinebackup full_backup incremental_backup --output=complete_backup\n[postgres@localhost ~]$ du -sh complete_backup\n39M     complete_backup\n<\/pre>\n<p><span style=\"font-weight: 400;\">After generating the complete backup, it\u2019s ready for use. To start the PostgreSQL server with this backup, point it to the backup directory and use a different port (e.g., 5434) to avoid conflicts with any existing instances.<\/span><\/p>\n<p><b>Steps to Start the Server with the Backup<\/b><span style=\"font-weight: 400;\">:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\"><b>Navigate to the Backup Directory<\/b><span style=\"font-weight: 400;\">: Ensure that the complete backup is located in the designated folder.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Start the PostgreSQL Server on Port 5434<\/b><span style=\"font-weight: 400;\">: Use the <\/span><span style=\"font-weight: 400;\">pg_ctl<\/span><span style=\"font-weight: 400;\"> command to initiate the server, specifying the data directory and port.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">This setup allows you to run the restored instance alongside your main server instance, enabling you to verify the backup or perform other maintenance without interference.<\/span><\/p>\n<pre class=\"lang:tsql decode:true \">[postgres@localhost ~]$ \/usr\/pgsql-17\/bin\/pg_ctl -D complete_backup start\nwaiting for server to start....2024-11-04 03:53:48.797 PST [210479] LOG:  redirecting log output to logging collector process\n2024-11-04 03:53:48.797 PST [210479] HINT:  Future log output will appear in directory \"log\".\n done\nserver started\n\n\n[postgres@localhost ~]$ psql -p 5434\npsql (17.0)\nType \"help\" for help.\n\npostgres=# c template1\nYou are now connected to database \"template1\" as user \"postgres\".\ntemplate1=#\ntemplate1=# select * from test;\n id |  name\n----+---------\n  1 | Anurag\n  2 | Prathap\n(2 rows)\n\n<\/pre>\n<p>&nbsp;<\/p>\n<div class=\"flex-shrink-0 flex flex-col relative items-end\">\n<div>\n<div class=\"pt-0\">\n<div class=\"gizmo-bot-avatar flex h-8 w-8 items-center justify-center overflow-hidden rounded-full\">\n<h2 class=\"relative p-1 rounded-sm flex items-center justify-center bg-token-main-surface-primary text-token-text-primary h-8 w-8\">Conclusion<\/h2>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"group\/conversation-turn relative flex w-full min-w-0 flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"flex max-w-full flex-col flex-grow\">\n<div class=\"min-h-8 text-message flex w-full flex-col items-end gap-2 whitespace-normal break-words [.text-message+&amp;]:mt-5\" dir=\"auto\" data-message-author-role=\"assistant\" data-message-id=\"64441f3f-bc37-4364-8429-2ac1ed73d4da\" data-message-model-slug=\"gpt-4o\">\n<div class=\"flex w-full flex-col gap-1 empty:hidden first:pt-[3px]\">\n<div class=\"markdown prose w-full break-words dark:prose-invert light\">\n<p>The introduction of incremental backups in PostgreSQL 17 marks a significant advancement, making backups faster and more storage-efficient by capturing only changed data blocks. For administrators of large, stable databases, this feature offers a streamlined, cost-effective alternative to traditional full backups, enabling faster recovery and simpler backup management.<\/p>\n<p>However, maintaining the correct backup sequence is essential for successful restoration. Testing incremental backups in a non-production setting can help ensure familiarity with the process and avoid errors.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction With the release of PostgreSQL 17, a game-changing feature has arrived: incremental backups. In prior versions, such as PostgreSQL 16 and earlier, users could only perform full backups. This approach, while reliable, had its drawbacks\u2014particularly the time it took to complete these backups and the storage they required. Previously, users relied on WAL (Write-Ahead&hellip;<\/p>\n","protected":false},"author":1,"featured_media":2699,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28],"tags":[163,266],"class_list":["post-2697","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-postgresql","tag-incremental-backups","tag-postgresql","category-28","description-off"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/posts\/2697","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/comments?post=2697"}],"version-history":[{"count":0,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/posts\/2697\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/media\/2699"}],"wp:attachment":[{"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/media?parent=2697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/categories?post=2697"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/divaind.com\/ie1\/wp-json\/wp\/v2\/tags?post=2697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}