提交 19a0c800 编写于 作者: A Adam Berlin

Error if about to store an invalid segment number.

A user found a scenario where they had stored a -1 for a tuple's
segno. We'd like to be notified of this type of scenario because it
should not exist and we would like to track down the root
cause. Validations that throw errors will help us track the root cause
down.
上级 b84ed373
......@@ -93,6 +93,8 @@ InsertInitialAOCSFileSegInfo(Relation prel, int32 segno, int32 nvp)
Relation segrel;
int16 formatVersion;
ValidateAppendonlySegmentDataBeforeStorage(segno);
/* New segments are always created in the latest format */
formatVersion = AORelationVersion_GetLatest();
......
......@@ -25,6 +25,7 @@
#include "access/aocssegfiles.h"
#include "access/aosegfiles.h"
#include "access/appendonlytid.h"
#include "access/appendonlywriter.h"
#include "catalog/pg_appendonly_fn.h"
#include "catalog/pg_type.h"
#include "catalog/pg_proc.h"
......@@ -80,6 +81,13 @@ NewFileSegInfo(int segno)
return fsinfo;
}
void
ValidateAppendonlySegmentDataBeforeStorage(int segno)
{
if (segno >= MAX_AOREL_CONCURRENCY || segno < 0)
ereport(ERROR, (errmsg("expected segment number to be between zero and the maximum number of concurrent writers, actually %d", segno)));
}
/*
* InsertFileSegInfo
*
......@@ -100,6 +108,8 @@ InsertInitialSegnoEntry(Relation parentrel, int segno)
Datum *values;
int16 formatVersion;
ValidateAppendonlySegmentDataBeforeStorage(segno);
/* New segments are always created in the latest format */
formatVersion = AORelationVersion_GetLatest();
......
......@@ -1517,10 +1517,7 @@ get_awaiting_drop_status_from_segments(Relation parentrel)
value = PQgetvalue(pgresult, j, 1);
segno = pg_atoi(value, sizeof(int32), 0);
if (segno < 0)
elog(ERROR, "segno %d is negative", segno);
if (segno >= MAX_AOREL_CONCURRENCY)
elog(ERROR, "segno %d exceeds max AO concurrency", segno);
ValidateAppendonlySegmentDataBeforeStorage(segno);
if (qe_state == AOSEG_STATE_AWAITING_DROP)
{
......
......@@ -3,7 +3,7 @@ top_builddir=../../../../..
include $(top_builddir)/src/Makefile.global
TARGETS=aomd appendonly_visimap appendonlywriter appendonly_visimap_entry \
aomd_filehandler
aomd_filehandler aosegfiles
include $(top_builddir)/src/backend/mock.mk
......@@ -24,3 +24,4 @@ aomd_filehandler.t: \
appendonly_visimap_entry.t:
aosegfiles.t: $(top_builddir)/src/backend/access/appendonly/aosegfiles.o
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include "postgres.h"
#include "access/aosegfiles.h"
#include "utils/memutils.h"
void
test_validate_segno_returns_false_when_segno_less_than_zero(void **state)
{
bool error_thrown = false;
PG_TRY();
{
ValidateAppendonlySegmentDataBeforeStorage(-1);
}
PG_CATCH();
{
error_thrown = true;
}
PG_END_TRY();
assert_true(error_thrown);
}
void
test_validate_segno_returns_true_when_segno_greater_than_or_equal_to_zero(void **state)
{
bool error_thrown = false;
PG_TRY();
{
ValidateAppendonlySegmentDataBeforeStorage(0);
ValidateAppendonlySegmentDataBeforeStorage(1);
ValidateAppendonlySegmentDataBeforeStorage(10);
ValidateAppendonlySegmentDataBeforeStorage(100);
}
PG_CATCH();
{
error_thrown = true;
}
PG_END_TRY();
assert_false(error_thrown);
}
void
test_validate_segno_throws_error_when_value_is_greater_than_maximum_number_of_concurrent_writers(void **state)
{
bool error_thrown = false;
int some_number_above_aorel_concurrency = 1234;
PG_TRY();
{
ValidateAppendonlySegmentDataBeforeStorage(some_number_above_aorel_concurrency);
}
PG_CATCH();
{
error_thrown = true;
}
PG_END_TRY();
assert_true(error_thrown);
}
int
main(int argc, char* argv[])
{
cmockery_parse_arguments(argc, argv);
MemoryContextInit();
const UnitTest tests[] = {
unit_test(test_validate_segno_returns_false_when_segno_less_than_zero),
unit_test(test_validate_segno_returns_true_when_segno_greater_than_or_equal_to_zero),
unit_test(test_validate_segno_throws_error_when_value_is_greater_than_maximum_number_of_concurrent_writers)
};
return run_tests(tests);
}
......@@ -131,6 +131,8 @@ extern FileSegInfo *NewFileSegInfo(int segno);
extern void InsertInitialSegnoEntry(Relation parentrel, int segno);
extern void ValidateAppendonlySegmentDataBeforeStorage(int segno);
/*
* GetFileSegInfo
*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册