Commit 39b235fa authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

merge -c 18380 from 3.0.5 to main refs[t:2436]

git-svn-id: file:///svn/toku/tokudb@18382 c7de825b-a66e-492c-adef-691d508d4ae1
parent c5dbc72b
......@@ -8,20 +8,17 @@
#include <string.h>
#include <time.h>
static uint64_t get_tnow(void) {
struct timeval tv;
int r = gettimeofday(&tv, NULL); assert(r == 0);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
}
#define DO_ASSERT_ON_ENOSPC 1
static int toku_assert_on_write_enospc = 0;
static const int toku_write_enospc_sleep = 1;
static uint64_t toku_write_enospc_last_report;
static uint64_t toku_write_enospc_last_time;
static uint32_t toku_write_enospc_current;
static uint64_t toku_write_enospc_total;
void toku_set_assert_on_write_enospc(int do_assert) {
toku_assert_on_write_enospc = do_assert;
}
void
toku_fs_get_write_info(uint64_t *enospc_last_time, uint64_t *enospc_current, uint64_t *enospc_total) {
*enospc_last_time = toku_write_enospc_last_time;
......@@ -48,46 +45,45 @@ try_again_after_handling_write_error(int fd, size_t len, ssize_t r_write) {
break;
}
case ENOSPC: {
#if DO_ASSERT_ON_ENOSPC
toku_write_enospc_last_report = get_tnow();
char err_msg[sizeof("Failed write of [] bytes to fd=[].") + 20+10]; //64 bit is 20 chars, 32 bit is 10 chars
snprintf(err_msg, sizeof(err_msg), "Failed write of [%"PRIu64"] bytes to fd=[%d].", (uint64_t)len, fd);
perror(err_msg);
fflush(stderr);
int out_of_disk_space = 1;
assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives.
#else
toku_sync_fetch_and_increment_uint64(&toku_write_enospc_total);
toku_sync_fetch_and_increment_uint32(&toku_write_enospc_current);
uint64_t tnow = get_tnow();
toku_write_enospc_last_time = tnow;
if (toku_write_enospc_last_report == 0 || tnow - toku_write_enospc_last_report >= 60*1000000) {
toku_write_enospc_last_report = tnow;
const int tstr_length = 26;
char tstr[tstr_length];
time_t t = time(0);
ctime_r(&t, tstr);
const int MY_MAX_PATH = 256;
char fname[MY_MAX_PATH], symname[MY_MAX_PATH];
sprintf(fname, "/proc/%d/fd/%d", getpid(), fd);
ssize_t n = readlink(fname, symname, MY_MAX_PATH);
if ((int)n == -1)
fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to fd=%d ", tstr, (uint64_t) len, fd);
else
fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to %*s ", tstr, (uint64_t) len, (int) n, symname);
fprintf(stderr, "retry in %d second%s\n", toku_write_enospc_sleep, toku_write_enospc_sleep > 1 ? "s" : "");
if (toku_assert_on_write_enospc) {
char err_msg[sizeof("Failed write of [] bytes to fd=[].") + 20+10]; //64 bit is 20 chars, 32 bit is 10 chars
snprintf(err_msg, sizeof(err_msg), "Failed write of [%"PRIu64"] bytes to fd=[%d].", (uint64_t)len, fd);
perror(err_msg);
fflush(stderr);
int out_of_disk_space = 1;
assert(!out_of_disk_space); //Give an error message that might be useful if this is the only one that survives.
} else {
toku_sync_fetch_and_increment_uint64(&toku_write_enospc_total);
toku_sync_fetch_and_increment_uint32(&toku_write_enospc_current);
time_t tnow = time(0);
toku_write_enospc_last_time = tnow;
if (toku_write_enospc_last_report == 0 || tnow - toku_write_enospc_last_report >= 60) {
toku_write_enospc_last_report = tnow;
const int tstr_length = 26;
char tstr[tstr_length];
time_t t = time(0);
ctime_r(&t, tstr);
const int MY_MAX_PATH = 256;
char fname[MY_MAX_PATH], symname[MY_MAX_PATH];
sprintf(fname, "/proc/%d/fd/%d", getpid(), fd);
ssize_t n = readlink(fname, symname, MY_MAX_PATH);
if ((int)n == -1)
fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to fd=%d ", tstr, (uint64_t) len, fd);
else
fprintf(stderr, "%.24s Tokudb No space when writing %"PRIu64" bytes to %*s ", tstr, (uint64_t) len, (int) n, symname);
fprintf(stderr, "retry in %d second%s\n", toku_write_enospc_sleep, toku_write_enospc_sleep > 1 ? "s" : "");
fflush(stderr);
}
sleep(toku_write_enospc_sleep);
try_again = 1;
toku_sync_fetch_and_decrement_uint32(&toku_write_enospc_current);
break;
}
sleep(toku_write_enospc_sleep);
try_again = 1;
toku_sync_fetch_and_decrement_uint32(&toku_write_enospc_current);
break;
#endif
}
}
default:
break;
}
......@@ -197,6 +193,11 @@ toku_file_fsync_without_accounting (int fd) {
return r;
}
static uint64_t get_tnow(void) {
struct timeval tv;
int r = gettimeofday(&tv, NULL); assert(r == 0);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
}
// keep trying if fsync fails because of EINTR
int
......
......@@ -62,6 +62,7 @@
toku_os_get_phys_memory_size;
toku_do_assert_fail;
toku_set_assert_on_write_enospc;
test_db_redirect_dictionary;
local: *;
......
......@@ -163,6 +163,7 @@ write_counting_and_failing (int fd, const void *buf, size_t size)
static void
do_writes_that_fail (void) {
toku_set_assert_on_write_enospc(TRUE);
db_env_set_func_pwrite(pwrite_counting_and_failing);
db_env_set_func_write (write_counting_and_failing);
write_count=0;
......
......@@ -67,6 +67,9 @@ int toku_os_initialize_settings(int verbosity) __attribute__((__visibility__("d
//
int toku_os_is_absolute_name(const char* path) __attribute__((__visibility__("default")));
// Set whether or not writes assert when ENOSPC is returned or they wait for space
void toku_set_assert_on_write_enospc(int do_assert) __attribute__((__visibility__("default")));
// Get file system write information
// *enospc_last_time is the last time ENOSPC was returned by write or pwrite
// *enospc_current is the number of threads waiting on space
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment