1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2024-11-24 08:52:38 +02:00

Extens page bitmap by doubling its size

This commit is contained in:
Konstantin Knizhnik 2020-09-02 19:28:44 +03:00
parent 46c7dba3bb
commit 9d8b4d8655
5 changed files with 146 additions and 45 deletions

3
.gitignore vendored
View File

@ -34,9 +34,6 @@
# Extra files
/src/pg_crc.c
/src/datapagemap.c
/src/datapagemap.h
/src/logging.h
/src/receivelog.c
/src/receivelog.h
/src/streamutil.c

View File

@ -7,13 +7,13 @@ OBJS = src/utils/configuration.o src/utils/json.o src/utils/logger.o \
OBJS += src/archive.o src/backup.o src/catalog.o src/checkdb.o src/configure.o src/data.o \
src/delete.o src/dir.o src/fetch.o src/help.o src/init.o src/merge.o \
src/parsexlog.o src/ptrack.o src/pg_probackup.o src/restore.o src/show.o src/util.o \
src/validate.o
src/validate.o src/datapagemap.o
# borrowed files
OBJS += src/pg_crc.o src/datapagemap.o src/receivelog.o src/streamutil.o \
OBJS += src/pg_crc.o src/receivelog.o src/streamutil.o \
src/xlogreader.o
EXTRA_CLEAN = src/pg_crc.c src/datapagemap.c src/datapagemap.h \
EXTRA_CLEAN = src/pg_crc.c \
src/receivelog.c src/receivelog.h src/streamutil.c src/streamutil.h \
src/xlogreader.c src/instr_time.h
@ -34,9 +34,6 @@ ifneq (,$(wildcard $(srchome)/src/bin/pg_basebackup/walmethods.c))
OBJS += src/walmethods.o
EXTRA_CLEAN += src/walmethods.c src/walmethods.h
endif
ifneq (,$(wildcard $(srchome)/src/bin/pg_rewind/logging.h))
EXTRA_CLEAN += src/logging.h
endif
ifdef USE_PGXS
PG_CONFIG = pg_config
@ -56,16 +53,9 @@ PG_LIBS_INTERNAL = $(libpq_pgport) ${PTHREAD_CFLAGS}
src/utils/configuration.o: src/datapagemap.h
src/archive.o: src/instr_time.h
src/backup.o: src/receivelog.h src/streamutil.h
ifneq (,$(wildcard $(srchome)/src/bin/pg_rewind/logging.h))
src/datapagemap.o: src/logging.h
endif
src/instr_time.h: $(srchome)/src/include/portability/instr_time.h
rm -f $@ && $(LN_S) $(srchome)/src/include/portability/instr_time.h $@
src/datapagemap.c: $(srchome)/src/bin/pg_rewind/datapagemap.c
rm -f $@ && $(LN_S) $(srchome)/src/bin/pg_rewind/datapagemap.c $@
src/datapagemap.h: $(srchome)/src/bin/pg_rewind/datapagemap.h
rm -f $@ && $(LN_S) $(srchome)/src/bin/pg_rewind/datapagemap.h $@
src/pg_crc.c: $(srchome)/src/backend/utils/hash/pg_crc.c
rm -f $@ && $(LN_S) $(srchome)/src/backend/utils/hash/pg_crc.c $@
src/receivelog.c: $(srchome)/src/bin/pg_basebackup/receivelog.c
@ -82,8 +72,6 @@ src/streamutil.h: $(srchome)/src/bin/pg_basebackup/streamutil.h
rm -f $@ && $(LN_S) $(srchome)/src/bin/pg_basebackup/streamutil.h $@
src/xlogreader.c: $(srchome)/src/backend/access/transam/xlogreader.c
rm -f $@ && $(LN_S) $(srchome)/src/backend/access/transam/xlogreader.c $@
src/logging.h: $(srchome)/src/bin/pg_rewind/logging.h
rm -f $@ && $(LN_S) $(srchome)/src/bin/pg_rewind/logging.h $@
src/walmethods.c: $(srchome)/src/bin/pg_basebackup/walmethods.c
rm -f $@ && $(LN_S) $(srchome)/src/bin/pg_basebackup/walmethods.c $@
src/walmethods.h: $(srchome)/src/bin/pg_basebackup/walmethods.h

113
src/datapagemap.c Normal file
View File

