예제 #1
0
 def get_history(self, timeline):
     history_path = 'pg_{0}/{1:08X}.history'.format(self.wal_name, timeline)
     try:
         cursor = self._connection.cursor()
         cursor.execute('SELECT isdir, modification FROM pg_catalog.pg_stat_file(%s)', (history_path,))
         isdir, modification = cursor.fetchone()
         if not isdir:
             cursor.execute('SELECT pg_catalog.pg_read_file(%s)', (history_path,))
             history = list(parse_history(cursor.fetchone()[0]))
             if history[-1][0] == timeline - 1:
                 history[-1].append(modification.isoformat())
             return history
     except Exception:
         logger.exception('Failed to read and parse %s', (history_path,))
예제 #2
0
 def get_history(self, timeline):
     history_path = os.path.join(self.wal_dir, '{0:08X}.history'.format(timeline))
     history_mtime = mtime(history_path)
     if history_mtime:
         try:
             with open(history_path, 'r') as f:
                 history = f.read()
             history = list(parse_history(history))
             if history[-1][0] == timeline - 1:
                 history_mtime = datetime.fromtimestamp(history_mtime).replace(tzinfo=tz.tzlocal())
                 history[-1].append(history_mtime.isoformat())
             return history
         except Exception:
             logger.exception('Failed to read and parse %s', (history_path,))
예제 #3
0
파일: rewind.py 프로젝트: xu001186/patroni
    def _check_timeline_and_lsn(self, leader):
        local_timeline, local_lsn = self._get_local_timeline_lsn()
        if local_timeline is None or local_lsn is None:
            return

        if isinstance(leader, Leader):
            if leader.member.data.get('role') != 'master':
                return
        # standby cluster
        elif not self.check_leader_is_not_in_recovery(
                **leader.conn_kwargs(self._postgresql.config.replication)):
            return

        history = need_rewind = None
        try:
            with self._postgresql.get_replication_connection_cursor(
                    **leader.conn_kwargs()) as cur:
                cur.execute('IDENTIFY_SYSTEM')
                master_timeline = cur.fetchone()[1]
                logger.info('master_timeline=%s', master_timeline)
                if local_timeline > master_timeline:  # Not always supported by pg_rewind
                    need_rewind = True
                elif master_timeline > 1:
                    cur.execute('TIMELINE_HISTORY %s', (master_timeline, ))
                    history = bytes(cur.fetchone()[1]).decode('utf-8')
                    logger.info('master: history=%s', history)
                else:  # local_timeline == master_timeline == 1
                    need_rewind = False
        except Exception:
            return logger.exception(
                'Exception when working with master via replication connection'
            )

        if history is not None:
            for parent_timeline, switchpoint, _ in parse_history(history):
                if parent_timeline == local_timeline:
                    try:
                        need_rewind = parse_lsn(local_lsn) >= switchpoint
                    except (IndexError, ValueError):
                        logger.exception('Exception when parsing lsn')
                    break
                elif parent_timeline > local_timeline:
                    break

        self._state = need_rewind and REWIND_STATUS.NEED or REWIND_STATUS.NOT_NEED