备份ZODB blob的正确方法是什么?

时间:2009-01-16 20:51:02

标签: python plone zope zodb blobstorage

我正在使用plone.app.blob将大型ZODB对象存储在blobstorage目录中。这减少了Data.fs上的大小压力,但我无法找到有关备份此数据的任何建议。

我已经通过将网络备份工具指向repozo备份目录来备份Data.fs。我应该简单地将该工具指向blobstorage目录来备份我的blob吗?

如果正在重新打包数据库或在复制过程中添加和删除blob,该怎么办? blobstorage目录中是否有必须按特定顺序复制的文件?

4 个答案:

答案 0 :(得分:12)

对数据进行repozo备份然后执行blobstorage目录的rsync应该是安全的,只要数据库在这两个操作发生时没有被打包。

这是因为,至少在使用带有FileStorage的blob时,对blob的修改总是会导致创建一个基于对象id和事务id命名的新文件。因此,如果在备份Data.fs之后写入新的或更新的blob,则它应该不是问题,因为Data.fs引用的文件应该仍然存在。在数据库打包之前删除blob不会导致文件被删除,所以也应该没问题。

以不同的顺序执行备份,或者在备份期间执行打包,可能会导致备份Data.fs引用未包含在备份中的blob。

答案 1 :(得分:2)

备份“blobstorage”就可以了。不需要特殊订单或其他任何东西,这很简单。

Plone中的所有操作都是完全事务性的,因此在事务中间点击备份应该可以正常工作。这就是您可以对ZODB进行实时备份的原因。在不知道你所使用的文件系统的情况下,我猜它应该按预期工作。

答案 2 :(得分:2)

我有一个脚本,使用硬链接复制一个月的blob(所以你有blob的历史记录作为Data.fs):

backup.sh

#!/bin/sh

# per a fer un full : ./cron_nocturn.sh full

ZEO_FOLDER=/var/plone/ZEO

# Zeo port
ZEO_PORT = 8023

# Name of the DB
ZEO_DB = zodb1

BACKUP_FOLDER=/backup/plone

LOGBACKUP=/var/plone/ZEO/backup.log

BACKUPDIR=`date +%d`

echo "INICI BACKUP" >> $LOGBACKUP
echo `date` >> $LOGBACKUP

# Fem el packing

if [ "$1" = "full" ]; then
  $ZEO_FOLDER/bin/zeopack -S $ZEO_DB -p $ZEO_PORT -h 127.0.0.1


echo "   Comprovant folders"
#mirem si existeix el folder de backup
if ! [ -x $BACKUP_FOLDER/$ZEO_DB ]; then
   mkdir $BACKUP_FOLDER/$ZEO_DB
fi

#mirem si existeix el backup folder del dia
if ! [ -x $BACKUP_FOLDER/blobs/$BACKUPDIR/ ] ; then
   mkdir $BACKUP_FOLDER/blobs/$BACKUPDIR/
fi

echo "   Backup Data.fs"
# backup de Data.fs
if  [ "$1" = "full" ]; then
   echo "   Copiant Data.fs"
   $ZEO_FOLDER/bin/repozo -B -F -r $BACKUP_FOLDER/$ZEO_DB/ -f $ZEO_FOLDER/var/filestorage/Data_$ZEO_DB.fs
   echo "   Purgant backups antics"
   $ZEO_FOLDER/neteja.py -l $BACKUP_FOLDER/$ZEO_DB -k 2
else
   $ZEO_FOLDER/bin/repozo -B -r $BACKUP_FOLDER/$ZEO_DB/ -f $ZEO_FOLDER/var/filestorage/Data_$ZEO_DB.fs
fi

echo "   Copiant blobs"
# backup blobs
rm -rf $BACKUP_FOLDER/blobs/$BACKUPDIR
cd $BACKUP_FOLDER/current-blobs && find . -print | cpio -dplm $BACKUP_FOLDER/blobs/$BACKUPDIR
rsync --force --ignore-errors --delete --update -a $ZEO_FOLDER/var/blobs/ $BACKUP_FOLDER/current-blobs/


echo "FI BACKUP" >> $LOGBACKUP
echo `date` >> $LOGBACKUP

neteja.py

#!/usr/bin/python2.4

# neteja.py -l [directori_desti] -k [numero_fulls_a_mantenir]
# Script que neteja un directori amb backups i guarda nomes els ultims fulls que li especifiquis
# Es basa en la utilitzacio de collective.recipe.backup
# Author: Victor Fernandez de Alba <sneridagh@gmail.com>

import sys, getopt

sys.path[0:0] = [
  '/var/plone/genwebupcZEO/produccio/eggs/collective.recipe.backup-1.3-py2.4.egg',
  '/var/plone/genwebupcZEO/produccio/eggs/zc.buildout-1.4.2-py2.4.egg',
  '/var/plone/genwebupcZEO/produccio/eggs/zc.recipe.egg-1.2.2-py2.4.egg',
  '/var/plone/genwebupcZEO/produccio/eggs/setuptools-0.6c11-py2.4.egg',
  ]

import collective.recipe.backup.repozorunner

argv = sys.argv[1:]
try:
    opts, args = getopt.getopt(argv, "l:k:", ["location=", "keep="])
except getopt.GetoptError:
    print "neteja.py -l [directori_desti] -k [numero_fulls_a_mantenir]"
    sys.exit(2)

for opt, arg in opts:
    if opt in ("-l", "--location"):
        location = arg
    elif opt in ("-k", "--keep"):
        keep = arg

if len(opts)<2:
    print "neteja.py -l [directori_desti] -k [numero_fulls_a_mantenir]"
    sys.exit(2)

collective.recipe.backup.repozorunner.cleanup(location, keep)

答案 3 :(得分:1)

您对FileStorage的备份策略很好。但是,备份任何将数据存储在多个文件中的数据库都不容易,因为您的副本必须在不写入各种文件的情况下发生。对于FileStorage,盲目的愚蠢副本很好,因为它只是一个文件。 (使用repozo甚至更好。)

在这种情况下(BlobStorage与FileStorage结合使用)我必须指向常规备份建议:

  • 在进行文件系统复制时使数据库脱机
  • 使用LVM等快照工具冻结指定点的磁盘
  • 进行交易出口(在实践中不可行)