一个php写的linux下lvm自动快照实现脚本
==========crontab配置===============
#vi /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
*/1 * * * * root /usr/bin/php /opt/openfiler/var/etc/snp_script.php >> /root/rec.ini
蓝色字体标注标识要添加的部分。
在每一行的开头有五个“*”号,分别表示分、时、日、月、星期。“*/1”表示每分钟执行一次。
所有路径必须为绝对路径。
===============php部分===================
#!/usr/bin/php <?php date_default_timezone_set( 'PRC' ); $snp_date_rec = date ( "Y-m-d-H-i" ); $now = explode ( "-" , $snp_date_rec ); $snapshots_path = "/opt/openfiler/var/www/htdocs/ipshot/etc/snapshots.xml" ; $schedules_path = "/opt/openfiler/var/www/htdocs/ipshot/etc/schedules.xml" ; //print_r($now); //=======DOM读取snapshot========= $snp_xml = new DOMDocument( '1.0' ); $snp_xml ->load( $snapshots_path ); $snp_XMLDoc = $snp_xml ->getElementsByTagName( "snapshots" )->item(0); $snp_date = date ( "Y-m-d H:i:s" ); $xml = new DOMDocument( '1.0' ); $xml ->load( $schedules_path ); $XMLDoc = $xml ->getElementsByTagName( "schedules" )->item(0); $isLast =false; //========DOM读取XML======== $schedules = array (); $cou =0; foreach ( $XMLDoc ->getElementsByTagName( "schedule" ) as $schedule ){ $sch = array (); $sch [ "name" ]= $schedule ->getAttribute( "name" ); $sch [ "interval" ]= $schedule ->getAttribute( "interval" ); $sch [ "count" ]= $schedule ->getAttribute( "count" ); $sch [ "size" ]= $schedule ->getAttribute( "size" ); $cou1 =0; $sch_volumes = array (); foreach ( $schedule ->getElementsByTagName( "volume" ) as $sch_volume ){ $last = $sch_volume ->getAttribute( "last" ); if ( empty ( $last )|| $last == "" ){ global $isLast ; $last = $sch_volume ->getAttribute( "time" ); $attr = $xml ->createAttribute( "last" ); $attr ->appendChild( $xml ->createTextNode( $last )); $sch_volume ->appendChild( $attr ); $isLast =true; $xml ->save( $schedules_path ); } $sch_volumes [ $cou1 ++]= array ( $sch_volume ->nodeValue, $last , $sch_volume ->getAttribute( "vg" )); } $sch [ "volumes" ]= $sch_volumes ; $schedules [ $cou ++]= $sch ; } foreach ( $schedules as $schedule ){ $interval = explode ( " " , $schedule [ "interval" ]); //print_r($interval); switch ( $interval [1]){ case "min" : $in =4; break ; case "hour" : $in =3; break ; case "day" : $in =2; break ; case "month" ; $in =1; break ; case "year" : $in =0; break ; case "week" ; $in =-1; break ; } print ( "Last:" .( $isLast ? "yes" : "no" ). "\n" ); foreach ( $schedule [ "volumes" ] as $volume ){ $start_time = explode ( "-" , $volume [1]); if ( $in ==-1){ if ( $isLast ||( $now [ $in ]- $start_time [ $in ]!=0&&( $now [2]- $start_time [2])%(7* $interval [0])==0)){ shell_exec( "/sbin/lvcreate -s -L " . $schedule [ "size" ]. " -n of.snapshot." . $volume [0]. ".autosn" . $snp_date_rec . " " . $volume [2]); } } else if ( $isLast ||( $now [ $in ]- $start_time [ $in ]!=0&&( $now [ $in ]- $start_time [ $in ])% $interval [0]==0)){ //print("\n".$interval[0].":\n"); $command = "/sbin/lvcreate -s -L " . $schedule [ "size" ]. " -n of.snapshot." . $volume [0]. ".autosn" . $snp_date_rec . " /dev/" . $volume [2]. "/" . $volume [0]; print $command ; $xpath = new DOMXPath( $xml ); $query = "/schedules/user/schedule[@name='" . $schedule [ "name" ]. "']/volume[@vg='" . $volume [2]. "' and text()='" . $volume [0]. "']" ; $node = $xpath ->query( $query )->item(0); $node ->setAttribute( "last" , $snp_date_rec ); $xml ->save( $schedules_path ); shell_exec( $command ); $snp = $snp_xml ->createElement( "snapshot" ); //print $snp_xml->saveXML(); $attr = $snp_xml ->createAttribute( "id" ); $attr ->appendChild( $snp_xml ->createTextNode( "autosn" . $snp_date_rec )); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "lvname" ); $attr ->appendChild( $snp_xml ->createTextNode( $volume [0])); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "vgname" ); $attr ->appendChild( $snp_xml ->createTextNode( $volume [2])); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "share" ); $attr ->appendChild( $snp_xml ->createTextNode( "no" )); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "rotateid" ); $attr ->appendChild( $snp_xml ->createTextNode( "100" )); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "timestamp" ); $attr ->appendChild( $snp_xml ->createTextNode( $snp_date )); $snp ->appendChild( $attr ); $attr = $snp_xml ->createAttribute( "size" ); $attr ->appendChild( $snp_xml ->createTextNode( $schedule [ "size" ])); $snp ->appendChild( $attr ); $snp_XMLDoc ->appendChild( $snp ); print $snp_xml ->saveXML(); } //删除过期快照 $count =0; foreach ( $snp_XMLDoc ->getElementsByTagName( "snapshot" ) as $snapshot ){ if ( $volume [0]== $snapshot ->getAttribute( "lvname" )&& $snapshot ->getAttribute( "rotateid" )==100){ $count ++; } } //print "\n\n".$count.": ".$schedule["count"]; if ( $count > $schedule [ "count" ]){ foreach ( $snp_XMLDoc ->getElementsByTagName( "snapshot" ) as $snapshot ){ $snpname = $snapshot ->getAttribute( "id" ); $lvname = $snapshot ->getAttribute( "lvname" ); if ( $volume [0]== $lvname && $snapshot ->getAttribute( "rotateid" )==100){ $command = "/sbin/lvremove -f /dev/" . $volume [2]. "/of.snapshot." . $volume [0]. "." . $snpname ; print "\n" . $command . "\n" ; shell_exec( $command ); $snp_XMLDoc ->removeChild( $snapshot ); break ; } } } } } $snp_xml ->save( $snapshots_path ); print ( "\n====================================== \n" ); ?> |
==========XML部分============
snapshot.xml:
<?xml version="1.0"?>
<snapshots>
<snapshot id="autosn2010-11-09-01-17" lvname="mir1" vgname="ipshot-pool" share="no" rotateid="100" timestamp="2010-11-09 01:17:02 GMT"/>
</snapshots>
schedules.xml:
<?xml version="1.0"?>
<schedules>
<schedule name="test1" interval="1 min" count="4" size="10M">
<volume time="2010-11-08-11-35" vg="ipshot-pool">mir1</volume>
</schedule>
</schedules>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)