Added log stats

This commit is contained in:
Jon Meredith 2009-05-27 15:25:50 -06:00
parent 70dd9ee11a
commit 62d4522580
5 changed files with 200 additions and 3 deletions

View file

@ -36,6 +36,7 @@ static void do_async_cursor_get(void* arg);
static void do_async_truncate(void* arg);
static void do_async_stat(void* arg);
static void do_async_lock_stat(void* arg);
static void do_async_log_stat(void* arg);
static int add_dbref(PortData* data, int dbref);
static int del_dbref(PortData* data, int dbref);
@ -886,6 +887,45 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
int rc = G_DB_ENV->lock_stat_print(G_DB_ENV, flags);
RETURN_INT(rc, outbuf);
}
case CMD_LOG_STAT:
{
FAIL_IF_ASYNC_PENDING(d, outbuf);
// Inbuf is <<Flags:32 >>
// If the working buffer is large enough, copy the data to put/get into it. Otherwise, realloc
// until it is large enough
if (d->work_buffer_sz < inbuf_sz)
{
d->work_buffer = driver_realloc(d->work_buffer, inbuf_sz);
d->work_buffer_sz = inbuf_sz;
}
// Copy the payload into place
memcpy(d->work_buffer, inbuf, inbuf_sz);
d->work_buffer_offset = inbuf_sz;
// Mark the port as busy and then schedule the appropriate async operation
d->async_op = cmd;
d->async_pool = G_TPOOL_GENERAL;
bdberl_tpool_run(d->async_pool, &do_async_log_stat, d, 0, &d->async_job);
// Let caller know that the operation is in progress
// Outbuf is: <<0:32>>
RETURN_INT(0, outbuf);
}
case CMD_LOG_STAT_PRINT:
{
FAIL_IF_ASYNC_PENDING(d, outbuf);
// Inbuf is << Flags:32 >>
unsigned int flags = UNPACK_INT(inbuf, 0);
// Outbuf is <<Rc:32>>
// Run the command on the VM thread - this is for debugging only,
// any real monitoring will use the async lock_stat
int rc = G_DB_ENV->log_stat_print(G_DB_ENV, flags);
RETURN_INT(rc, outbuf);
}
}
*outbuf = 0;
return 0;
@ -1417,6 +1457,52 @@ static void async_cleanup_and_send_lock_stats(PortData* d, DB_LOCK_STAT *lsp)
driver_send_term(port, pid, response, sizeof(response) / sizeof(response[0]));
}
static void async_cleanup_and_send_log_stats(PortData* d, DB_LOG_STAT *lsp)
{
// Save the port and pid references -- we need copies independent from the PortData
// structure. Once we release the port_lock after clearing the cmd, it's possible that
// the port could go away without waiting on us to finish. This is acceptable, but we need
// to be certain that there is no overlap of data between the two threads. driver_send_term
// is safe to use from a thread, even if the port you're sending from has already expired.
ErlDrvPort port = d->port;
ErlDrvTermData pid = d->port_owner;
async_cleanup(d);
ErlDrvTermData response[] = {
ERL_DRV_ATOM, driver_mk_atom("ok"),
// Start of list
ST_STATS_TUPLE(lsp, magic), /* Log file magic number. */
ST_STATS_TUPLE(lsp, version), /* Log file version number. */
ST_STATS_INT_TUPLE(lsp, mode), /* Log file permissions mode. */
ST_STATS_TUPLE(lsp, lg_bsize), /* Log buffer size. */
ST_STATS_TUPLE(lsp, lg_size), /* Log file size. */
ST_STATS_TUPLE(lsp, wc_bytes), /* Bytes to log since checkpoint. */
ST_STATS_TUPLE(lsp, wc_mbytes), /* Megabytes to log since checkpoint. */
ST_STATS_TUPLE(lsp, record), /* Records entered into the log. */
ST_STATS_TUPLE(lsp, w_bytes), /* Bytes to log. */
ST_STATS_TUPLE(lsp, w_mbytes), /* Megabytes to log. */
ST_STATS_TUPLE(lsp, wcount), /* Total I/O writes to the log. */
ST_STATS_TUPLE(lsp, wcount_fill),/* Overflow writes to the log. */
ST_STATS_TUPLE(lsp, rcount), /* Total I/O reads from the log. */
ST_STATS_TUPLE(lsp, scount), /* Total syncs to the log. */
ST_STATS_TUPLE(lsp, region_wait), /* Region lock granted after wait. */
ST_STATS_TUPLE(lsp, region_nowait), /* Region lock granted without wait. */
ST_STATS_TUPLE(lsp, cur_file), /* Current log file number. */
ST_STATS_TUPLE(lsp, cur_offset),/* Current log file offset. */
ST_STATS_TUPLE(lsp, disk_file), /* Known on disk log file number. */
ST_STATS_TUPLE(lsp, disk_offset), /* Known on disk log file offset. */
ST_STATS_TUPLE(lsp, maxcommitperflush), /* Max number of commits in a flush. */
ST_STATS_TUPLE(lsp, mincommitperflush), /* Min number of commits in a flush. */
ST_STATS_TUPLE(lsp, regsize), /* Region size. */
// End of list
ERL_DRV_NIL,
ERL_DRV_LIST, 23+1,
ERL_DRV_TUPLE, 2
};
driver_send_term(port, pid, response, sizeof(response) / sizeof(response[0]));
}
static void do_async_put(void* arg)
{
// Payload is: <<DbRef:32, Flags:32, KeyLen:32, Key:KeyLen, ValLen:32, Val:ValLen>>
@ -1712,6 +1798,32 @@ static void do_async_lock_stat(void* arg)
}
}
static void do_async_log_stat(void* arg)
{
// Payload is: <<Flags:32 >>
PortData* d = (PortData*)arg;
// Extract operation flags
unsigned flags = UNPACK_INT(d->work_buffer, 0);
DB_LOG_STAT *lsp = NULL;
int rc = G_DB_ENV->log_stat(G_DB_ENV, &lsp, flags);
if (rc != 0 || lsp == NULL)
{
async_cleanup_and_send_rc(d, rc);
}
else
{
async_cleanup_and_send_log_stats(d, lsp);
}
// Finally, clean up lock stats
if (NULL != lsp)
{
free(lsp);
}
}
static void* zalloc(unsigned int size)
{

View file

@ -51,6 +51,8 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
#define CMD_ENV_STAT_PRINT 20
#define CMD_LOCK_STAT 21
#define CMD_LOCK_STAT_PRINT 22
#define CMD_LOG_STAT 23
#define CMD_LOG_STAT_PRINT 24
/**
* Command status values

View file

@ -28,6 +28,8 @@
-define(CMD_ENV_STAT_PRINT, 20).
-define(CMD_LOCK_STAT, 21).
-define(CMD_LOCK_STAT_PRINT, 22).
-define(CMD_LOG_STAT, 23).
-define(CMD_LOG_STAT_PRINT, 24).
-define(DB_TYPE_BTREE, 1).
-define(DB_TYPE_HASH, 2).

View file

@ -18,6 +18,8 @@
stat_print/2,
lock_stat/1,
lock_stat_print/1,
log_stat/1,
log_stat_print/1,
env_stat_print/1,
transaction/1, transaction/2, transaction/3,
put/3, put/4,
@ -1399,7 +1401,7 @@ stat_print(Db, Opts) ->
%% <dd>Reset statistics after returning their values</dd>
%% </dl>
%%
%% @spec stat(Opts) -> {ok, [{atom(), number()}]} | {error, Error}
%% @spec lock_stat(Opts) -> {ok, [{atom(), number()}]} | {error, Error}
%% where
%% Opts = [atom()]
%%
@ -1425,7 +1427,6 @@ lock_stat(Opts) ->
end.
%%--------------------------------------------------------------------
%% @doc
%% Print lock stats
@ -1468,6 +1469,79 @@ lock_stat_print(Opts) ->
end.
%%--------------------------------------------------------------------
%% @doc
%% Retrieve log stats
%%
%% This function retrieves bdb log statistics
%%
%% === Options ===
%%
%% <dl>
%% <dt>stat_clear</dt>
%% <dd>Reset statistics after returning their values</dd>
%% </dl>
%%
%% @spec log_stat(Opts) -> {ok, [{atom(), number()}]} | {error, Error}
%% where
%% Opts = [atom()]
%%
%% @end
%%--------------------------------------------------------------------
-spec log_stat(Opts :: db_flags()) ->
{ok, [{atom(), number()}]} | db_error().
log_stat(Opts) ->
Flags = process_flags(Opts),
Cmd = <<Flags:32/native>>,
<<Result:32/signed-native>> = erlang:port_control(get_port(), ?CMD_LOG_STAT, Cmd),
case decode_rc(Result) of
ok ->
receive
{error, Reason} ->
{error, decode_rc(Reason)};
{ok, Stats} ->
{ok, Stats}
end;
Error ->
{error, Error}
end.
%%--------------------------------------------------------------------
%% @doc
%% Print log stats
%%
%% This function prints bdb log statistics to wherever
%% BDB messages are being sent
%%
%% === Options ===
%%
%% <dl>
%% <dt>stat_all</dt>
%% <dd>Display all available information.</dd>
%% <dt>stat_clear</dt>
%% <dd>Reset statistics after displaying their values.</dd>
%% </dl>
%%
%% @spec log_stat_print(Opts) -> ok | {error, Error}
%% where
%% Opts = [atom()]
%%
%% @end
%%--------------------------------------------------------------------
-spec log_stat_print(Opts :: db_flags()) ->
ok | db_error().
log_stat_print(Opts) ->
Flags = process_flags(Opts),
Cmd = <<Flags:32/native>>,
<<Result:32/signed-native>> = erlang:port_control(get_port(), ?CMD_LOG_STAT_PRINT, Cmd),
case decode_rc(Result) of
ok -> ok;
Error -> {error, Error}
end.
%%--------------------------------------------------------------------
%% @doc
%% Print environment stats

View file

@ -35,7 +35,8 @@ all() ->
btree_stat_should_report_on_success,
hash_stat_should_report_on_success,
stat_should_fail_on_bad_dbref,
lock_stat_should_report_on_success].
lock_stat_should_report_on_success,
log_stat_should_report_on_success].
dbconfig(Config) ->
@ -284,3 +285,9 @@ lock_stat_should_report_on_success(_Config) ->
%% Check a lock stat that that probably won't change
2147483647 = proplists:get_value(cur_maxid, Stat),
done.
log_stat_should_report_on_success(_Config) ->
{ok, Stat} = bdberl:log_stat([]),
%% Check a log stat that that probably won't change
264584 = proplists:get_value(magic, Stat),
done.