mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 12:01:42 +01:00
closes[t:2622] when realloc fails in the brtloader writer, mark the dbuf in error and check the error later
git-svn-id: file:///svn/toku/tokudb@20350 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
d6dc7aad45
commit
001f15c2f5
2 changed files with 139 additions and 85 deletions
|
@ -1752,6 +1752,7 @@ struct dbuf {
|
|||
unsigned char *buf;
|
||||
int buflen;
|
||||
int off;
|
||||
int error;
|
||||
};
|
||||
|
||||
struct leaf_buf {
|
||||
|
@ -1832,10 +1833,12 @@ static void seek_align(struct dbout *out) {
|
|||
}
|
||||
|
||||
static void dbuf_init (struct dbuf *dbuf) {
|
||||
dbuf->buf=0;
|
||||
dbuf->buflen=0;
|
||||
dbuf->off=0;
|
||||
dbuf->buf = 0;
|
||||
dbuf->buflen = 0;
|
||||
dbuf->off = 0;
|
||||
dbuf->error = 0;
|
||||
}
|
||||
|
||||
static void dbuf_destroy (struct dbuf *dbuf) {
|
||||
toku_free(dbuf->buf); dbuf->buf = NULL;
|
||||
}
|
||||
|
@ -1852,6 +1855,7 @@ static int64_t allocate_block (struct dbout *out)
|
|||
out->n_translations_limit *= 2;
|
||||
}
|
||||
REALLOC_N(out->n_translations_limit, out->translation);
|
||||
lazy_assert(out->translation);
|
||||
}
|
||||
out->n_translations++;
|
||||
dbout_unlock(out);
|
||||
|
@ -1860,13 +1864,21 @@ static int64_t allocate_block (struct dbout *out)
|
|||
|
||||
static void putbuf_bytes (struct dbuf *dbuf, const void *bytes, int nbytes) {
|
||||
if (dbuf->off + nbytes > dbuf->buflen) {
|
||||
void *oldbuf = dbuf->buf;
|
||||
int oldbuflen = dbuf->buflen;
|
||||
dbuf->buflen += dbuf->off + nbytes;
|
||||
dbuf->buflen *= 2;
|
||||
REALLOC_N(dbuf->buflen, dbuf->buf);
|
||||
lazy_assert(dbuf->buf);
|
||||
if (dbuf->buf == NULL) {
|
||||
dbuf->error = errno;
|
||||
dbuf->buf = oldbuf;
|
||||
dbuf->buflen = oldbuflen;
|
||||
}
|
||||
}
|
||||
if (!dbuf->error) {
|
||||
memcpy(dbuf->buf + dbuf->off, bytes, nbytes);
|
||||
dbuf->off += nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) {
|
||||
|
@ -1876,6 +1888,7 @@ static void putbuf_int8 (struct dbuf *dbuf, unsigned char v) {
|
|||
static void putbuf_int32 (struct dbuf *dbuf, int v) {
|
||||
putbuf_bytes(dbuf, &v, 4);
|
||||
}
|
||||
|
||||
static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) {
|
||||
putbuf_int32(dbuf, v>>32);
|
||||
putbuf_int32(dbuf, v&0xFFFFFFFF);
|
||||
|
@ -1884,13 +1897,21 @@ static void putbuf_int64 (struct dbuf *dbuf, unsigned long long v) {
|
|||
static void putbuf_int32_at(struct dbuf *dbuf, int off, int v) {
|
||||
const int nbytes = 4;
|
||||
if (off+nbytes > dbuf->buflen) {
|
||||
void *oldbuf = dbuf->buf;
|
||||
int oldbuflen = dbuf->buflen;
|
||||
dbuf->buflen += dbuf->off + nbytes;
|
||||
dbuf->buflen *= 2;
|
||||
REALLOC_N(dbuf->buflen, dbuf->buf);
|
||||
lazy_assert(dbuf->buf);
|
||||
if (dbuf->buf == NULL) {
|
||||
dbuf->error = errno;
|
||||
dbuf->buf = oldbuf;
|
||||
dbuf->buflen = oldbuflen;
|
||||
}
|
||||
}
|
||||
if (!dbuf->error)
|
||||
memcpy(dbuf->buf + off, &v, 4);
|
||||
}
|
||||
|
||||
static void putbuf_int64_at(struct dbuf *dbuf, int off, unsigned long long v) {
|
||||
unsigned int a = v>>32;
|
||||
unsigned int b = v&0xFFFFFFFF;
|
||||
|
@ -2428,6 +2449,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int
|
|||
putbuf_bytes(&lbuf->dbuf, key, keylen);
|
||||
putbuf_bytes(&lbuf->dbuf, val, vallen);
|
||||
int le_len = 1+4+4+keylen+vallen;
|
||||
if (!lbuf->dbuf.error) {
|
||||
invariant(le_off + le_len == lbuf->dbuf.off);
|
||||
u_int32_t this_x = x1764_memory(lbuf->dbuf.buf + le_off, le_len);
|
||||
u_int32_t this_prod = lbuf->rand4fingerprint * this_x;
|
||||
|
@ -2438,6 +2460,7 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int
|
|||
printf("%s:%d this_prod=%8x\n", __FILE__, __LINE__, this_prod);
|
||||
printf("%s:%d local_fingerprint=%8x\n", __FILE__, __LINE__, lbuf->local_fingerprint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int write_literal(struct dbout *out, void*data, size_t len) {
|
||||
|
@ -2470,6 +2493,9 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr
|
|||
|
||||
putbuf_int32_at(&lbuf->dbuf, lbuf->n_in_buf_p, lbuf->n_in_buf);
|
||||
|
||||
result = lbuf->dbuf.error;
|
||||
if (result == 0) {
|
||||
|
||||
//print_bytestring(lbuf->dbuf.buf, lbuf->dbuf.off, 200);
|
||||
|
||||
int n_uncompressed_bytes_at_beginning = (8 // tokuleaf
|
||||
|
@ -2541,12 +2567,12 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr
|
|||
seek_align_locked(out);
|
||||
}
|
||||
dbout_unlock(out);
|
||||
|
||||
}
|
||||
|
||||
toku_free(sub_block); // RFP cilk++ bug
|
||||
|
||||
toku_free(compressed_buf);
|
||||
}
|
||||
|
||||
dbuf_destroy(&lbuf->dbuf);
|
||||
toku_free(lbuf);
|
||||
|
||||
|
|
|
@ -81,9 +81,11 @@ static ssize_t bad_pwrite(int fd, const void * bp, size_t len, toku_off_t off) {
|
|||
|
||||
static int my_malloc_event = 0;
|
||||
static int my_malloc_count = 0, my_big_malloc_count = 0;
|
||||
static int my_realloc_count = 0, my_big_realloc_count = 0;
|
||||
|
||||
static void reset_my_malloc_counts(void) {
|
||||
my_malloc_count = my_big_malloc_count = 0;
|
||||
my_realloc_count = my_big_realloc_count = 0;
|
||||
}
|
||||
|
||||
static void *my_malloc(size_t n) {
|
||||
|
@ -109,6 +111,29 @@ static void *my_malloc(size_t n) {
|
|||
return malloc(n);
|
||||
}
|
||||
|
||||
static void *my_realloc(void *p, size_t n) {
|
||||
void *caller = __builtin_return_address(0);
|
||||
if (!((void*)toku_realloc <= caller && caller <= (void*)toku_free))
|
||||
goto skip;
|
||||
my_realloc_count++;
|
||||
if (n >= 64*1024) {
|
||||
my_big_realloc_count++;
|
||||
if (my_malloc_event) {
|
||||
caller = __builtin_return_address(1);
|
||||
if ((void*)toku_xrealloc <= caller && caller <= (void*)toku_malloc_report)
|
||||
goto skip;
|
||||
event_count++;
|
||||
if (event_count == event_count_trigger) {
|
||||
event_hit();
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
skip:
|
||||
return realloc(p, n);
|
||||
}
|
||||
|
||||
static int qsort_compare_ints (const void *a, const void *b) {
|
||||
int avalue = *(int*)a;
|
||||
int bvalue = *(int*)b;
|
||||
|
@ -207,6 +232,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_
|
|||
assert(fd>=0);
|
||||
|
||||
toku_set_func_malloc(my_malloc);
|
||||
toku_set_func_realloc(my_realloc);
|
||||
brtloader_set_os_fwrite(bad_fwrite);
|
||||
toku_set_func_write(bad_write);
|
||||
toku_set_func_pwrite(bad_pwrite);
|
||||
|
@ -217,6 +243,7 @@ static void write_dbfile (char *template, int n, char *output_name, BOOL expect_
|
|||
assert(expect_error ? r != 0 : r == 0);
|
||||
|
||||
toku_set_func_malloc(NULL);
|
||||
toku_set_func_realloc(NULL);
|
||||
brtloader_set_os_fwrite(NULL);
|
||||
toku_set_func_write(NULL);
|
||||
toku_set_func_pwrite(NULL);
|
||||
|
@ -289,6 +316,7 @@ int test_main (int argc, const char *argv[]) {
|
|||
write_dbfile(template, n, output_name, FALSE);
|
||||
|
||||
if (verbose) printf("my_malloc_count=%d big_count=%d\n", my_malloc_count, my_big_malloc_count);
|
||||
if (verbose) printf("my_realloc_count=%d big_count=%d\n", my_realloc_count, my_big_realloc_count);
|
||||
|
||||
int event_limit = event_count;
|
||||
if (verbose) printf("event_limit=%d\n", event_limit);
|
||||
|
|
Loading…
Add table
Reference in a new issue