PostgreSQL之精妙的数据库导入导出工具架构 (十二)

(十二)详解逻辑备份---大对象的导出

1 其他的数据导出---大对象的数据

    除了表的数据之外,大对象的真实数据,也被作为数据处理。如上一节中2.4节,同时也列出了大对象数据被导出的方式。
    每个大对象,也占据一个导出对象链表的节点,每个大对象的数据导出,也类似表的数据导出。
    大对象数据的处理,与表的数据不同的之处,在于,大对象需要放到一个事务中处理。所以,其多出两个函数,一个叫startPtr,是开始事务处理的;一个叫endPtr,是结束事务处理的。
    
2 dumpBlobs函数细节
2.1 dumpBlobs函数是要导出大对象的数据。
2.2 类似导出表的数据,导出大对象,采取的同样是“cursor”方式。
2.3 遍历读出的每一大对象,得到其对象ID,即得到每一个大对象的标识,
2.4 然后,打开(调用lo_open函数)这个大对象。
2.5 打开大对象后,调用StartBlob函数,有一个函数指针的使用典范:
       int
      StartBlob(Archive *AHX, Oid oid)
      {
          ArchiveHandle *AH = (ArchiveHandle *) AHX;
      
          if (!AH->StartBlobPtr)
              die_horribly(AH, modulename, "large-object output not supported in chosen format\n");
      
          (*AH->StartBlobPtr) (AH, AH->currToc, oid); //函数指针的使用典范
      
          return 1;
      }

    如果导出格式是二进制,则使用“pg_backup_custom.c”文件中对应的如下函数执行导出:
      static void
      _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid)
      {
          if (oid == 0)
              die_horribly(AH, modulename, "invalid OID for large object\n");
      
          WriteInt(AH, oid);
          _StartDataCompressor(AH, te);
      }       
 
2.6 循环读出本大对象的数据块,直到本大对象的所有数据读完。
2.7 调用EndBlob函数,

3 大对象导出其他关系

3.1 大对象数据导出的整体逻辑关系
    3.1.1 当导出对象链表被导出后,WriteDataChunks被调用,用于导出数据
    3.1.2 当数据是大对象的数据时,WriteDataChunks函数中通过函数指针,调用了“_StartBlobs”函数(以“pg_backup_custom.c”文件中被调用的函数为例)
    3.1.3 之后,又一次通过函数指针,即传给“ArchiveEntry”的倒数第二个参数的“dumpFn”对应的“dumpBlobs”函数,执行导出所有大对象的数据
    3.1.4 在“dumpBlobs”函数中,又一次通过函数指针,调用了“StartBlob->_StartBlob”
    3.1.5 这样,所有大对象的数据就被一次导出了
3.2 大对象导出在备份文件中的位置是如何记载的?
    如果导出格式是二进制,则使用“pg_backup_custom.c”文件中对应的如下函数执行导出:    
      static void
      _StartBlobs(ArchiveHandle *AH, TocEntry *te)
      {
          lclContext *ctx = (lclContext *) AH->formatData;
          lclTocEntry *tctx = (lclTocEntry *) te->formatData;
      
          tctx->dataPos = _getFilePos(AH, ctx);
          tctx->dataState = K_OFFSET_POS_SET;
      
          _WriteByte(AH, BLK_BLOBS);    /* Block type */
          WriteInt(AH, te->dumpId);    /* For sanity check */
      }

    注意,此处调用_getFilePos函数给tctx->dataPos赋值,而tctx是te的formatData,所以,te上会记载导出数据的在导出文件中的位置。而我们曾经在本系列的第二篇“(二)体系结构“中提出”问题二:为什么又写一遍?”,根本原因就和此有关。
    数据对象在导出时,分为两部分,一是“数据对象被抽象后的元信息”、一是“真正的数据”,而数据在导出文件中的位置,被记载到“数据对象被抽象后的元信息”中,但是本位置信息只有在导出数据时,才能得到具体的值(_StartBlobs中即可得到位置信息),所以,记载位置的链表信息,会被重新写出一遍。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值