文档章节

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

p
 pg_edb
发布于 2017/08/16 09:23
字数 1118
阅读 14
收藏 0
点赞 0
评论 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
博文 5
码字总数 2203
作品 0
杭州
PostgreSQL 一主多从(多副本,强同步)简明手册 - 配置、压测、监控、切换、防脑裂、修复、0丢失 - 珍藏级

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

德哥
04/18
0
0
PostgreSQL9.x集簇备份pg_basebackup

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

YuanyuanL
2015/08/27
0
0
PostgreSql基于Standby的异步流主从复制

一、概述 PostgreSQl从9.0版本之后推出一个类似于Oracle的active dataguard和MySql中继日志一样的日志传送。我们借助这个功能就可实现PostgreSql的主从复制。 基本原理就是,通常一台主数据库...

青苗飞扬
06/26
0
0
postgresql的hot standby(replication stream)

PG在9.*版本后热备提供了新的一个功能,那就是Stream Replication的读写分离,是PG高可用性的一个典型应用,也就是我们传统意义上说的Hot-Standby,比如Oracle的DG,mssql的mirror以及Mysql的...

kenyon_君羊
2012/04/24
0
15
【入门教程】PostgreSQL+SequoiaDB HA 实践

前言 SequoiaDB作为分布式数据库,从设计之初就已经支持SQL访问。目前,SequoiaDB自研的SQL访问组件SequoiaSQL作为企业版的功能之一已经提供给上百家企业用户使用,并且已经实现分布式架构下...

巨杉数据库
2017/10/26
0
0
PostgrSQL流复制wal异常

PostgreSQL的流复制的原理是通过传递主机(master)上的wal日志信息到备机(slave)然后恢复,这中间就有一个潜在的问题,如果主机端比较忙,wal日志被覆盖了,而从机可能因为网络或者其他原因没...

kenyon_君羊
2014/01/26
0
0
PostgreSQL的流复制配置(基于事务日志传送)

自PostgreSQL 9.0开始,添加了流复制(Streaming Repulication)。流复制源于pg早期的“同步日志传送复制”(Synchronous Log Shipping Repulication)--一个高可用的(HA)解决方案。 流复制...

YuanyuanL
2014/09/15
0
0
PostgreSQL的pg_xlog文件数计算和在线清理

postgresql的pgxlog是记录数据库事务信息用的,类似oracle的redo信息,也叫wal日志(write ahead log),就是在写数据到磁盘里成为固定数据之前,先写入到日志里,然后一定条件下触发调用fsync...

kenyon_君羊
2013/07/15
0
0
Postgres中的WAL(三)ControlFileData & CKPT

控制文件在数据库中非常的重要,里面会记录CKPT信息以及数据库的初始化信息。这篇文件主要分享一下控制文件,以及数据库崩溃的情况下如何如何通过控制文件和CKPT来回放WAL。 PG_VERSION:10....

RDBMS原理分析
07/12
0
0
PostgreSQL 11 preview - Allow on-line enabling and disabling of data checksums

标签 PostgreSQL , checksum , online modify , pgverifychecksums , pgenabledatachecksums , pgdisabledatachecksums 背景 PostgreSQL的数据文件是以数据块组织的,由于数据块可能比文件系......

德哥
05/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

about git flow

  昨天元芳做了git分支管理规范的分享,为了拓展大家关于git分支的认知,这里我特意再分享这两个关于git flow的链接,大家可以看一下。 Git 工作流程 Git分支管理策略   git flow本质上是...

qwfys
今天
2
0
Linux系统日志文件

/var/log/messages linux系统总日志 /etc/logrotate.conf 日志切割配置文件 参考https://my.oschina.net/u/2000675/blog/908189 dmesg命令 dmesg’命令显示linux内核的环形缓冲区信息,我们可...

chencheng-linux
今天
1
0
MacOS下给树莓派安装Raspbian系统

下载镜像 前往 树莓派官网 下载镜像。 点击 最新版Raspbian 下载最新版镜像。 下载后请,通过 访达 双击解压,或通过 unzip 命令解压。 检查下载的文件 ls -lh -rw-r--r-- 1 dingdayu s...

dingdayu
今天
1
0
spring boot使用通用mapper(tk.mapper) ,id自增和回显等问题

最近项目使用到tk.mapper设置id自增,数据库是mysql。在使用通用mapper主键生成过程中有一些问题,在总结一下。 1、UUID生成方式-字符串主键 在主键上增加注解 @Id @GeneratedValue...

北岩
今天
2
0
告警系统邮件引擎、运行告警系统

告警系统邮件引擎 cd mail vim mail.py #!/usr/bin/env python#-*- coding: UTF-8 -*-import os,sysreload(sys)sys.setdefaultencoding('utf8')import getoptimport smtplibfr......

Zhouliang6
今天
1
0
Java工具类—随机数

Java中常用的生成随机数有Math.random()方法及java.util.Random类.但他们生成的随机数都是伪随机的. Math.radom()方法 在jdk1.8的Math类中可以看到,Math.random()方法实际上就是调用Random类...

PrivateO2
今天
2
0
关于java内存模型、并发编程的好文

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在...

DannyCoder
昨天
1
0
dubbo @Reference retries 重试次数 一个坑

在代码一中设置 成retries=0,也就是调用超时不用重试,结果DEBUG的时候总是重试,不是0吗,0就不用重试啊。为什么还是调用了多次呢? 结果在网上看到 这篇文章才明白 https://www.cnblogs....

奋斗的小牛
昨天
2
0
数据结构与算法3

要抓紧喽~~~~~~~放羊的孩纸回来喽 LowArray类和LowArrayApp类 程序将一个普通的Java数组封装在LowArray类中。类中的数组隐藏了起来,它是私有的,所以只有类自己的方法才能访问他。 LowArray...

沉迷于编程的小菜菜
昨天
1
0
spring boot应用测试框架介绍

一、spring boot应用测试存在的问题 官方提供的测试框架spring-boot-test-starter,虽然提供了很多功能(junit、spring test、assertj、hamcrest、mockito、jsonassert、jsonpath),但是在数...

yangjianzhou
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部