前言
最近开了个 mc 服务器,为了提高数据的安全性,使用 python 写了个简单的备份脚本
备份存档数据 (包含三个世界的数据)
代码如下:
# -*- coding: utf-8 -*-
import os
import zipfile
import datetime
import logging
# 设置备份目录和备份文件名
backup_dir = "/home/minecraft/backups"
server_path = "/root/mc"
# 配置日志输出
logging.basicConfig(filename=os.path.join(backup_dir, "backup.log"), level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s')
def backup_minecraft_server():
try:
# 切换到服务器目录
os.chdir(server_path)
# 备份world世界
world_backup_file = "world_{}.zip".format(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
with zipfile.ZipFile(os.path.join(backup_dir, world_backup_file), "w", zipfile.ZIP_DEFLATED) as archive:
for root, dirs, files in os.walk("world"):
for file in files:
archive.write(os.path.join(root, file))
# 备份world_nether世界
nether_backup_file = "world_nether_{}.zip".format(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
with zipfile.ZipFile(os.path.join(backup_dir, nether_backup_file), "w", zipfile.ZIP_DEFLATED) as archive:
for root, dirs, files in os.walk("world_nether"):
for file in files:
archive.write(os.path.join(root, file))
# 备份world_the_end世界
end_backup_file = "world_the_end_{}.zip".format(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
with zipfile.ZipFile(os.path.join(backup_dir, end_backup_file), "w", zipfile.ZIP_DEFLATED) as archive:
for root, dirs, files in os.walk("world_the_end"):
for file in files:
archive.write(os.path.join(root, file))
# 合并备份文件
merged_backup_file = "minecraft_backup_{}.zip".format(datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
with zipfile.ZipFile(os.path.join(backup_dir, merged_backup_file), "w", zipfile.ZIP_DEFLATED) as archive:
archive.write(os.path.join(backup_dir, world_backup_file), arcname="world.zip")
archive.write(os.path.join(backup_dir, nether_backup_file), arcname="world_nether.zip")
archive.write(os.path.join(backup_dir, end_backup_file), arcname="world_the_end.zip")
# 删除临时备份文件
os.remove(os.path.join(backup_dir, world_backup_file))
os.remove(os.path.join(backup_dir, nether_backup_file))
os.remove(os.path.join(backup_dir, end_backup_file))
# 获取备份目录中的所有备份文件
backup_files = []
for file_name in os.listdir(backup_dir):
file_path = os.path.join(backup_dir, file_name)
if os.path.isfile(file_path):
backup_files.append((file_path, datetime.datetime.fromtimestamp(os.path.getmtime(file_path))))
# 按照备份文件的修改时间进行排序
backup_files.sort(key=lambda x: x[1])
# 删除超过最新7个备份的文件
if len(backup_files) > 7:
for file_path, file_time in backup_files[:-7]:
os.remove(file_path)
except Exception as e:
logging.error(str(e))
if __name__ == "__main__":
backup_minecraft_server()
保留最新的 7 份备份
按照每天备份一次算,其实就等于保留 7 天的备份
备份整个目录 (请保证备份的目录有足够的空间)
# -*- coding: utf-8 -*-
import os
import zipfile
from datetime import datetime
source_path = "/data/server"
backup_path = "/home/backup/mc_backup/server"
max_backup_count = 7 # 最大保留备份文件数量
# 打包zip压缩逻辑
def zip_directory(directory, zip_name):
with zipfile.ZipFile(zip_name, 'w',allowZip64=True) as zipf:
for root, dirs, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
zipf.write(file_path, os.path.relpath(file_path, directory))
# 备份逻辑
def backup_files(source_path, backup_path):
os.chdir(backup_path)
current_time = datetime.now()
times = current_time.strftime('%Y-%m-%d-%H-%M-%S') # 包含秒
zip_name = "mc_server_" + times + ".zip"
zip_directory(source_path, zip_name)
# 删除多余的备份文件
existing_backups = [file for file in os.listdir(backup_path) if file.startswith("mc_server_") and file.endswith(".zip")]
existing_backups.sort(key=lambda x: os.path.getmtime(x), reverse=True)
for i in range(max_backup_count, len(existing_backups)):
os.remove(existing_backups[i])
print(times+"_mc服务器备份完成")
backup_files(source_path, backup_path)
上面的这个比较通用不管是 mc 服务器目录还是其他的都可以备份
我上面这个脚本的使用场景是 pve 虚拟机挂载了宿主机的 raid5 目录备份
添加定时任务
0 3 * * * python /path/to/backup.py
每天凌晨三点备份
后续添加
1.异地备份(OSS 对象存储)
2.查看备份日志
Comments NOTHING