【问题标题】:What is the correct way to backup ZODB blobs?备份 ZODB blob 的正确方法是什么?
【发布时间】:2011-03-11 00:54:01
【问题描述】:

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

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

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

【问题讨论】:

    标签: python plone zope zodb blobstorage


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      备份“blobstorage”即可。无需特殊订单或其他任何东西,非常简单。

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

      【讨论】:

      • 在备份 Data.fs 之前备份我的 blobstorage 目录是否可行,并且在我开始备份 Data.fs 时已添加或更新了另一个 blob?如果我在备份时打包数据库会怎样?
      • 这个答案不正确——joeforker 提出的担忧是有效的。有关推荐的方法,请参阅我的单独答案。
      【解决方案3】:

      我有一个脚本,它使用硬链接将 blob 复制一个月(因此您将 blob 的历史记录为 Data.fs):

      备份.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)
      

      【讨论】:

      • 请注意,我最近启动了collective.recipe.backup 的一个分支来备份blobstorage。尚未完成,但应该可以在非生产数据库上进行测试。
      【解决方案4】:

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

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

      • 在制作文件系统副本时使数据库脱机
      • 使用 LVM 等快照工具在给定点冻结磁盘
      • 进行事务性导出(在实践中不可行)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-18
        • 1970-01-01
        • 2019-04-23
        • 1970-01-01
        • 2021-05-28
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多