与数据 = 有序相比,数据 = 日志对于 Ext4 是否更安全?

Tim*_*Tim 42 ext4

Ext4 的默认日志模式是data=ordered,根据文档,这意味着

“在将元数据提交到日志之前,所有数据都被直接强制输出到主文件系统。”

但是,还有一个data=journal选项,这意味着

“所有数据在写入主文件系统之前都会提交到日志中。启用此模式将禁用延迟分配和 O_DIRECT 支持。”

我对此的理解是,该data=journal模式将记录所有数据以及元数据,从表面上看,这似乎意味着这是就数据​​完整性和可靠性而言最安全的选择,尽管对于性能而言可能不是那么多。

如果可靠性是最重要的,但性能要低得多,我应该选择这个选项吗?使用此选项有什么注意事项吗?

作为背景,有问题的系统在 UPS 上,并且驱动器上的写缓存被禁用。

Cor*_*ren 36

是的,这data=journal是将数据写入磁盘的最安全方式。由于所有数据和元数据在写入磁盘之前都会写入日志,因此您始终可以在发生崩溃时重放中断的 I/O 作业。它还禁用延迟分配功能,这可能会导致数据丢失

3 种模式在手册中按安全性顺序列出:

  1. 数据=期刊
  2. 数据=有序
  3. 数据=写回

还有一个您可能感兴趣的选项:

commit=nrsec    (*) Ext4 can be told to sync all its data and metadata
                    every 'nrsec' seconds. The default value is 5 seconds.
Run Code Online (Sandbox Code Playgroud)

唯一已知的警告是它可能会变得非常缓慢。您可以通过使用该noatime选项禁用访问时间更新来降低性能影响。

  • 您指出禁用延迟分配更安全。但是,我找不到“data=journal”提供比“data=ordered”+“nodellalloc”更安全的结果的情况。你是否有一个? (2认同)

小智 5

该线程非常旧,但仍然相关。

我们想要合并 MySQL 数据库上的许多微小写入,并使用 Ceph RBD 映像作为 KVM 下的 VM 运行。

访客:CentOS 6 VM 的 /etc/fstab:

/dev/sda1               /                       ext4    defaults,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0,noatime,nodiratime,commit=60,data=journal,discard 1 1
Run Code Online (Sandbox Code Playgroud)

“/dev/sda”设备 (1 TiB) 位于压缩纠删码 NVMe 池中,在三重复制 NVMe 池中具有相对较小 (128 MiB) 的专用日志设备。

以下是我们在救援环境中使用的命令:

分离日志:

tune2fs -O ^has_journal /dev/sda1;
Run Code Online (Sandbox Code Playgroud)

检查文件系统是否存在不一致:

fsck.ext4 -f -C 0 /dev/sda1;
Run Code Online (Sandbox Code Playgroud)

获取块大小:

tune2fs -l /dev/sda1;
Run Code Online (Sandbox Code Playgroud)

格式化专用日志设备(警告):

最小日志大小应为 1024 * 块大小(为了安全起见,我们使用 128 MiB)

设置块大小以匹配 /dev/sda1

mke2fs -O journal_dev -L root_journal /dev/sdb1 -b 4096;
Run Code Online (Sandbox Code Playgroud)

将专用日志设备附加到文件系统:

tune2fs -j -J device=LABEL=root_journal /dev/sda1;
Run Code Online (Sandbox Code Playgroud)

MySQL 设置:

[mysqld]
innodb_old_blocks_time = 1000           # Prevent buffer pool pollution. Default as of MySQL 5.6
innodb_buffer_pool_size = 24576M        # MySQL Cache
innodb_log_buffer_size = 128M           # 25% of log_file_size
innodb_log_file_size = 512M             # 25% of the buffer_pool (no, not really)
query_cache_size = 128M                 # Query Cache
table_cache = 512                       # Make it large enough for: show global status like 'open%';
#mysqltuner.pl:
innodb_flush_method = O_DSYNC           # Don't validate writes. MySQL 5.6+ should use O_DIRECT
innodb_flush_log_at_trx_commit = 2      # Flush MySQL transactions to operating system cache
join_buffer_size = 256K
thread_cache_size = 4
innodb_buffer_pool_instances = 16
skip-innodb_doublewrite
Run Code Online (Sandbox Code Playgroud)

  • 所以?发生了什么变化? (9认同)