无法调整APFS分区大小 - “新的大小必须与现有大小不同”

我正在努力将整个1TB硬盘用作1个驱动器。使用磁盘工具将磁盘调整为1TB时,我一直收到“新大小必须与现有大小不同”的错误提示。 我尝试使用苹果的磁盘工具,但遇到了同样的问题。
额外的信息,我忘了提到...我将一个容量为256GB的驱动器克隆到了这个1TB的驱动器上...然后我运行了磁盘工具进行修复。

screenshot


你应该在disk0s1上有一个EFI分区。你能否将sudo gpt -r show disk0的结果编辑到你的问题中? - lx07
我收到gpt显示:无法打开设备'disk0':操作不允许 - pew pew
抱歉,我忘了提到你需要禁用SIP才能使用sudo gpt -r show disk0来查看你的启动磁盘。这是值得做的,因为它将确认你的分区在磁盘上的位置。 - lx07
2个回答

这对我有帮助:
1. 修复(内部,磁盘0 - 在您的情况下) `diskutil repairdisk disk0`
2. 调整大小(合成,磁盘1 - 在您的情况下使用HS) `diskutil apfs resizeContainer disk1 0`
修复磁盘后,resizeContainer 将无错误地工作。您可以在此处查看类似问题以获取更多上下文信息:无法调整大小APFS分区 - "新大小必须与现有大小不同"

欢迎来到Ask Different。修复磁盘有可能删除数据吗? - bmike
1repairdisk警告我可能会对EFI分区产生影响,所以我进行了备份。但在我的情况下,我没有丢失任何数据。 - Ilya K
谢谢。我担心其中一些情况非常微妙,在 klanomath 和 David Anderson 分析机器时,只需一条命令就可能失去一切,而某人会运行修复操作,丧失修复分区表和分配大小信息的最后机会,而这些信息是他们手工编辑的。根据我的经验,修复会使账目恢复正常,但代价是丢失数据。 - bmike
在我的情况下,我不得不在磁盘的每个分区上运行“急救工具”,否则系统在调整大小后将无法再次启动。我陷入了一个重启循环中。 - Bemipefe

当您尝试扩大APFS容器时,如果其下方几乎没有或没有任何可用空间,就会出现此错误消息。例如,下面是一个磁盘映像的diskutil list disk2输出,其中几乎所有的可用空间都已分配给了分区。
/dev/disk2 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.0 TB     disk2
   1:                        EFI EFI                     209.7 MB   disk2s1
   2:                  Apple_HFS tbd                     749.9 GB   disk2s2
   3:                 Apple_APFS Container disk3         249.8 GB   disk2s3

一个人可以看到 209.7 MB + 749.9 GB + 249.8 GB = 1.000 TB。如果输入以下命令,那么 disk2s1disk2s2 将被转换为空闲空间。
diskutil erasevolume free none disk2s1
diskutil erasevolume free none disk2s2

在输入上述命令后,diskutil list disk2 的输出结果如下所示。
/dev/disk2 (disk image):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        +1.0 TB     disk2
   1:                 Apple_APFS Container disk3         249.8 GB   disk2s3

以下命令可用于将位于 APFS 分区下方的空闲空间返回给所包含的 APFS 容器。
diskutil apfs resizeContainer disk2s3 0 

然而,由于所有重要的空闲空间都在分区上方,将生成以下错误消息。
Started APFS operation
Error: -69743: The new size must be different than the existing size

通过输入以下命令,可以确定 disk2s3 分区的确切位置和大小。
diskutil info disk2s3 | grep -e Offset -e Size

在这种情况下,该命令会产生以下输出。
   Partition Offset:         750209736704 Bytes (1465253392 512-Byte-Device-Blocks)
   Disk Size:                249.8 GB (249790263296 Bytes) (exactly 487871608 512-Byte-Units)
   Device Block Size:        512 Bytes

以下的总和结果是 disk2s3 分区的结束位置。
750,209,736,704 bytes 249,790,263,296 bytes  = 1,000,000,000,000 bytes = 1.000 TB

