Linux系统提⽰Nospaceleftondevice解决⽅法
在Linux环境上创建、拷贝⽂件或者vi编辑⽂件保存时经常会遇到系统提⽰"No space left on device"提⽰空间不⾜的问题。这种问题通常是由于磁盘空间不⾜或者inodes节点不⾜导致。解决办法也很简单就是删除不需要的⽂件进⾏磁盘空间或者inode节点释放。本⽂主要描述出现该问题时的分析⽅法和删除⽂件⽅法,包括:
(1)"No space left on device"问题分析,通过df -h查看是否磁盘空间不⾜,df -i查看是否inode节点不⾜。
(2)如何快速查磁盘空间不⾜对应⽂件系统中的超⼤⽂件并进⾏删除。
(3)介绍使⽤find指令或者脚本快速删除⽆⽤⽂件。
问题现象
在创建⽂件或者vi编辑保存⽂件时linux系统提⽰"No space left on device"。
问题分析
出现"No space left on device"提⽰信息导致操作失败的原因通常有3种:
(1)⽂件系统中⽂件占⽤空间总量即将或超过100%。通过df -h可以查看是否有⽂件系统空间使⽤率快达到100%或已达到100%。(2)⽂件已经删除但是存在占⽤⽂件的进程导致空间未释放。可以通过df和lsof指令查看。df查看⽂件系统空间充⾜,lsof查看存在已删除⽂件占⽤的进程。
(3)inodes节点不⾜导致。这种情况通常是系统上有⾮常多的单个⽂件占⽤空间很⼩但是数量很多导致。常见于linux服务器上安装有oracle数据库的场景。oracle数据库会⽣成很多的⽇志⽂件。
问题解决
(1)⽂件系统中⽂件占⽤空间总量即将或超过100%问题解决
Step1、利⽤df命令确定将磁盘空间即将耗尽的⽂件系统对应的⽬录。
linux~ # df
⽂件系统 1K-块已⽤可⽤已⽤% 挂载点
/dev/sda2 1462944922824443211049870821% /
/dev/sda1 1019208623609042407% /boot
tmpfs 1032204010322040% /dev/shm
/dev/sdb1 288428410828842841080100% /home
根据上述结果可知,/dev/sdb1磁盘空间即将达到100%,对应的挂载点为/home⽬录。进⼊/home⽬录进⾏查删除操作即可。
Step2、利⽤du命令逐级查占⽤磁盘空间较⼤的⽂件或者⽂件夹。
linux~ # du -sm /home
Step3、删除查到的⽆⽤的安装包、备份包⽂件或者长期未清理的debug⽇志。如果查确认之后发现并⽆占⽤较⼤空间的⽂件,需确认该⽂件系统挂载点/home⽬录下是否已被使⽤并且存在占⽤空间较⼤的⽂件。使⽤umout /home卸载挂载点查看。具体查删除⽂件⽅法可以查看FAQ。
Step4、重新执⾏df命令查看/dev/sdb1磁盘空间使⽤率是否降低。如果磁盘空间释放⼤⼩与已删除⽂件⼤⼩不⼀致,参考"df与du显⽰磁盘空间不⼀致问题解决"
2、df与du显⽰磁盘空间不⼀致问题解决
使⽤df命令查看⽂件系统空(/home)间不⾜,删除⼤⽂件后执⾏df重新查看,⽂件系统空间却并未增加。可能是删除⽂件时仍有进程在使⽤,删除时只是对删除⽂件做deleted标记并未真正释放。空间未释放。
分析解决⽅法如下:
Step1、du -sm /home查看对应⽂件系统⽂件占⽤⼤⼩。发现⽂件占⽤空间远远⼩于df查看占⽤的空间。
Step2、使⽤lsof指令查看被标记deleted但未真正释放的⽂件
linux~ # lsof /home | grep 'deleted'
或者
linux~ # ls -ald /proc/*/fd/* | grep 'deleted' | grep -v 'pts'
根据上述结果发现确实有进程占⽤刚删除的⼤⽂件。
Step3、kill掉占⽤删除⽂件的进程
linux~ # lsof /home | grep 'deleted' | grep -v grep | awk '{print $2}' | sort|xargs kill -9
或者⼿⼯获取占⽤⽂件的进程ID,执⾏kill -9 ${ID}
Step4、重新执⾏df查看,问题解决。
3、df -i显⽰inodes使⽤率即将100%
Step1、df -i查看inodes使⽤率即将达到100%。获取对应的⽂件系统挂载⽬录。如/home
Step2、使⽤find命令查⽂件,删除不需要使⽤的⽂件。通常为业务⽇志⽂件、oracle数据库⽇志⽂件、审计⽂件等等。⼤⽂件很少会出现这种情况,因为有⼤量⼤⽂件的话,⾸先应该是会把磁盘空间占满。具体查删除⽂件⽅法可以参考FAQ。
Step3、删除⽂件,重新执⾏df -i查看,问题解决。
4、FAQs
1、如何实现⾃动删除服务器垃圾⽂件?
需求描述
(1)假设业务运⾏产⽣的⽇志⽂件⽣成路径位于$HOME/log⽬录下,⽂件名为'⽤户名_[debug|run|warn].log'或者'⽤户名
_[debug|run|warn].log.n',n为数字,常为备份名。
(2)假设业务运⾏产⽣的临时⽂件⽣成路径位于$HOME/temp⽬录,⽂件名为'⽤户名_[debug|run|warn].tmp'或者'⽤户名
_[debug|run|warn].tmp.n',n为数字,常为备份名。
(3)查Linux服务器超过指定⼤⼩(如100M)的安装包、备份包⽂件,供⽤户⼈⼯判断是否可以删除。
(4)不能误删系统⽂件,特别是oracle⽤户的重做⽇志⽂件(redoN.log)。
代码实现
#!/bin/bash
#********************************************************
#*** Author : lion
#*** Create Date : 2017/09/18
#*** Modify Date : NA
#*** Function : Delete the server logs and temp files
#********************************************************
function Usage()
{
echo"NAME"
echo" clearlogs.sh"
echo"SYNOPSIS"
echo" clearlogs.sh"
echo"DESCRIPTION"
echo" clear the server logs and temp files"
exit 0
}
function writelog()
{
local logfile=$1
local debug_level=$2
local messages=$3
echo"[$(date '+%Y-%m-%d %H:%M:%S')] [${debug_level}] ${messages}"
echo"[$(date '+%Y-%m-%d %H:%M:%S')] [${debug_level}] ${messages}" >> ${logfile}
}
function find_logs()
{
local user=$1
local user_home=$2
if [ -d ${user_home}/log ];then
find ${user_home}/log -maxdepth 2 -type f -name "${user}*.log*" -mtime +${KEEP_DAYS} -print >> "${DELETE_LOGS_LIST}" fi
if [ -d ${user_home}/temp ];then
find ${user_home}/temp -maxdepth 2 -type f -name "${user}*.tmp*" -mtime +${KEEP_DAYS} -print >> "${DELETE_LOGS_LIST}" fi
}
if [ "X$1" == "X--help" ];then
Usage
fi
if [ $(whoami) != 'root' ];then
printf "Please use root to execute\n"
exit 1
fi
##global Var
CURRENT_PATH=$(pwd)
CURRENT_DATE=$(date'+%Y%m%d')
SCRIPT_NAME="clearlogs"
CLEARLOGS_DIR="${CURRENT_PATH}/${SCRIPT_NAME}_${CURRENT_DATE}"
SEARCH_FILE_SIZE='100M'
LOG_FILE="${CLEARLOGS_DIR}/${SCRIPT_NAME}.log"
DELETE_LOGS_LIST="${CLEARLOGS_DIR}/${SCRIPT_NAME}_delete_files.log"
USER_LIST="${CLEARLOGS_DIR}/user.lst"
BIG_FILES_LIST="${CLEARLOGS_DIR}/${SCRIPT_NAME}_bigfile.lst"
KEEP_DAYS=3
if [ ! -d ${CLEARLOGS_DIR} ];then
mkdir ${CLEARLOGS_DIR}
fi
rm"${DELETE_LOGS_LIST}""${USER_LIST}""${BIG_FILES_LIST}" &> /dev/null
touch"${DELETE_LOGS_LIST}""${USER_LIST}""${BIG_FILES_LIST}"
awk -F':''{if($0 !~ /var/)print $1,$6}' /etc/passwd > "${USER_LIST}"
writelog "${LOG_FILE}""INFO""Begin find logs and temp files,wait "
while read user user_home
do
find_logs ${user} ${user_home} &
done < "${USER_LIST}"
wait
writelog "${LOG_FILE}""INFO""End find logs and temp files"
writelog "${LOG_FILE}""INFO""Begin delete logs and temp files at ${DELETE_LOGS_LIST}"
while read line
do
if [ -f ${line} ];then
rm ${line} &> /dev/null
if [ $? -eq 0 ];then
writelog "${LOG_FILE}""INFO""File[ ${line} ] delete success"
else
writelog "${LOG_FILE}""INFO""File[ ${line} ] delete failed"
fi
fi
done < "${DELETE_LOGS_LIST}"
writelog "${LOG_FILE}""INFO""End delete logs and temp files at ${DELETE_LOGS_LIST}"
writelog "${LOG_FILE}""INFO""Begin find larger than ${SEARCH_FILE_SIZE} files,wait "
find / \( -path '/proc' -o -path '/var' \) -prune -o -type f -size "+${SEARCH_FILE_SIZE}" -print > "${BIG_FILES_LIST}"
writelog "${LOG_FILE}""INFO""End find larger than ${SEARCH_FILE_SIZE} files"
writelog "${LOG_FILE}""INFO""The files at [ ${BIG_FILES_LIST} ] are larger than ${SEARCH_FILE_SIZE},please check and delete by manual"
View Code
使⽤⽅法
(1)上述代码已上传⾄github,下载路径:c,上传到root⽤户⽬录下,任意⽬录。
(2)执⾏chmod +x clearlogs.sh赋可执⾏权限。
(3)执⾏./clearlogs.sh。查看相关⽇志即可。
说明:1、脚本可以根据实际情况进⾏修改以适⽤当前产品;2、脚本多次运⾏测试正常后可配置定时任务进⾏定期清理删除。
2、Linux下如何快速查占磁盘空间⼤的⽂件
需求背景
清理服务器⽂件系统空间时经常需要查⼤⽂件以进⾏分析删除,从⽽释放空间。
设计思路
快速查服务器上所有超过指定⼤⼩的⽂件并显⽰。第⼀列显⽰⽂件⼤⼩,第⼆列显⽰⽂件绝对路径。通常可以直接如下命令进⾏查:find / -type f -size +100M -print
考虑加快查速度,分成多个⽬录在后台并发查并显⽰。获取⽬录⽅法如下
find / -maxdepth 2 \( -path '/proc' -o -path '/var' \) -prune -o -type d -print | grep '^/.*/'
假设⽂件名为,第⼀列显⽰⽂件⼤⼩,第⼆列显⽰⽂件路径如下:
awk -v filename="" -v filesize=$(stat -c %s "" ) 'BEGIN{print filesize/1024/1024"
M",filename}'
代码实现
linux命令查看文件夹大小#!/bin/bash
SEARCH_DIR_LIST=""
SEARCH_TEMP_FILES="search_"
SEARCH_FILES=""
file_size="100M"
if [ $(whoami) != 'root' ];then
printf "Please Use root to execute\n"
exit 1
fi
rm"${SEARCH_DIR_LIST}""${SEARCH_TEMP_FILES}""${SEARCH_FILES}" &> /dev/null
find / -maxdepth 2 \( -path '/proc' -o -path '/var' \) -prune -o -type d -print | grep'^/.*/'> "${SEARCH_DIR_LIST}"
printf "Begin search larger than ${file_size}M files,wait \n"
while read line
do
( find ${line} -type f -size +${file_size} -print >> "${SEARCH_TEMP_FILES}" ) &
done < "${SEARCH_DIR_LIST}"
wait
printf "End search larger than ${file_size}M files.\n"
printf "Begin Compute each files detail size,\n"
while read line
do
awk -v filename=${line} -v filesize=$(stat -c %s ${line}) 'BEGIN{print filesize/1024/1024"M",filename}' >> ${SEARCH_FILES} done < "${SEARCH_TEMP_FILES}"
wait
printf "End Compute each files detail size.\n"
printf "Please Check below files..\n"
cat ${SEARCH_FILES} | sort -rn
rm"${SEARCH_DIR_LIST}""${SEARCH_TEMP_FILES}"
printf "Script execute end!\n"
View Code
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论