文档章节

postgresql 在流复制模式下,WAL发生以下错误的对处方法

p
 pg_edb
发布于 2017/08/16 09:23
字数 1118
阅读 26
收藏 0

postgresql在流复制模式(stream)时,slave侧log出现以下错误:

record with zero length at XXX

FATAL:terminating walreceiver process due to administrator command

错误

xlog.c            
             
4069            
             
  else if (record->xl_len == 0)      
  {          
    ereport(emode_for_corrupt_record(emode, *RecPtr),
        (errmsg("record with zero length at %X/%X",
            RecPtr->xlogid, RecPtr->xrecoff)));
    goto next_record_is_invalid;    
  }          
             
             
             
next_record_is_invalid:        
  failedSources |= readSource;      
             
  if (readFile >= 0)        
  {          
    close(readFile);      
    readFile = -1;      
  }          
             
  /*          
   * If archive recovery was requested, but we were still doing crash
   * recovery, switch to archive recovery and retry using the offline
   * archive. We have now replayed all the valid WAL in pg_xlog, so
   * we are presumably now consistent.    
   *          
   * We require that there's at least some valid WAL present in
   * pg_xlog, however (!fetch_ckpt). We could recover using the WAL
   * from the archive, even if pg_xlog is completely empty, but we'd
   * have no idea how far we'd have to replay to reach consistency.
   * So err on the safe side and give up.    
   */          
  if (!InArchiveRecovery && ArchiveRecoveryRequested && !fetching_ckpt)
  {          
    ereport(DEBUG1,      
        (errmsg_internal("reached end of WAL in pg_xlog, entering archive recovery")));
    InArchiveRecovery = true;    
    if (StandbyModeRequested)    
      StandbyMode = true;  
             
    /* initialize minRecoveryPoint to this record */
    LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
    ControlFile->state = DB_IN_ARCHIVE_RECOVERY;
    if (XLByteLT(ControlFile->minRecoveryPoint, EndRecPtr))
      ControlFile->minRecoveryPoint = EndRecPtr;
             
    /* update local copy */    
    minRecoveryPoint = ControlFile->minRecoveryPoint;
             
    UpdateControlFile();    
    LWLockRelease(ControlFileLock);  
             
    CheckRecoveryConsistency();    
             
    goto retry;      
  }          
             
             
  retry:          
  /* See if we need to retrieve more data */  
  if (readFile < 0 ||        
    (readSource == XLOG_FROM_STREAM && !XLByteLT(*RecPtr, receivedUpto)))
  {          
    if (StandbyMode)      
    {        
      /*      
       * In standby mode, wait for the requested record to become
       * available, either via restore_command succeeding to restore the
       * segment, or via walreceiver having streamed the record.
       */      
      for (;;)      
      {      
        if (WalRcvInProgress())
        {    
          bool  
             
          /*  
           * If we find an invalid record in the WAL streamed from
           * master, something is seriously wrong. There's little
           * chance that the problem will just go away, but PANIC is
           * not good for availability either, especially in hot
           * standby mode. Disconnect, and retry from
           * archive/pg_xlog again. The WAL in the archive should be
           * identical to what was streamed, so it's unlikely that
           * it helps, but one can hope...
           */  
          if (failedSources & XLOG_FROM_STREAM)
          {  
            ShutdownWalRcv();
            continue;
          }  
             
          /*  
           * Walreceiver is active, so see if new data has arrived.
           *  
           * We only advance XLogReceiptTime when we obtain fresh
           * WAL from walreceiver and observe that we had already
           * processed everything before the most recent "chunk"
           * that it flushed to disk.  In steady state where we are
           * keeping up with the incoming data, XLogReceiptTime will
           * be updated on each cycle.  When we are behind,
           * XLogReceiptTime will not advance, so the grace time
           * alloted to conflicting queries will decrease.
           */  
          if (XLByteLT(*RecPtr, receivedUpto))
            havedata = true;
          else  
          {  
            XLogRecPtr
             
            receivedUpto = GetWalRcvWriteRecPtr(&latestChunkStart);
            if (XLByteLT(*RecPtr, receivedUpto))
            {
             
             
             
             
             
             
            }
            else
             
          }  
          if (havedata)
          {  
            /*
             * Great, streamed far enough. Open the file if it's
             * not open already.  Use XLOG_FROM_STREAM so that
             * source info is set correctly and XLogReceiptTime
             * isn't changed.
             */
            if (readFile < 0)
            {
             
             
             
             
             
             
            }
            else
            {
             
             
             
            }
            break;
          }  
             
          /*  
           * Data not here yet, so check for trigger then sleep for
           * five seconds like in the WAL file polling case below.
           */  
          if (CheckForStandbyTrigger())
            goto retry;
             
          /*  
           * Wait for more WAL to arrive, or timeout to be reached
           */  
          WaitLatch(&XLogCtl->recoveryWakeupLatch,
             
             
          ResetLatch(&XLogCtl->recoveryWakeupLatch);
        }    
        else    
        {    
          int  
          pg_time_t now;
             
          /*  
           * Until walreceiver manages to reconnect, poll the
           * archive.
           */  
          if (readFile >= 0)
          {  
            close(readFile);
            readFile = -1;
          }  
          /* Reset curFileTLI if random fetch. */
          if (randAccess)
            curFileTLI = 0;
             
          /*  
           * Try to restore the file from archive, or read an
           * existing file from pg_xlog.
           */  
          sources = XLOG_FROM_ARCHIVE | XLOG_FROM_PG_XLOG;
          if (!(sources & ~failedSources))
          {  
            /*
             * We've exhausted all options for retrieving the
             * file. Retry.
             */
            failedSources = 0;
             
            /*
             * Before we sleep, re-scan for possible new timelines
             * if we were requested to recover to the latest
             * timeline.
             */
            if (recoveryTargetIsLatest)
            {
             
             
            }
             
            /*
             * If it hasn't been long since last attempt, sleep to
             * avoid busy-waiting.
             */
            now = (pg_time_t) time(NULL);
            if ((now - last_fail_time) < 5)
            {
             
             
            }
            last_fail_time = now;
             
            /*
             * If primary_conninfo is set, launch walreceiver to
             * try to stream the missing WAL, before retrying to
             * restore from archive/pg_xlog.
             *
             * If fetching_ckpt is TRUE, RecPtr points to the
             * initial checkpoint location. In that case, we use
             * RedoStartLSN as the streaming start position
             * instead of RecPtr, so that when we later jump
             * backwards to start redo at RedoStartLSN, we will
             * have the logs streamed already.
             */
            if (PrimaryConnInfo)
            {
             
             
             
             
            }
          }  
          /* Don't try to read from a source that just failed */
          sources &= ~failedSources;
          readFile = XLogFileReadAnyTLI(readId, readSeg, DEBUG2,
             
          switched_segment = true;
          if (readFile >= 0)
            break;
             
          /*  
           * Nope, not found in archive and/or pg_xlog.
           */  
          failedSources |= sources;
             
          /*  
           * Check to see if the trigger file exists. Note that we
           * do this only after failure, so when you create the
           * trigger file, we still finish replaying as much as we
           * can from archive and pg_xlog before failover.
           */  
          if (CheckForStandbyTrigger())
            goto triggered;
        }    
             
        /*    
         * This possibly-long loop needs to handle interrupts of
         * startup process.  
         */    
        HandleStartupProcInterrupts();
      }      
    }        
    else        
    {        
      /* In archive or crash recovery. */
      if (readFile < 0)    
      {      
        int    
             
        /* Reset curFileTLI if random fetch. */
        if (randAccess)  
          curFileTLI = 0;
             
        sources = XLOG_FROM_PG_XLOG;
        if (InArchiveRecovery)
          sources |= XLOG_FROM_ARCHIVE;
             
        readFile = XLogFileReadAnyTLI(readId, readSeg, emode,
             
        switched_segment = true;
        if (readFile < 0)  
          return false;
      }      
    }        
  }          
             
  /*          
   * At this point, we have the right segment open and if we're streaming we
   * know the requested record is in it.    
   */          
  Assert(readFile != -1);      
             
  /*          
   * If the current segment is being streamed from master, calculate how
   * much of the current page we have received already. We know the
   * requested record has been received, but this is for the benefit of
   * future calls, to allow quick exit at the top of this function.
   */          
  if (readSource == XLOG_FROM_STREAM)    
  {          
    if (RecPtr->xlogid != receivedUpto.xlogid ||
      (RecPtr->xrecoff / XLOG_BLCKSZ) != (receivedUpto.xrecoff / XLOG_BLCKSZ))
    {        
      readLen = XLOG_BLCKSZ;  
    }        
    else        
      readLen = receivedUpto.xrecoff % XLogSegSize - targetPageOff;
  }          
  else          
    readLen = XLOG_BLCKSZ;    
             
  if (switched_segment && targetPageOff != 0)  
  {          
    /*        
     * Whenever switching to a new WAL segment, we read the first page of
     * the file and validate its header, even if that's not where the
     * target record is.  This is so that we can check the additional
     * identification info that is present in the first page's "long"
     * header.      
     */        
    readOff = 0;      
    if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
    {        
      ereport(emode_for_corrupt_record(emode, *RecPtr),
          (errcode_for_file_access(),
           errmsg("could not read from log file %u, segment %u, offset %u: %m",
             
      goto next_record_is_invalid;  
    }        
    if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode, true))
      goto next_record_is_invalid;  
  }          
             
  /* Read the requested page */      
  readOff = targetPageOff;      
  if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0)  
  {          
    ereport(emode_for_corrupt_record(emode, *RecPtr),
        (errcode_for_file_access(),
     errmsg("could not seek in log file %u, segment %u to offset %u: %m",
        readId, readSeg, readOff)));
    goto next_record_is_invalid;    
  }          
  if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ)
  {          
    ereport(emode_for_corrupt_record(emode, *RecPtr),
        (errcode_for_file_access(),
     errmsg("could not read from log file %u, segment %u, offset %u: %m",
        readId, readSeg, readOff)));
    goto next_record_is_invalid;    
  }          
  if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode, false))
    goto next_record_is_invalid;    
             
  Assert(targetId == readId);      
  Assert(targetSeg == readSeg);      
  Assert(targetPageOff == readOff);    
  Assert(targetRecOff < readLen);    
             
  return true;        
             
