thin pool用满后lvcreate不报错但写入失败,因thin provisioning存在overcommit风险,仅元数据分配不占物理空间,写入时可能eagain或hang;需监控data_percent、启用auto-extension、谨慎处理snapshot及metadata损坏风险。

thin pool 用满后 lvcreate 不报错但写入失败
Thin provisioning 的核心风险就是 overcommit:逻辑容量远超物理空间,lvcreate -T 创建 thin volume 时只分配元数据,不占实际空间。只要 thin pool 没满,命令就成功;但一写入就可能卡在 write() EAGAIN 或直接 hang 住——尤其对数据库、日志轮转这类持续写入场景。
实操建议:
- 永远用
lvs -o+data_percent,metadata_percent监控两个百分比,data_percent超过 85% 就该预警 - 启用 auto-extension:在
/etc/lvm/profile/thin_pool_activation.profile中设thin_pool_autoextend_threshold = 80和thin_pool_autoextend_percent = 20,避免手动干预延迟 - 别依赖
lvresize --poolmetadatasize临时扩容 metadata,它不解决 data 空间不足,且 metadata 扩容本身有 I/O 开销
snapshot 占用空间不可见,lvs 显示 size 为 0
thin snapshot 不是传统 copy-on-write 那种独立 LV,而是共享同一 thin pool 的数据块引用。所以 lvs 里它的 LSize 是 0,但实际占用由“写入差异量”决定——改得越多,占用越大,且不会自动释放。
常见错误现象:
- 创建 snapshot 后,
data_percent涨得飞快,但找不到哪个 LV 在写 -
lvconvert --merge失败,报Snapshot is busy,其实是 merge 过程中需要额外空间暂存新写入 - 误删原 LV 后 snapshot 仍存在,但变成只读孤儿,继续吃 pool 空间
实操建议:
- 用
lvs -o+origin,lv_layout区分 origin 和 snapshot,layout 字段显示thin或snapshot - 定期清理不用的 snapshot:
lvs | awk '/snapshot/ {print $1,$2}' | xargs -r -n2 sh -c 'lvremove -f $1/$2' - 不要对正在被 mount 或 open 的 LV 做 snapshot,否则可能触发 kernel 的 thin-pool lock 争用
thin pool 元数据损坏导致整个 VG 不可用
thin pool 的 metadata LV 是单点故障:它损坏,所有 thin volume(包括 snapshot)都会无法激活,vgchange -ay 报 Failed to activate thin pool,甚至 vgs 都可能卡住。
原因很实在:metadata 默认用 1MB 缓存 + 无冗余存储,SSD 掉电、ext4 journal 错乱、LVM bug 都可能让它变脏。
实操建议:
- 初始化 pool 时强制指定大一点的 metadata size:
lvcreate -L 10G -T vg/pool -M y --poolmetadatasize 16M(默认常只有 2–4M) - 定期备份 metadata:
thin_dump /dev/vg/pool_tmeta > /backup/pool_tmeta.dump.$(date +%F),出事时可用thin_restore回滚 - 避免在 metadata LV 上做 fsck 或 dd,它不是普通文件系统,操作即高危
MySQL InnoDB 在 thin LV 上因 discard 导致空间不回收
InnoDB 启用 innodb_file_per_table=ON + innodb_discard_threshold 后会主动 TRIM 删除的页,但 LVM thin 默认不透传 DISCARD 到底层设备——结果是 MySQL 认为空间已释放,LVM 却还记着那些块被占用,data_percent 居高不下。
实操建议:
- 确认 thin pool 支持 discard:
lvs -o+discards输出应为passdown,不是ignore;若为 ignore,需重建 pool 并加--discards passdown - 重建时注意顺序:先
lvconvert --thinpool --discards passdown vg/pool,再lvcreate -T新 volume - MySQL 侧配合:设
innodb_deadlock_detect=OFF减少 thin-pool 元数据锁竞争(尤其高并发 delete 场景)
thin provisioning 的麻烦不在配置,而在空间账本是三套并行记的:应用层以为自己在管理文件大小,文件系统在管理 block 分配,LVM 在管理 extent 引用。哪一层没对齐,overcommit 就从便利变成事故。最常被忽略的是 metadata 容量和 discard 透传,这两个不提前设好,后面扩容、恢复、性能优化全要绕弯。










