Products
GG网络技术分享 2025-03-18 16:14 0
大家好,这里是关于[宝塔面板磁盘空间满、inodes满处理办法],[手把手教你学网站服务器常用脚本]问题的解答,希望对您有所帮助。如果你还想了解更多这方面的信息,请关注本站其他相关内容,共同学习吧!
教程大全inodes,宝塔面板,磁盘满
宝塔面板磁盘空间满、inodes满处理办法
很多朋友使用服务器突然会发现服务器的网站无法访问,并且MySQL等服务无法重启,主要原因就是磁盘空间满了。下面就针对宝塔面板给出磁盘空间清理的几种方式。
连入服务器SSH输入下方命令即可清理。请对照自己的实际情况来使用。
清理网站日志/php站点session/系统邮件/临时文件
cd /www/server/panel && python tools.pyc clear
清空面板回收站
rm -rf /www/Recycle_bin/*
清除mysql二进制日志(操作过程中会停止重启数据库)
/etc/init.d/mysqld stop
rm -f /www/server/data/ib_logfile*
rm -f /www/server/data/mysql-bin.*
/etc/init.d/mysqld start需要注意的是 执行rm命令时是不会返回任何提示的,直到能再次输入命令之前它都是正在删除文件的状态
能输入命令的时候即删除完成
清理完毕后可以输入以下命令检查磁盘剩余空间
df -h
只要Use%这一列没有一个达到100%就可以了
一般只需要关注系统盘,即第一行,若有挂载数据盘到www目录,也要注意。
在解释bt宝塔面板是什么之前,先简单说说一直以来建网站方法
wget -c ftp://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz && tar zxf lnmp1.3-full.tar.gz && cd lnmp1.3-full && ./install.sh lamp
上面只是解决了安装的问题,关于网站后面还有很多维护工作需要——网站监控、数据库备份、日志记录等等。 如果有专门的服务器管理软件就省事多了。因此服务器管理软件(俗称面板)就出现了。
面板的出现已经有很长历史了,bt面板、wdcp面板、plesk面板、amh面板、c panel。国外用C panel比较多,国内用BT宝塔面板。
C panel面板这个比较古老了,国外VPS厂商用的多。多数是英文版,并且操作起来不太符合国人操作习惯。
BT面板是国产的,原生支持中文,官网介绍“提升运维效率的服务器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能。”还有他是免费的,收费功能针对技术支持等业务。
所以直接用bt面板来建网站和管理网站了。
[bt面板官网] (https://www.bt.cn/?invite_code=MV9lcWR5emw=)。安装bt面板之后,注册账号,网站后台可以跟微信绑定,方便网站管理等。
具体安装过程可以查看 [阿里云服务器快速建网站_安装BT宝塔面板和wordpress] (https://zhuanlan.zhihu.com/p/137713506)
作为新手来说,免费版bt可满足大部分网站管理需求——网站搭建、运维监控、维护、备份数据库、备份网站、内存清理等等。
有人说面板的出现,“简直是开历史倒车,把Linux的B格大大降低,一点都没有极客风,面板小白都可以操作”,因此对面板深恶痛绝。对此我就呵呵了。 现代社会节奏那么快,不是那么多人有大把时间能沉下心思来把Linux系统从头到家系统学习一遍的。还怀念以前读书时候,还专门花上几个月来把Linux的系统学习。像《鸟哥的 Linux 私房菜-基础篇·第三版》、《The Linux Command Line》(William E. Shotts Jr)、《深入理解 Linux 内核》( Daniel P.Bovet / Marco Cesati)。 以前年轻时候,也不怎么做笔记,都是背命令。但是尴尬的地方在于,等到年纪大了,发现以前的命令记得不太多了,毕竟老话说得好“好记性不如烂笔头”。另外不是专门干Linux运维,如果不怎么用,这些命令很快就会遗漏。对这个没体会的,可以试试会议一下以前你的小学同学、中学同学,还能记起几个人名字?自然就有体会了。
算了,不叨叨那么多了。
当然也可以学习一下bt面板的脚本,学习为自己所用嘛,这就是这篇文章的由来。
所以,面板的出现,还是降低了不少小白上手Linux门槛的,所以面板的历史很早就出现了。而且正因为bt面板符合国人习惯,并且是免费的,集成了一大堆网站维护工具,另外还有专门的收费类服务解决个人和企业难题,bt面板从2014年开始到现在那么流行。
对了,在使用bt面板之前得要有个云服务器吧。这里推荐阿里云的云服务器(Elastic Compute Service,简称ECS)。根据其官网介绍是阿里云提供的性能卓越、稳定可靠、弹性扩展的IaaS(Infrastructure as a Service)级别云计算服务。
ECS即类似于国外的VPS。(不要好奇那么多人买国外VPS干嘛用)。架设个人博客网站、企业门户都可以使用ECS。如果其网站如个人博客主要面向国内用户访问,为加快速度还是建议选用国内的服务器商。
[阿里云域名] (https://wanwang.aliyun.com/domain/com/?userCode=yos4xyvp)连接,
[阿里云服务器ECS] (https://www.aliyun.com/minisite/goods?userCode=yos4xyvp) 链接
它的脚本有以下:
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
endDate=`date +"%Y-%m-%d %H:%M:%S"`
log="释放内存!"
echo "★[$endDate] $log"
echo '----------------------------------------------------------------------------'
for phpV in 52 53 54 56 70 71 72
do
if [ -f /etc/init.d/php-fpm-${phpV} ];then
/etc/init.d/php-fpm-${phpV} reload
fi
done
if [ -f "/etc/init.d/mysqld" ];then
/etc/init.d/mysqld reload
fi
if [ -f "/etc/init.d/nginx" ];then
/etc/init.d/nginx reload
fi
if [ -f "/etc/init.d/httpd" ];then
/etc/init.d/httpd graceful
fi
# httpd重新加载
if [ -f "/etc/init.d/pure-ftpd" ];then
pkill -9 pure-ftpd
sleep 0.3
/etc/init.d/pure-ftpd start 2>/dev/null
fi
# pkill -9 接进程名,杀死进程。
# 2>/dev/null的意思就是将标准错误stderr删掉。
sync
# sync 强制把文件系统buff写入磁盘,确保文件系统完整性。
sleep 2
sync
echo 3 > /proc/sys/vm/drop_caches
# 释放内存之前需要执行sync命令。sync 强制把文件系统buff写入磁盘,确保文件系统完整性。
# /proc是一个虚拟文件系统。
# 调整/proc/sys/vm/drop_caches来释放内存。
# 其默认值为0,值为1时表示可以释放pagecache缓存,值为2时可以释放pagecache和inode缓存,值为3时可以释放pagecache(页面缓存,磁盘块的任何内存映射)), dentries(目录的数据结构)和inodes(文件的数据结构)缓存。
# echo 3 > /proc/sys/vm/drop_caches,即调整其数值为3来释放内存(包括页面缓存、目录数据结构、文件数据结构等)。
echo '----------------------------------------------------------------------------'
#exit 0
CentOS 6.x 以前的版本中,系统的服务 (services) 启动的接口是在/etc/init.d/ 这个目录下,目录下的所有文件都是 scripts。
虽然/etc/init.d/* 这个脚本启动的方式 (systemV) 已经被新一代的 systemd 所取代 (从 CentOS 7 开始), 但是很多的个别服务在管理他们的服务启动方面,还是使用 shell script 的机制。
下面有nginx(nginx发音:恩静埃克斯 = Engine X)、mysqld、php-fpm-72等文件。
日期显示
endDate=`date +"%Y-%m-%d %H:%M:%S"`
mysqld重新加载
if [ -f "/etc/init.d/mysqld" ];then
/etc/init.d/mysqld reload
fi
通过reload命令,将其清理内存。
reload (重新加载),reload会重新加载配置文件,服务不会中断。而且reload时会测试conf语法等,如果出错会rollback用上一次正确配置文件保持正常运行。也叫平滑重启,不会对已经连接的服务造成影响。
httpd重新加载
if [ -f "/etc/init.d/httpd" ];then
/etc/init.d/httpd graceful
fi
要在重启 Apache 服务器时不中断当前的连接,则应运行:/usr/local/sbin/apachectl graceful
ftpd重新加载
if [ -f "/etc/init.d/pure-ftpd" ];then
pkill -9 pure-ftpd
sleep 0.3
/etc/init.d/pure-ftpd start 2>/dev/null
fi
pkill -9 接进程名,杀死进程。
睡眠0.3秒后,重新启动ftpd,并且2>/dev/null的意思就是将标准错误stderr删掉。
释放内存
sync
echo 3 > /proc/sys/vm/drop_caches
#!/usr/bin/python
#coding: utf-8
import sys
import os
import shutil
import time
import glob
print '=================================================================='
print '★['+time.strftime("%Y/%m/%d %H:%M:%S")+'],切割日志'
print '=================================================================='
print '|--当前保留最新的['+sys.argv[2]+']份'
logsPath = '/www/wwwlogs/'
oldFileName = logsPath+sys.argv[1]
if not os.path.exists(oldFileName):
print '|---'+sys.argv[1]+'文件不存在!'
exit()
logs=sorted(glob.glob(oldFileName+"_*"))
count=len(logs)
num=count - int(sys.argv[2])
for i in range(count):
if i>num:
break;
os.remove(logs[i])
print '|---多余日志['+logs[i]+']已删除!'
newFileName=oldFileName+'_'+time.strftime("%Y-%m-%d_%H%M%S")+'.log'
# time.strftime("%Y/%m/%d %H:%M:%S")生成为 '2019-12-12_200605'
shutil.move(oldFileName,newFileName)
if os.path.exists('/www/server/nginx/logs/nginx.pid'):
os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");
# cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。因为nginx启动会在该路径下生成nginx.pid文件。
# `反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。
# kill -USR1 中,信号量USR1代表重新打开文件。其在core/ngx_config.h中定义
#if (NGX_LINUXTHREADS)
#define NGX_REOPEN_SIGNAL INFO
#define NGX_CHANGEBIN_SIGNAL XCPU
#else
#define NGX_REOPEN_SIGNAL USR1
#define NGX_CHANGEBIN_SIGNAL USR2
#endif
else:
os.system('/etc/init.d/httpd reload');
print '|---已切割日志到:'+newFileName
这个脚本里面核心部分是
if os.path.exists('/www/server/nginx/logs/nginx.pid'):
os.system("kill -USR1 `cat /www/server/nginx/logs/nginx.pid`");
cat /www/server/nginx/logs/nginx.pid 显示nginx的pid进程号。因为nginx启动会在该路径下生成nginx.pid文件。 `反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。
kill -USR1 中,信号量USR1代表重新打开文件。其在core/ngx_config.h中定义
#if (NGX_LINUXTHREADS)
#define NGX_REOPEN_SIGNAL INFO
#define NGX_CHANGEBIN_SIGNAL XCPU
#else
#define NGX_REOPEN_SIGNAL USR1
#define NGX_CHANGEBIN_SIGNAL USR2
#endif
通过Python运行/www/server/panel/script/目录下的backup.py脚本,将网站www.xxx.com保存。保存备份数为3。
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
python /www/server/panel/script/backup.py site www.xxx.com 3
其调用的backup.py文件如下
#!/usr/bin/python
#coding: utf-8
#-----------------------------
# 宝塔Linux面板网站备份工具
#-----------------------------
import sys,os
reload(sys)
sys.setdefaultencoding('utf-8')
#Python2.x中由于str和byte之间没有明显区别,经常要依赖于defaultencoding来做转换。
# 在python3中有了明确的str和byte类型区别,从一种类型转换成另一种类型要显式指定encoding。
# 但是仍然可以使用这个方法代替
# import importlib,sys
# importlib.reload(sys)
os.chdir('/www/server/panel');
sys.path.append("class/")
# /www/server/panel/class 里有大量的模块文件,public.py, db.py。
# 通过改变路径方便下面导入模块。
import public,db,time
# 是class文件夹的模块文件
class backupTools:
def backupSite(self,name,count):
sql = db.Sql();
path = sql.table('sites').where('name=?',(name,)).getField('path');
#sql.table(self,table)设置表名
#def where(self,where,param):
# self.__OPT_WHERE = " WHERE " + where
# self.__OPT_PARAM = param
# WHERE name=?
#getField(self,keyName):#取回指定字段
#result = self.field(keyName).select();
startTime = time.time();
if not path:
endDate = time.strftime('%Y/%m/%d %X',time.localtime())
#'2019/12/12 20:41:01'
# %Y 年份2019 %m 月份 %d天 %X 标准的时间串
log = "网站["+name+"]不存在!"
print "★["+endDate+"] "+log
print "----------------------------------------------------------------------------"
return;
backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/site';
if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path);
filename= backup_path + "/Web_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.tar.gz'
public.ExecShell("cd " + os.path.dirname(path) + " && tar zcvf '" + filename + "' '" + os.path.basename(path) + "' > /dev/null")
endDate = time.strftime('%Y/%m/%d %X',time.localtime())
if not os.path.exists(filename):
log = "网站["+name+"]备份失败!"
print "★["+endDate+"] "+log
print "----------------------------------------------------------------------------"
return;
outTime = time.time() - startTime
pid = sql.table('sites').where('name=?',(name,)).getField('id');
sql.table('backup').add('type,name,pid,filename,addtime,size',('0',os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename)))
log = "网站["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒";
public.WriteLog('计划任务',log)
print "★["+endDate+"] " + log
print "|---保留最新的["+count+"]份备份"
print "|---文件名:"+filename
#清理多余备份
backups = sql.table('backup').where('type=? and pid=?',('0',pid)).field('id,filename').select();
num = len(backups) - int(count)
if num > 0:
for backup in backups:
public.ExecShell("rm -f " + backup['filename']);
sql.table('backup').where('id=?',(backup['id'],)).delete();
num -= 1;
print "|---已清理过期备份文件:" + backup['filename']
if num < 1: break;
def backupDatabase(self,name,count):
sql = db.Sql();
path = sql.table('databases').where('name=?',(name,)).getField('path');
startTime = time.time();
if not path:
endDate = time.strftime('%Y/%m/%d %X',time.localtime())
log = "数据库["+name+"]不存在!"
print "★["+endDate+"] "+log
print "----------------------------------------------------------------------------"
return;
backup_path = sql.table('config').where("id=?",(1,)).getField('backup_path') + '/database';
if not os.path.exists(backup_path): public.ExecShell("mkdir -p " + backup_path);
filename = backup_path + "/Db_" + name + "_" + time.strftime('%Y%m%d_%H%M%S',time.localtime())+".sql.gz"
import re
mysql_root = sql.table('config').where("id=?",(1,)).getField('mysql_root')
mycnf = public.readFile('/etc/my.cnf');
rep = "\\[mysqldump\\]\\nuser=root"
sea = "[mysqldump]\\n"
subStr = sea + "user=root\\npassword=" + mysql_root+"\\n";
mycnf = mycnf.replace(sea,subStr)
if len(mycnf) > 100:
public.writeFile('/etc/my.cnf',mycnf);
public.ExecShell("/www/server/mysql/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X',time.localtime())
log = "数据库["+name+"]备份失败!"
print "★["+endDate+"] "+log
print "----------------------------------------------------------------------------"
return;
mycnf = public.readFile('/etc/my.cnf');
mycnf = mycnf.replace(subStr,sea)
if len(mycnf) > 100:
public.writeFile('/etc/my.cnf',mycnf);
endDate = time.strftime('%Y/%m/%d %X',time.localtime())
outTime = time.time() - startTime
pid = sql.table('databases').where('name=?',(name,)).getField('id');
sql.table('backup').add('type,name,pid,filename,addtime,size',(1,os.path.basename(filename),pid,filename,endDate,os.path.getsize(filename)))
log = "数据库["+name+"]备份成功,用时["+str(round(outTime,2))+"]秒";
public.WriteLog('计划任务',log)
print "★["+endDate+"] " + log
print "|---保留最新的["+count+"]份备份"
print "|---文件名:"+filename
#清理多余备份
backups = sql.table('backup').where('type=? and pid=?',('1',pid)).field('id,filename').select();
num = len(backups) - int(count)
if num > 0:
for backup in backups:
public.ExecShell("rm -f " + backup['filename']);
sql.table('backup').where('id=?',(backup['id'],)).delete();
num -= 1;
print "|---已清理过期备份文件:" + backup['filename']
if num < 1: break;
#连接FTP
def connentFtp(self):
from ftplib import FTP
ftp=FTP()
ftp.set_debuglevel(0)
ftp.connect('192.168.1.245','21')
ftp.login('uptest','admin')
ftp.cwd('test')
bufsize = 1024
return ftp;
#上传文件
def updateFtp(self,filename):
ftp = self.connentFtp();
file_handler = open(filename,'rb')
ftp.storbinary('STOR %s' % os.path.basename(filename),file_handler,bufsize)
ftp.set_debuglevel(0)
file_handler.close()
ftp.quit()
#从FTP删除文件
def deleteFtp(self,filename):
ftp = self.connentFtp();
ftp.delete(filename);
return True;
#获取列表
def getList(self):
ftp = self.connentFtp();
return ftp.nlst();
if __name__ == "__main__":
backup = backupTools()
# python /www/server/panel/script/backup.py site www.pythondaquan.com 3
type = sys.argv[1];
if type == 'site':
backup.backupSite(sys.argv[2], sys.argv[3])
else:
backup.backupDatabase(sys.argv[2], sys.argv[3])作者的其他回答:
[自己拥有一台服务器可以做哪些很酷的事情]、
[阿里云服务器快速建网站 (安装BT宝塔面板和wordpress)]、
阿里云域名注册与备案、服务器ECS购买与登录 、
[七牛图床添加阿里云域名]、
[markdown多平台发布及七牛图床使用]
Demand feedback