next_record_is_invalid:        
  failedSources |= readSource;      
             
  if (readFile >= 0)        
    close(readFile);      
  readFile = -1;        
  readLen = 0;        
  readSource = 0;        
             
  /* In standby-mode, keep trying */    
  if (StandbyMode)        
    goto retry;      
  else          
    return false;      
             
triggered:          
  if (readFile >= 0)        
    close(readFile);      
  readFile = -1;        
  readLen = 0;        
  readSource = 0;        
             
  return false;        
}            
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             
             

© 著作权归作者所有

共有 人打赏支持
p
粉丝 0
博文 6
码字总数 2675
作品 0
杭州
私信 提问
postgres配置主从流复制

http://www.cnblogs.com/yjf512/p/4499547.html postgres主从流复制 postgres在9.0之后引入了主从的流复制机制,所谓流复制,就是从库通过tcp流从主库中同步相应的数据。postgres的主从看过一...

Ch`ing-hua
2015/12/24
2
1
postgresql9.6主从高可用源码环境编译配置详解

系统版本:centos7 8核 32G内存 主从服务器IP: 192.168.125.33 postgreSQL master 192.168.125.34 postgreSQL slave 1、创建数据库管理账户 # groupadd pggroup # useradd -g pggroup pgus......

断臂人
01/06
0
0
PostgreSQL9.x集簇备份pg_basebackup

从postgresql 9版本开始增添了pgbasebackup客户端工具程序,它可以用来备份整个数据库集簇,可以用作流复制的基础备份的一个更方便的方式。 pgbasebackup语法详见:http://www.postgresql.o...

YuanyuanL
2015/08/27
0
0
PostgreSQL 一主多从(多副本,强同步)简明手册 - 配置、压测、监控、切换、防脑裂、修复、0丢失 - 珍藏级

标签 PostgreSQL , 多副本 , 一主多从 , 流复制 背景 PostgreSQL物理流复制有几个特点 1、延迟及低,毫不畏惧大事务 2、支持断点续传 3、支持多副本 4、配置简单,看本文 5、备库与主库物理完...

德哥
2018/04/18
0
0
PostgreSQL DBA快速入门(二) - 高可用流复制配置

PostgreSQL DBA快速入门(二) - 高可用流复制配置 之前的文章中我们谈论了单机PostgreSQL实例的部署,有人可能会说这不是生产级别的配置,因为没有任何高可用机制呀。那么本篇文章,我们来谈谈...

闻术苑
2018/07/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

SQL语句查询

1.1 排序 通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。 格式: SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC; ASC 升序 (默认) DESC 降序 1.查询所有商品信息,...

stars永恒
37分钟前
2
0
IntelliJ IDEA 第一个 Scala 程序

IntelliJ 安装完成 Scala 插件后,你需要尝试使用 IntelliJ 来创建并且运行第一个程序。 通常这个程序只是简单的输出 Hello World。 创建一个新工程 在文件下面选择新建,然后选择创建工程。...

honeymose
41分钟前
2
0
mysql分表,分区的区别和联系

一,什么是mysql分表,分区 什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看mysql分表的3种方法 什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同...

吴伟祥
43分钟前
1
0
csapp 习题 - 如何实现异或 exclusive-or

阅读 csapp v3 时,练习题 2.13 很有意思。练习题描述如下。 位设置是对于参数 mask 中每一个为 1 的位,那么参数 x 中相应位则被设置为 1 ;位清除是对于参数 mask 中每一个为 1 的位,那么...

ylme
昨天
5
0
Amino——产品迭代

兴趣部落产品迭代 时间 版本号 更新内容 备注 2019年1月2日 v3.1.1 支持定制部落首页的内容tab,酋长可以将精华、相册、分类添加到部落首页啦。 支持申请酋长,酋长可以直接推送优质话题,快...

铸剑为犁413
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部