可以看到,在disk2s3分区之后几乎没有可感知的空闲空间,这就是为什么出现了错误消息。

可以通过输入以下命令来确定磁盘映像的确切大小

diskutil info disk2 | grep Size

在这种情况下,输出如下所示。
   Disk Size:                1.0 TB (1000000020480 Bytes) (exactly 1953125040 512-Byte-Units)
   Device Block Size:        512 Bytes

这显示在disk2s3分区结束后存在20480字节的空间。然而,并不是所有的空间都是可用的。其中一部分空间被GUID分区表(GPT)的备份副本占用。
由于这是一个磁盘映像,可以输入以下命令而无需禁用系统完整性保护(SIP)。
gpt -r show /dev/disk2

在这种情况下,该命令会产生以下输出。
       start        size  index  contents
           0           1         PMBR
           1           1         Pri GPT header
           2          32         Pri GPT table
          34  1465253358         
  1465253392   487871608      1  GPT part - 7C3457EF-0000-11AA-AA11-00306543ECAC
  1953125000           7         
  1953125007          32         Sec GPT table
  1953125039           1         Sec GPT header

这个输出显示在disk2s3分区之后实际上有7个扇区的空闲空间。由于扇区大小(设备块大小)为512字节,因此空闲空间计算为3584字节。这比diskutil apfs resizeContainer disk2s3 0命令所需的4096字节分配块大小要小。
目前,APFS的分配块大小固定为4096字节。在这种情况下,可以通过输入以下命令来确认分配块大小。
diskutil info disk3s1 | grep Allocation

以下是此命令的输出结果。
   Allocation Block Size:    4096 Bytes

你是在暗示OP 之前有一个750GB的分区,并且在删除/丢失它后发现disk0s2是唯一剩下的分区,而且正好位于磁盘的末尾?我认为这种可能性很小,更有可能的是EFI是第一个分区,之后是空闲空间,但需要使用gpt -r show或类似的命令来确认。如果他们删除了EFI 另一个较早的分区,你应该看到disk0s3作为剩下的分区(与你的测试一样),而不是disk0s2。 - lx07
@lx07:磁盘标识符与分区索引没有关联。你假设在我的例子中,disk0s3 是 GPT 中的第三个分区。虽然在我的例子开始时是正确的,但是从 gpt -r show /dev/disk2 命令的输出可以看出,在例子结束时,disk0s3 是 GPT 中的第一个分区。你也不能总是假设 GPT 中的分区按升序排列。不过,如果 diskutil 命令改变了 GPT,结果将会是按升序排列的分区。 - David Anderson
@lx07:老实说,我猜测楼主在某个时候重新启动了Mac。这会重新分配磁盘标识符。这可能是解释为什么标识符变成了disk0s2而不是disk0s3的一种方式。换句话说,在输入命令diskutil erasevolume free none disk0s1之前,楼主重启了Mac,然后才发表了这个问题。顺便说一下,你不需要禁用SIP并使用gpt命令来获取分区表。你可以使用diskutil命令或下载一个脚本来获取该表。 - David Anderson
1@lx07 OP很可能早些时候删除了disk0s2(大约750 GB的分区)并重新启动。在下一步中,OP成功删除了EFI分区(disk0s1)(屏幕截图中没有痕迹,但可能在终端窗口中进一步隐藏 - 可惜,在这里我们无法滚动屏幕截图),并且未能删除disk0s00和disk0s0(如屏幕截图所示)。 - klanomath
@klanomath:我没有确切的答案。如果diskutil命令能够输出分区偏移信息,那么脚本将会起作用。我知道这在High Sierra和更新版本的macOS上发生,但我不确定从哪个版本的macOS(OS X)开始。如果diskutil命令无法产生所需的输出,脚本将会生成错误消息。这就是为什么man页面显示了High Sierra和更新版本的macOS的原因。 - David Anderson
@DavidAnderson 啊,谢谢。我浏览了一下 man 手册,显然错过了“兼容性”部分。 - klanomath
@klanomath和DavidAnderson - 说得好 - 我忘了重启。 - lx07