diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index a23a1033632..ba605059fc2 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -2842,7 +2842,7 @@ The commands accepted in replication mode are:
Files other than regular files and directories, such as symbolic
links (other than for the directories listed above) and special
- device files, are skipped. (Symbolic links
+ device and operating system files, are skipped. (Symbolic links
in pg_tblspc are maintained.)
diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml
index 9e6807b4574..e1d24f805ed 100644
--- a/doc/src/sgml/ref/pg_basebackup.sgml
+++ b/doc/src/sgml/ref/pg_basebackup.sgml
@@ -832,7 +832,8 @@ PostgreSQL documentation
The backup will include all files in the data directory and tablespaces,
including the configuration files and any additional files placed in the
directory by third parties, except certain temporary files managed by
- PostgreSQL. But only regular files and directories are copied, except that
+ PostgreSQL and operating system files. But only regular files and
+ directories are copied, except that
symbolic links used for tablespaces are preserved. Symbolic links pointing
to certain directories known to PostgreSQL are copied as empty directories.
Other symbolic links and special device files are skipped.
diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml
index 47c55492301..2f431302495 100644
--- a/doc/src/sgml/ref/pg_rewind.sgml
+++ b/doc/src/sgml/ref/pg_rewind.sgml
@@ -374,8 +374,9 @@ GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, b
backup_label,
tablespace_map,
pg_internal.init,
- postmaster.opts, and
- postmaster.pid, as well as any file or directory
+ postmaster.opts,
+ postmaster.pid and
+ .DS_Store as well as any file or directory
beginning with pgsql_tmp, are omitted.
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index d142cc21319..7ed82a76ff8 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1272,6 +1272,10 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces,
strlen(PG_TEMP_FILE_PREFIX)) == 0)
continue;
+ /* Skip macOS system files */
+ if (strcmp(de->d_name, ".DS_Store") == 0)
+ continue;
+
/*
* Check if the postmaster has signaled us to exit, and abort with an
* error in that case. The error handler further up will call
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
index e23ac607aae..43d18fe4ccf 100644
--- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -76,6 +76,16 @@ foreach my $filename (
close $file;
}
+# Test that macOS system files are skipped. Only test on non-macOS systems
+# however since creating incorrect .DS_Store files on a macOS system may have
+# unintended side effects.
+if ($Config{osname} ne 'darwin')
+{
+ open my $file, '>>', "$pgdata/.DS_Store";
+ print $file "DONOTCOPY";
+ close $file;
+}
+
# Connect to a database to create global/pg_internal.init. If this is removed
# the test to ensure global/pg_internal.init is not copied will return a false
# positive.
@@ -144,6 +154,12 @@ foreach my $filename (
ok(!-f "$tempdir/backup/$filename", "$filename not copied");
}
+# We only test .DS_Store files being skipped on non-macOS systems
+if ($Config{osname} ne 'darwin')
+{
+ ok(!-f "$tempdir/backup/.DS_Store", ".DS_Store not copied");
+}
+
# Unlogged relation forks other than init should not be copied
ok(-f "$tempdir/backup/${baseUnloggedPath}_init",
'unlogged init fork in backup');
diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c
index 831cf42d3ad..b97d0f32903 100644
--- a/src/bin/pg_checksums/pg_checksums.c
+++ b/src/bin/pg_checksums/pg_checksums.c
@@ -338,6 +338,10 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
strlen(PG_TEMP_FILES_DIR)) == 0)
continue;
+ /* Skip macOS system files */
+ if (strcmp(de->d_name, ".DS_Store") == 0)
+ continue;
+
snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name);
if (lstat(fn, &st) < 0)
{
diff --git a/src/bin/pg_checksums/t/002_actions.pl b/src/bin/pg_checksums/t/002_actions.pl
index 761f7ab53b6..a8ced3b4bed 100644
--- a/src/bin/pg_checksums/t/002_actions.pl
+++ b/src/bin/pg_checksums/t/002_actions.pl
@@ -6,6 +6,7 @@
use strict;
use warnings;
+use Config;
use PostgresNode;
use TestLib;
@@ -114,6 +115,12 @@ append_to_file "$pgdata/global/pgsql_tmp/1.1", "foo";
append_to_file "$pgdata/global/pg_internal.init", "foo";
append_to_file "$pgdata/global/pg_internal.init.123", "foo";
+# These are non-postgres macOS files, which should be ignored by the scan.
+# Only perform this test on non-macOS systems though as creating incorrect
+# system files may have side effects on macOS.
+append_to_file "$pgdata/global/.DS_Store", "foo"
+ unless ($Config{osname} eq 'darwin');
+
# Enable checksums.
command_ok([ 'pg_checksums', '--enable', '--no-sync', '-D', $pgdata ],
"checksums successfully enabled in cluster");
diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c
index 2618b4c957b..f3ce4f68288 100644
--- a/src/bin/pg_rewind/filemap.c
+++ b/src/bin/pg_rewind/filemap.c
@@ -648,6 +648,10 @@ decide_file_action(file_entry_t *entry)
if (strcmp(path, "global/pg_control") == 0)
return FILE_ACTION_NONE;
+ /* Skip macOS system files */
+ if (strstr(path, ".DS_Store") != NULL)
+ return FILE_ACTION_NONE;
+
/*
* Remove all files matching the exclusion filters in the target.
*/
diff --git a/src/bin/pg_rewind/t/003_extrafiles.pl b/src/bin/pg_rewind/t/003_extrafiles.pl
index baea3836b6f..be60ecaaee4 100644
--- a/src/bin/pg_rewind/t/003_extrafiles.pl
+++ b/src/bin/pg_rewind/t/003_extrafiles.pl
@@ -5,6 +5,7 @@
use strict;
use warnings;
+use Config;
use TestLib;
use Test::More tests => 5;
@@ -53,6 +54,10 @@ sub run_test
append_to_file
"$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file4",
"in standby4";
+ # Skip testing .DS_Store files on macOS to avoid risk of side effects
+ append_to_file
+ "$test_standby_datadir/tst_standby_dir/.DS_Store",
+ "macOS system file" unless ($Config{osname} eq 'darwin');
mkdir "$test_primary_datadir/tst_primary_dir";
append_to_file "$test_primary_datadir/tst_primary_dir/primary_file1",