32
32
#endif
33
33
34
34
#include "miscadmin.h"
35
+ #include "common/file_perm.h"
35
36
#include "portability/mem.h"
37
+ #include "postmaster/postmaster.h"
36
38
#include "storage/dsm.h"
37
39
#include "storage/fd.h"
38
40
#include "storage/ipc.h"
39
41
#include "storage/pg_shmem.h"
40
42
#include "utils/guc.h"
41
43
#include "utils/pidfile.h"
42
44
43
-
44
45
/*
45
46
* As of PostgreSQL 9.3, we normally allocate only a very small amount of
46
47
* System V shared memory, and only for the purposes of providing an
@@ -96,8 +97,8 @@ typedef enum
96
97
unsigned long UsedShmemSegID = 0 ;
97
98
void * UsedShmemSegAddr = NULL ;
98
99
100
+ void * AnonymousShmem = NULL ;
99
101
static Size AnonymousShmemSize ;
100
- static void * AnonymousShmem = NULL ;
101
102
102
103
static void * InternalIpcMemoryCreate (IpcMemoryKey memKey , Size size );
103
104
static void IpcMemoryDetach (int status , Datum shmaddr );
@@ -535,6 +536,31 @@ CreateAnonymousSegment(Size *size)
535
536
Size allocsize = * size ;
536
537
void * ptr = MAP_FAILED ;
537
538
int mmap_errno = 0 ;
539
+ int fd = -1 ;
540
+ void * hint = NULL ;
541
+ int mmap_flags = PG_MMAP_FLAGS ;
542
+
543
+ if (OnlineUpgradePath )
544
+ {
545
+ int shm_flags = O_RDWR ;
546
+ char path [64 ];
547
+ mmap_flags &= ~MAP_ANONYMOUS ;
548
+ sprintf (path , "/%d" , MyProcPid );
549
+
550
+ if (IsOnlineUpgrade )
551
+ {
552
+ mmap_flags |= MAP_FIXED ;
553
+ hint = AnonymousShmem ;
554
+ }
555
+ else
556
+ {
557
+ shm_flags |= O_CREAT |O_TRUNC ;
558
+ }
559
+ fd = shm_open (path , shm_flags , pg_file_create_mode );
560
+ if (fd < 0 )
561
+ ereport (FATAL ,
562
+ (errmsg ("could not create shared memory object: %m" ), 0 ));
563
+ }
538
564
539
565
#ifndef MAP_HUGETLB
540
566
/* PGSharedMemoryCreate should have dealt with this case */
@@ -546,15 +572,21 @@ CreateAnonymousSegment(Size *size)
546
572
* Round up the request size to a suitable large value.
547
573
*/
548
574
Size hugepagesize ;
549
- int mmap_flags ;
575
+ int huge_flags ;
550
576
551
- GetHugePageSize (& hugepagesize , & mmap_flags );
577
+ GetHugePageSize (& hugepagesize , & huge_flags );
552
578
553
579
if (allocsize % hugepagesize != 0 )
554
580
allocsize += hugepagesize - (allocsize % hugepagesize );
555
581
556
- ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE ,
557
- PG_MMAP_FLAGS | mmap_flags , -1 , 0 );
582
+ if (fd >= 0 && !IsOnlineUpgrade )
583
+ {
584
+ if (ftruncate (fd , allocsize ) < 0 )
585
+ ereport (FATAL ,
586
+ (errmsg ("could not truncate shared memory file: %m" ), 0 ));
587
+ }
588
+ ptr = mmap (hint , allocsize , PROT_READ | PROT_WRITE ,
589
+ huge_flags | mmap_flags , fd , 0 );
558
590
mmap_errno = errno ;
559
591
if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED )
560
592
elog (DEBUG1 , "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m" ,
@@ -569,8 +601,14 @@ CreateAnonymousSegment(Size *size)
569
601
* to non-huge pages.
570
602
*/
571
603
allocsize = * size ;
572
- ptr = mmap (NULL , allocsize , PROT_READ | PROT_WRITE ,
573
- PG_MMAP_FLAGS , -1 , 0 );
604
+ if (fd >= 0 && !IsOnlineUpgrade )
605
+ {
606
+ if (ftruncate (fd , allocsize ) < 0 )
607
+ ereport (FATAL ,
608
+ (errmsg ("could not truncate shared memory file: %m" ), 0 ));
609
+ }
610
+ ptr = mmap (hint , allocsize , PROT_READ | PROT_WRITE ,
611
+ mmap_flags , fd , 0 );
574
612
mmap_errno = errno ;
575
613
}
576
614
@@ -758,7 +796,7 @@ PGSharedMemoryCreate(Size size,
758
796
759
797
* shim = hdr ;
760
798
if (IsOnlineUpgrade )
761
- return hdr ;
799
+ return AnonymousShmem ? AnonymousShmem : ( void * ) hdr ;
762
800
763
801
hdr -> creatorPID = getpid ();
764
802
hdr -> magic = PGShmemMagic ;
@@ -834,6 +872,16 @@ PGSharedMemoryReAttach(void)
834
872
dsm_set_control_handle (hdr -> dsm_control );
835
873
836
874
UsedShmemSegAddr = hdr ; /* probably redundant */
875
+
876
+ if (IsOnlineUpgrade && AnonymousShmem )
877
+ {
878
+ Size size = hdr -> totalsize ;
879
+ void * addr = CreateAnonymousSegment (& size );
880
+ Assert (addr == AnonymousShmem );
881
+ Assert (size == hdr -> totalsize );
882
+ AnonymousShmemSize = size ;
883
+ elog (LOG , "Online upgrade maps anonymous segment to %p" , addr );
884
+ }
837
885
}
838
886
839
887
/*
0 commit comments