XFS filesystem shutdown when deleting millions of files on RHEL

在删除约50-60百万个小文件时,XFS文件系统在Red Hat Enterprise Linux 7上出现关闭问题。此问题在内核版本3.10.0-862.el7中得到解决。

XFS filesystem shutdown when deleting millions of files on RHEL

 SOLUTION UNVERIFIED - 已更新 2019年三月8日20:43 - 

English 

环境

  • Red Hat Enterprise Linux 7

问题

  • XFS file system shut down when deleting 50 ~ 60 million small files (5 ~ 10 KB).

Raw

kernel: XFS (dm-3): xlog_write: reservation summary:
  trans type  = INACTIVE (3)
  unit res    = 78564 bytes
  current res = -33148 bytes
  total reg   = 0 bytes (o/flow = 0 bytes)
  ophdrs      = 0 (ophdr space = 0 bytes)
  ophdr + reg = 0 bytes
  num regions = 0
kernel: XFS : xlog_write: reservation ran out. Need to up reservation
kernel: XFS : xfs_do_force_shutdown(0x2) called from line 2042 of file fs/xfs/xfs_log.c.  Return address = 0xffffffffa033edb8
kernel: XFS : xfs_imap_to_bp: xfs_trans_read_buf() returned error 5.
kernel: XFS : Log I/O Error Detected.  Shutting down filesystem
kernel: XFS : Please umount the filesystem and rectify the problem(s)
kernel: XFS : xfs_log_force: error 5 returned.

决议

This issue has been resolved by RHSA-2018:1062 please upgrade to kernel-3.10.0-862.el7 (7.5) or later for this fix.

Workaround

If you are unable to upgrade to the latest kernel some customers have reported success mounting the filesystem with the 'ikeep' mount option which prevents XFS from freeing unused inode clusters.

根源

This series refactors some of the transaction overrun reporting code in XFS to provide more useful error reports (patches 1-4) and refactors some of the log reservations associated with inode transactions to provide more accurate worst case reservations. This helps avoid transaction reservation overruns during particular workloads.

Below commits have been backported.

Raw

  xfs: separate shutdown from ticket reservation print helper
  xfs: refactor xlog_cil_insert_items() to facilitate transaction dump
  xfs: dump transaction usage details on log reservation overrun
  xfs: print transaction log reservation on overrun
  xfs: include inobt buffers in ifree tx log reservation
  xfs: fix up agi unlinked list reservations
  xfs: truncate transaction does not modify the inobt
  xfs: include an allocfree res for inobt modifications
  xfs: refactor inode chunk alloc/free tx reservation
  xfs: eliminate duplicate icreate tx reservation functions

诊断步骤

A metadump was taken of a filesystem exhibiting this issue for analysis.

Raw

# xfs_metadump -gow /dev/mapper/vg_data | bzip2 > reservation_failure.xfsmetadump.bz2 

The image was restored to a local volume group for testing.
kdump was configured and the system set to panic on log reservation failures.

Raw

# sysctl fs.xfs.error_level=11 fs.xfs.panic_mask=2
fs.xfs.error_level = 11
fs.xfs.panic_mask = 2
# bzcat ~/xfs-metadump.img.gz | xfs_mdrestore - /dev/mapper/vg_metadump
# mount /dev/mapper/vg_metadump /mnt/metadump
# find /mnt/metadump -type f -delete

Initial analysis of the vmcore

Raw