@ -0,0 +1,113 @@
/*-------------------------------------------------------------------------
*
* datapagemap.c
* A data structure for keeping track of data pages that have changed.
*
* This is a fairly simple bitmap.
*
* Copyright (c) 2013-2019, PostgreSQL Global Development Group
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "datapagemap.h"
struct datapagemap_iterator
{
datapagemap_t *map;
BlockNumber nextblkno;
};
/*****
* Public functions
*/
/*
* Add a block to the bitmap.
*/
void
datapagemap_add(datapagemap_t *map, BlockNumber blkno)
{
int offset;
int bitno;
int oldsize = map->bitmapsize;
offset = blkno / 8;
bitno = blkno % 8;
/* enlarge or create bitmap if needed */
if (oldsize <= offset)
{
int newsize;
/*
* The minimum to hold the new bit is offset + 1. But add some
* headroom, so that we don't need to repeatedly enlarge the bitmap in
* the common case that blocks are modified in order, from beginning
* of a relation to the end.
*/
newsize = (oldsize == 0) ? 16 : oldsize;
while (newsize <= offset) {
newsize <<= 1;
}
map->bitmap = pg_realloc(map->bitmap, newsize);
/* zero out the newly allocated region */
memset(&map->bitmap[oldsize], 0, newsize - oldsize);
map->bitmapsize = newsize;
}
/* Set the bit */
map->bitmap[offset] |= (1 << bitno);
}
/*
* Start iterating through all entries in the page map.
*
* After datapagemap_iterate, call datapagemap_next to return the entries,
* until it returns false. After you're done, use pg_free() to destroy the
* iterator.
*/
datapagemap_iterator_t *
datapagemap_iterate(datapagemap_t *map)
{
datapagemap_iterator_t *iter;
iter = pg_malloc(sizeof(datapagemap_iterator_t));
iter->map = map;
iter->nextblkno = 0;
return iter;
}
bool
datapagemap_next(datapagemap_iterator_t *iter, BlockNumber *blkno)
{
datapagemap_t *map = iter->map;
for (;;)
{
BlockNumber blk = iter->nextblkno;
int nextoff = blk / 8;
int bitno = blk % 8;
if (nextoff >= map->bitmapsize)
break;
iter->nextblkno++;
if (map->bitmap[nextoff] & (1 << bitno))
{
*blkno = blk;
return true;
}
}
/* no more set bits in this bitmap. */
return false;
}

29
src/datapagemap.h Normal file
View File

@ -0,0 +1,29 @@
/*-------------------------------------------------------------------------
*
* datapagemap.h
*
* Copyright (c) 2013-2019, PostgreSQL Global Development Group
*
*-------------------------------------------------------------------------
*/
#ifndef DATAPAGEMAP_H
#define DATAPAGEMAP_H
#include "storage/relfilenode.h"
#include "storage/block.h"
struct datapagemap
{
char *bitmap;
int bitmapsize;
};
typedef struct datapagemap datapagemap_t;
typedef struct datapagemap_iterator datapagemap_iterator_t;
extern void datapagemap_add(datapagemap_t *map, BlockNumber blkno);
extern datapagemap_iterator_t *datapagemap_iterate(datapagemap_t *map);
extern bool datapagemap_next(datapagemap_iterator_t *iter, BlockNumber *blkno);
#endif /* DATAPAGEMAP_H */

View File

@ -538,33 +538,7 @@ datapagemap_is_set(datapagemap_t *map, BlockNumber blkno)
offset = blkno / 8;
bitno = blkno % 8;
/* enlarge or create bitmap if needed */
if (map->bitmapsize <= offset)
{
int oldsize = map->bitmapsize;
int newsize;
/*
* The minimum to hold the new bit is offset + 1. But add some
* headroom, so that we don't need to repeatedly enlarge the bitmap in
* the common case that blocks are modified in order, from beginning
* of a relation to the end.
*/
newsize = offset + 1;
newsize += 10;
map->bitmap = pg_realloc(map->bitmap, newsize);
/* zero out the newly allocated region */
memset(&map->bitmap[oldsize], 0, newsize - oldsize);
map->bitmapsize = newsize;
}
//datapagemap_print(map);
/* check the bit */
return map->bitmap[offset] & (1 << bitno);
return (map->bitmapsize <= offset) ? false : (map->bitmap[offset] & (1 << bitno)) != 0;
}
/*