updatedb 用于更新 locate 命令使用的文件名数据库。locate 之所以能快速搜索文件,就是因为它不是实时扫描文件系统,而是查询 updatedb 预先构建的数据库。updatedb 通常由 cron 定时任务自动执行(每日一次)。

新创建的文件在 updatedb 运行之前,locate 是搜不到的。如果你刚创建/移动了文件并想立即搜索到它,手动运行 sudo updatedb 即可。

语法

updatedb [选项]

常用选项

选项含义
-o FILE数据库输出到指定文件
-U PATH仅扫描指定目录
-l LEVEL详细程度 (0=静默, 1=默认)
-e PATHS排除指定路径(逗号分隔)
--prunefs排除的文件系统类型
--prunenames排除的文件/目录名模式
--prunepaths排除的路径

基础用法

1. 基本数据库更新

# 手动更新数据库(需要 root 权限)
sudo updatedb

# 查看数据库文件位置
locate -S
# 或
ls -lh /var/lib/mlocate/mlocate.db

# 查看数据库统计信息
locate -S
# Database /var/lib/mlocate/mlocate.db:
#     15234 directories
#     89456 files
#     12345678 bytes in file names
#     5678901 bytes used to store database

2. 仅扫描特定目录

# 仅更新 /home 下的文件索引
sudo updatedb -U /home

# 仅更新 /opt 和 /usr/local
sudo updatedb -U /opt -U /usr/local

# 自定义输出数据库位置
sudo updatedb -o /tmp/myhome.db -U /home

# 使用自定义数据库搜索
locate -d /tmp/myhome.db myfile

3. 排除不需要扫描的路径

# 临时排除某个路径
sudo updatedb -e "/mnt,/media,/tmp"

# 永久配置: 编辑 /etc/updatedb.conf
cat /etc/updatedb.conf

# 典型配置:
# PRUNE_BIND_MOUNTS="yes"
# PRUNEFS="NFS nfs nfs4 afs binfmt iso9660 udf tmpfs"
# PRUNENAMES=".git .svn .hg"
# PRUNEPATHS="/tmp /var/spool /media /mnt /var/cache"

# 自定义排除规则
cat > /tmp/updatedb_custom.conf << 'EOF'
PRUNE_BIND_MOUNTS="yes"
PRUNEFS="NFS nfs nfs4 afs binfmt iso9660 udf tmpfs devtmpfs"
PRUNENAMES=".git .svn .hg .cache node_modules vendor"
PRUNEPATHS="/tmp /var/spool /media /mnt /var/cache /snap"
EOF

# 使用自定义配置运行
sudo updatedb --prunefs="NFS tmpfs" --prunenames=".git"

4. 监控 updatedb 性能

#!/bin/bash
# 运行 updatedb 并记录性能指标

echo "==updatedb 性能分析=="
echo "开始时间: $(date)"

START_TIME=$(date +%s)

# 运行 updatedb 并记录资源使用
sudo /usr/bin/time -v updatedb 2>&1 | tee /tmp/updatedb_time.log

END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))

echo ""
echo "==结果=="
echo "耗时: ${DURATION}s"
echo "数据库大小: $(ls -lh /var/lib/mlocate/mlocate.db | awk '{print $5}')"

# 提取 CPU 和内存信息
grep -E "User time|System time|Maximum resident" /tmp/updatedb_time.log

5. 设置定时更新

# 查看默认的 cron 配置(通常是 /etc/cron.daily/mlocate)
cat /etc/cron.daily/mlocate 2>/dev/null || cat /etc/cron.daily/locate 2>/dev/null

# 自定义 cron 配置
# 每天凌晨 2 点更新
sudo bash -c 'echo "0 2 * * * root /usr/bin/updatedb" > /etc/cron.d/custom-updatedb'

# 更频繁更新(每 4 小时)
sudo bash -c 'echo "0 */4 * * * root /usr/bin/updatedb" > /etc/cron.d/frequent-updatedb'

# 使用 systemd timer(替代 cron 的现代方式)
sudo tee /etc/systemd/system/updatedb.timer << 'EOF'
[Unit]
Description=Daily locate database update

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl enable --now updatedb.timer

6. 与 locate 联动排查

# 场景: locate 找不到刚创建的文件
echo "test content" > /tmp/test_locate_file.txt

# 检查文件存在
ls -l /tmp/test_locate_file.txt

# locate 搜不到(数据库还没更新)
locate test_locate_file 2>/dev/null
# (无输出)

# 手动更新数据库
sudo updatedb

# 再次搜索
locate test_locate_file
# /tmp/test_locate_file.txt

# 清理
rm /tmp/test_locate_file.txt

7. 大文件系统的优化策略

#!/bin/bash
# 对于超大文件系统(数百万文件),分部分更新
# 策略: 将不同目录的数据库分开管理

# 1. 为主要目录创建独立数据库
sudo updatedb -o /var/lib/mlocate/home.db -U /home
sudo updatedb -o /var/lib/mlocate/opt.db -U /opt
sudo updatedb -o /var/lib/mlocate/usr.db -U /usr

# 2. 创建主数据库(排除已独立索引的)
sudo updatedb \
    -e "/home,/opt,/usr" \
    -o /var/lib/mlocate/main.db

# 3. 搜索时合并多个数据库
search_all() {
    local query="$1"
    for db in /var/lib/mlocate/{main,home,opt,usr}.db; do
        [ -f "$db" ] && locate -d "$db" "$query"
    done
}

search_all "nginx.conf"

# 4. 查看各数据库统计
for db in /var/lib/mlocate/{main,home,opt,usr}.db; do
    [ -f "$db" ] && echo "=== $(basename $db) ===" && locate -d "$db" -S
done

8. 备份和恢复数据库

# 备份当前数据库
sudo cp /var/lib/mlocate/mlocate.db /var/backups/mlocate.db.$(date +%Y%m%d)

# 恢复到之前的数据库
# 如果 updatedb 运行出错导致数据库损坏
sudo cp /var/backups/mlocate.db.20260614 /var/lib/mlocate/mlocate.db

# 验证数据库有效性
locate -S
locate /
# 如果能正常输出,说明数据库有效
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