XFS (dm-2): xlog_write: reservation summary:
XFS (dm-2):   trans type  = INACTIVE (3)
XFS (dm-2):   unit res    = 47832 bytes
XFS (dm-2):   current res = -128 bytes
XFS (dm-2):   total reg   = 0 bytes (o/flow = 0 bytes)
XFS (dm-2):   ophdrs      = 0 (ophdr space = 0 bytes)
XFS (dm-2):   ophdr + reg = 0 bytes
XFS (dm-2):   num regions = 0
XFS (dm-2): Transforming an alert into a BUG.
XFS (dm-2): xlog_write: reservation ran out. Need to up reservation
------------[ cut here ]------------
kernel BUG at fs/xfs/xfs_message.c:97!
invalid opcode: 0000 [#1] SMP
Modules linked in: intel_powerclamp ... xfs ...
CPU: 0 PID: 29036 Comm: find Not tainted 3.10.0-514.el7.x86_64 #1
Hardware name: Dell Inc. PowerEdge R530/0CN7X8, BIOS 2.4.2 01/09/2017
task: ffff88085717af10 ti: ffff8806a1f50000 task.ti: ffff8806a1f50000
RIP: 0010:[<ffffffffa033c40c>]  [<ffffffffa033c40c>] xfs_alert_tag+0xec/0x100 [xfs]
RSP: 0018:ffff8806a1f53c08  EFLAGS: 00010246
RAX: 0000000000000043 RBX: ffff880858970000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff88085c60f838 RDI: ffff88085c60f838
RBP: ffff8806a1f53c78 R08: 0000000000000086 R09: 00000000000005d4
R10: 00000000000003ff R11: 0000000000000001 R12: ffff88066531cfd0
R13: ffff880858970000 R14: ffff880471dba108 R15: ffff880259574d68
FS:  00007f3fe617a800(0000) GS:ffff88085c600000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000840018 CR3: 0000000581fe9000 CR4: 00000000003407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Stack:
 ffffffffa0372da8 ffffffffa0372da8 ffff8806a1f53c20 ffff880600000018
 ffff8806a1f53c88 ffff8806a1f53c40 00000000668a0908 00000000668a0908
 ffff8802902afcb8 ffff8801bc792f80 0000000000000000 0000000000000000
Call Trace:
 [<ffffffffa0347f8f>] xlog_print_tic_res+0x14f/0x170 [xfs]
 [<ffffffffa034a629>] xfs_log_commit_cil+0x499/0x4d0 [xfs]
 [<ffffffffa034422d>] __xfs_trans_commit+0x12d/0x260 [xfs]
 [<ffffffffa0344610>] xfs_trans_commit+0x10/0x20 [xfs]
 [<ffffffffa0339bd4>] xfs_inactive_ifree+0x1d4/0x240 [xfs]
 [<ffffffffa0339ccd>] xfs_inactive+0x8d/0x130 [xfs]
 [<ffffffffa033f346>] xfs_fs_evict_inode+0xa6/0xe0 [xfs]
 [<ffffffff8121a0e7>] evict+0xa7/0x170
 [<ffffffff8121a985>] iput+0xf5/0x180
 [<ffffffff8120f31e>] do_unlinkat+0x1ae/0x2b0
 [<ffffffff812037f4>] ? SYSC_newfstatat+0x34/0x60
 [<ffffffff812102eb>] SyS_unlinkat+0x1b/0x40
 [<ffffffff816964c9>] system_call_fastpath+0x16/0x1b

crash> whatis xlog_print_tic_res
void xlog_print_tic_res(struct xfs_mount *, struct xlog_ticket *);
crash> dis -r ffffffffa0347f8f
0xffffffffa0347e40 <xlog_print_tic_res>:    nopl   0x0(%rax,%rax,1) [FTRACE NOP]
0xffffffffa0347e45 <xlog_print_tic_res+0x5>:    push   %rbp
0xffffffffa0347e46 <xlog_print_tic_res+0x6>:    mov    %rsp,%rbp
0xffffffffa0347e49 <xlog_print_tic_res+0x9>:    push   %r13
0xffffffffa0347e4b <xlog_print_tic_res+0xb>:    mov    %rdi,%r13
0xffffffffa0347e4e <xlog_print_tic_res+0xe>:    push   %r12
0xffffffffa0347e50 <xlog_print_tic_res+0x10>:   mov    %rsi,%r12
... r12 and r13 aren't changed later

crash> struct xlog_ticket ffff88066531cfd0
struct xlog_ticket {
  t_queue = {
    next = 0xffff88066531cfd0, 
    prev = 0xffff88066531cfd0
  }, 
  t_task = 0xffff88085717af10, 
  t_tid = 0x8fb68988, 
  t_ref = {
    counter = 0x1
  }, 
  t_curr_res = 0xffffff80,  (-128) 
  t_unit_res = 0xbad8,      (47832)
  t_ocnt = 0x2, 
  t_cnt = 0x1, 
  t_clientid = 0x69, 
  t_flags = 0x3, 
  t_trans_type = 0x3, 
  t_res_num = 0x0, 
  t_res_num_ophdrs = 0x0, 
  t_res_arr_sum = 0x0, 
  t_res_o_flow = 0x0, 
  t_res_arr = {{
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }, {
      r_len = 0x0, 
      r_type = 0x0
    }}
}
  • Related source code:

Raw

https://access.redhat.com/labs/psb/versions/kernel-3.10.0-229.el7/fs/xfs/xfs_log.c

void
xlog_print_tic_res(
        struct xfs_mount        *mp,
        struct xlog_ticket        *ticket)
{
        uint i;
        uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t);

        /* match with XLOG_REG_TYPE_* in xfs_log.h */
        static char *res_type_str[XLOG_REG_TYPE_MAX] = {
            "bformat",
            "bchunk",
            "efi_format",
            "efd_format",
            "iformat",
            "icore",
            "iext",
            "ibroot",
            "ilocal",
            "iattr_ext",
            "iattr_broot",
            "iattr_local",
            "qformat",
            "dquot",
            "quotaoff",
            "LR header",
            "unmount",
            "commit",
            "trans header"
        };
        static char *trans_type_str[XFS_TRANS_TYPE_MAX] = {
            "SETATTR_NOT_SIZE",
            "SETATTR_SIZE",
            "INACTIVE",
            "CREATE",
            "CREATE_TRUNC",
            "TRUNCATE_FILE",
            "REMOVE",
            "LINK",
            "RENAME",
            "MKDIR",
            "RMDIR",
            "SYMLINK",
            "SET_DMATTRS",
            "GROWFS",
            "STRAT_WRITE",
            "DIOSTRAT",
            "WRITE_SYNC",
            "WRITEID",
            "ADDAFORK",
            "ATTRINVAL",
            "ATRUNCATE",
            "ATTR_SET",
            "ATTR_RM",
            "ATTR_FLAG",
            "CLEAR_AGI_BUCKET",
            "QM_SBCHANGE",
            "DUMMY1",
            "DUMMY2",
            "QM_QUOTAOFF",
            "QM_DQALLOC",
            "QM_SETQLIM",
            "QM_DQCLUSTER",
            "QM_QINOCREATE",
            "QM_QUOTAOFF_END",
            "SB_UNIT",
            "FSYNC_TS",
            "GROWFSRT_ALLOC",
            "GROWFSRT_ZERO",
            "GROWFSRT_FREE",
            "SWAPEXT"
        };

        xfs_warn(mp,
                "xlog_write: reservation summary:\n"
                "  trans type  = %s (%u)\n"
                "  unit res    = %d bytes\n"
                "  current res = %d bytes\n"
                "  total reg   = %u bytes (o/flow = %u bytes)\n"
                "  ophdrs      = %u (ophdr space = %u bytes)\n"
                "  ophdr + reg = %u bytes\n"
                "  num regions = %u\n",
                ((ticket->t_trans_type <= 0 ||
                  ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
                  "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]),
                ticket->t_trans_type,
                ticket->t_unit_res,
                ticket->t_curr_res,
                ticket->t_res_arr_sum, ticket->t_res_o_flow,
                ticket->t_res_num_ophdrs, ophdr_spc,
                ticket->t_res_arr_sum +
                ticket->t_res_o_flow + ophdr_spc,
                ticket->t_res_num);

        for (i = 0; i < ticket->t_res_num; i++) {
                uint r_type = ticket->t_res_arr[i].r_type;
                xfs_warn(mp, "region[%u]: %s - %u bytes", i,
                            ((r_type <= 0 || r_type > XLOG_REG_TYPE_MAX) ?
                            "bad-rtype" : res_type_str[r_type-1]),
                            ticket->t_res_arr[i].r_len);
        }

        xfs_alert_tag(mp, XFS_PTAG_LOGRES,
                "xlog_write: reservation ran out. Need to up reservation");
        xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
}
<think>首先,用户的问题是关于解决错误消息:'xfs_growfs: /dev/sda3 is not a mounted XFS filesystem'。我需要基于提供的参考引用来解决这个问题。 回顾引用: - 引用[1]:讨论了在RHEL 7/CentOS 7中使用xfs_growfs扩容XFS文件系统,并提到了验证文件系统类型和添加磁盘空间。 - 引用[2]:提到了错误“Can't open /dev/sda3 exclusively. Mounted filesystem?”,这是在尝试扩展卷组时发生的错误。 用户的具体错误是“xfs_growfs: /dev/sda3 is not a mounted XFS filesystem”,这表示当尝试使用xfs_growfs时,/dev/sda3不是一个挂载的XFS文件系统。 关键点: - xfs_growfs命令用于扩展已挂载的XFS文件系统。它不能直接在未挂载的分区上使用。 - 错误消息表明/dev/sda3要么没有挂载,要么不是XFS文件系统,或者它不是文件系统设备。 从引用[2]中,有线索:用户可能试图操作/dev/sda3,但错误提示它可能被挂载或访问问题。 步骤来解决这个错误: 1. **验证文件系统类型**:确保/dev/sda3确实是XFS文件系统。 - 使用命令:`df -Th` 或 `lsblk -f` 来检查文件系统类型和挂载点。 - 如果它不是XFS,错误是合理的,因为xfs_growfs只适用于XFS。 2. **检查挂载状态**:xfs_growfs需要文件系统已挂载。 - 使用`mount | grep sda3` 或 `findmnt /dev/sda3` 来检查是否挂载。 - 如果未挂载,需要先挂载它。 3. **挂载文件系统**:如果/dev/sda3未挂载,需要挂载它到一个挂载点。 - 例如:`mount /dev/sda3 /mnt/somepoint` - 然后使用xfs_growfs:`xfs_growfs /mnt/somepoint` 4. **确认设备可用性**:确保设备存在且没有冲突。 - 使用`lsblk` 列出块设备。 - 检查是否有其他进程锁定设备,如引用[2]中的错误。 5. **扩展文件系统**:一旦挂载,使用xfs_growfs扩展。 引用[1]中提到扩展XFS,但要确保它挂载。 引用[2]中的错误“Can't open /dev/sda3 exclusively. Mounted filesystem?”表明设备可能被挂载或在用,这不同但相关。用户这里的错误是相反的:它认为设备未挂载。 所以,解决方法: - 确保/dev/sda3是XFS文件系统。 - 确保它已挂载。 - 然后使用xfs_growfs在挂载点上,而不是设备路径上。命令是`xfs_growfs [mountpoint]`,而不是`xfs_growfs /dev/sda3`。 澄清:xfs_growfs的参数应该是挂载点,而不是设备文件。用户可能错误地用设备文件作为参数。 例如,正确命令:`xfs_growfs /` 如果挂载在根目录下。 所以,用户可能试图运行`xfs_growfs /dev/sda3`,但应该运行`xfs_growfs [mountpoint]`。 结构化回答: 1. **理解错误**:解释为什么发生错误。 2. **步骤解决**: a. 验证文件系统类型:使用`df -Th` 或 `lsblk -f`。 b. 检查挂载状态:使用`mount | grep sda3` 或 `findmnt /dev/sda3`。 c. 如果未挂载,挂载文件系统到临时挂载点。 d. 使用xfs_growfs:`xfs_growfs [mountpoint]`。 3. **预防措施**:确保在扩展前备份数据。 4. **相关引用**:自然地引用提供的引用。例如,引用[1]提到验证文件系统类型。 生成相关问题:根据系统级指令,我需要生成相关问题。 回答结构清晰:使用中文回答。 最后,添加引用标识在引用的段落末尾。 回答框架: - 解释错误原因。 - 提供解决步骤。 - 生成相关问题。 </think>### 解决 'xfs_growfs: /dev/sda3 is not a mounted XFS filesystem' 错误的方法 这个错误通常发生在尝试使用 `xfs_growfs` 命令扩展 XFS 文件系统时,系统检测到 `/dev/sda3` 设备未被正确识别为已挂载的 XFS 文件系统。可能的原因包括:设备未挂载、文件系统类型不是 XFS、参数使用错误(如直接指定设备路径而非挂载点),或设备已被其他进程占用(如引用[2]中提到的独占访问问题)。下面我将逐步解释解决方法,确保操作安全可靠。操作前,建议备份重要数据,并在测试环境中验证。 #### 错误原因分析 - `xfs_growfs` 命令只能用于**已挂载**的 XFS 文件系统。它要求指定挂载点(如 `/home`),而不是设备路径(如 `/dev/sda3`)。 - 如果您直接运行 `xfs_growfs /dev/sda3`,系统会报错,因为 `/dev/sda3` 未被识别为一个挂载点。错误消息明确指示设备未挂载或不是有效的 XFS 文件系统。 - 引用[1]中强调,在执行扩展前必须验证文件系统类型和挂载状态(例如使用 `df -Th` 命令),否则可能引发此类错误。 - 引用[2]中提到的错误(“Can't open /dev/sda3 exclusively. Mounted filesystem?”)也可能相关,它表明设备可能被占用或挂载冲突,需要先解除锁定。 #### 解决步骤 按照以下步骤操作,可以解决错误并成功扩展文件系统。假设您是在 RHEL 7 / CentOS 7 系统上操作(如引用[1]的环境)。 1. **验证文件系统类型和挂载状态** 首先,确认 `/dev/sda3` 确实是 XFS 文件系统且已挂载。使用 `df -Th` 命令查看所有文件系统的类型和挂载点: ```bash df -Th ``` - 在输出中,检查 `/dev/sda3` 对应的行: - 如果 **Type 列显示 “xfs”**,说明它是 XFS 文件系统。 - 如果 **Mounted on 列显示一个挂载点**(如 `/home`),说明它已挂载。 - 如果未列出 `/dev/sda3` 或 Type 列不是 “xfs”,则它不是有效的 XFS 文件系统,您可能需要重新格式化或检查分区表。 - 示例输出(基于引用[1]): ``` Filesystem Type Size Used Avail Use% Mounted on /dev/sda3 xfs 8.0G 33M 8.0G 1% /home # 示例,假设sda3挂载在/home ``` - 如果未挂载,您会看到 `/dev/sda3` 不在列表中。 如果输出中无 `/dev/sda3`,使用 `lsblk -f` 命令进一步检查设备: ```bash lsblk -f ``` - 确认 `/dev/sda3` 的 FSTYPE 是否为 “xfs”。 2. **挂载文件系统(如果未挂载)** 如果第一步确认 `/dev/sda3` 未挂载,您需要先挂载它到一个空闲挂载点: - 创建一个临时挂载点(例如 `/mnt/sda3`): ```bash sudo mkdir -p /mnt/sda3 ``` - 挂载设备: ```bash sudo mount /dev/sda3 /mnt/sda3 ``` - 如果挂载失败,检查设备是否被占用(如引用[2]的错误)。使用 `fuser -v /dev/sda3` 查看占用进程,并停止相关服务。 - 如果设备是逻辑卷的一部分(如 LVM),确保卷组已激活(使用 `vgdisplay` 和 `lvdisplay` 命令)。 3. **正确运行 xfs_growfs** - `xfs_growfs` 的参数必须是挂载点,而不是设备路径: ```bash sudo xfs_growfs [挂载点] ``` - 例如,如果 `/dev/sda3` 挂载在 `/home`,运行: ```bash sudo xfs_growfs /home ``` - 如果挂载在临时点 `/mnt/sda3`,运行: ```bash sudo xfs_growfs /mnt/sda3 ``` - 命令成功时,输出会显示文件系统的新大小(如 “data blocks changed from X to Y”)。 - **注意**:确保文件系统有可扩展的空间(如通过 `fdisk` 或 `parted` 扩展分区后)。操作后,使用 `df -h` 验证大小变化。 4. **处理常见问题** - **设备被占用(如引用[2])**:如果挂载或扩展时出现 “Can't open /dev/sda3 exclusively”,卸载设备并重试: ```bash sudo umount /dev/sda3 # 卸载 sudo xfs_repair /dev/sda3 # 可选:修复文件系统 sudo mount /dev/sda3 /mnt/sda3 # 重新挂载 sudo xfs_growfs /mnt/sda3 ``` - **文件系统损坏**:运行 `xfs_repair` 检查: ```bash sudo xfs_repair /dev/sda3 ``` - **非 XFS 文件系统**:如果您误判文件系统类型,需备份数据后重新格式化为 XFS: ```bash sudo mkfs.xfs /dev/sda3 # 警告:这会清除数据! ``` #### 注意事项 - **安全第一**:操作前备份数据(使用 `rsync` 或云快照)。扩容通常需要磁盘空间已通过虚拟机或物理方式添加(如引用[1]所述)。 - **权限**:使用 `sudo` 运行所有特权命令。 - **参考依据**:本方法基于 XFS 文档和引用[1][^1]的最佳实践。如果您遇到类似引用[2][^2]的卷组问题,可能需要先解决 LVM 配置。 通过以上步骤,错误应该被解决。如果问题持续,提供更多系统日志(如 `/var/log/messages`)有助于诊断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值