问题描述
数据文件更新(修改或者新增)之后,需要拷贝一份到备份机器。
由于文件数量较多,更新的只是一小部分,不能全部scp过去,通过paramiko提供的sftp功能,比较本地与备份机器的文件记录,主要是比较修改时间(modify time,st_mtime)。,传输其中不同的文件。
此外,为了方便对数据库的情况按不同日期进行整理,传输过去的文件保持与本地相同的读写时间(读:acess time,st_atime;写:modify time,st_mtime)。
解决方案
paramiko.SSHClient().open_sftp() 提供了sftp功能,包括:
- 传输文件,put(local_file, remote_file)
- 统计远端文件信息,stat(remote_file),注意这里需要处理远端文件不存在的情况(即本地文件为新增的情况)
- 修改远端文件时间,utime(remote_file, (st_atime, st_mtime))
# use this node as a client, write to a file server to backup a copy
import paramiko
import tqdm
import errno
import os
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
hostname = "xx.xx.xx.xx"
port = "8008"
username = "fake"
password = "123456"
client.connect(hostname, port, username, password, compress=True)
sftp_client = client.open_sftp()
def remote_finfo(sftp, filename, remote_path):
try:
info = sftp.stat(remote_path + filename)
except IOError as e:
if e.errno == errno.ENOENT:
return None
raise
else:
return info
DIR = 'YOUR_LOCAL_DIR_PATH/'
RPATH = 'YOUR_REMOTE_DIR_PATH/'
for filename in tqdm.tqdm(os.listdir(DIR)):
local_file = DIR + filename
remote_file = RPATH + filename
info1 = os.stat(local_file)
info2 = remote_finfo(sftp_client, filename, RPATH)
if info2 is not None:
if info1.st_mtime > info2.st_mtime:
sftp_client.put(local_file, remote_file)
sftp_client.utime(remote_file, (info1.st_atime, info1.st_mtime))
else:
sftp_client.put(local_file, remote_file)
sftp_client.utime(remote_file, (info1.st_atime, info1.st_mtime))