summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexg@wiredtiger.com>2012-11-28 10:30:37 +1100
committerAlex Gorrod <alexg@wiredtiger.com>2012-11-28 10:30:37 +1100
commit45a13edceabecaa1544e99db7b6c51f60d6a34c7 (patch)
treec4158ea87f12345e496fb45e48ae5207c483a2a2
parent91d9d8ef94513923a446f9fdab596aa2951ff1f2 (diff)
downloadmongo-45a13edceabecaa1544e99db7b6c51f60d6a34c7.tar.gz
Fix tracking of dirty pages. Add statistics for dirty pages.
-rw-r--r--dist/stat_data.py4
-rw-r--r--examples/c/ex_all.c2
-rw-r--r--src/btree/bt_handle.c2
-rw-r--r--src/btree/bt_page.c2
-rw-r--r--src/btree/bt_read.c2
-rw-r--r--src/btree/bt_slvg.c2
-rw-r--r--src/btree/bt_sync.c2
-rw-r--r--src/btree/bt_walk.c2
-rw-r--r--src/btree/rec_write.c11
-rw-r--r--src/conn/conn_cache.c52
-rw-r--r--src/conn/conn_stat.c2
-rw-r--r--src/include/btree.i36
-rw-r--r--src/include/extern.h2
-rw-r--r--src/include/stat.h4
-rw-r--r--src/include/wiredtiger.in52
-rw-r--r--src/support/stat.c12
16 files changed, 135 insertions, 54 deletions
diff --git a/dist/stat_data.py b/dist/stat_data.py
index 2129b72dfa9..21f25b2db32 100644
--- a/dist/stat_data.py
+++ b/dist/stat_data.py
@@ -22,6 +22,8 @@ class Stat:
connection_stats = [
Stat('block_read', 'blocks read from a file'),
Stat('block_write', 'blocks written to a file'),
+ Stat('cache_bytes_dirty', 'cache: tracked dirty bytes in the cache'),
+ Stat('cache_bytes_dirty_calc', 'cache: counted dirty bytes in the cache'),
Stat('cache_bytes_inuse',
'cache: bytes currently held in the cache', perm=1),
Stat('cache_bytes_max', 'cache: maximum bytes configured', perm=1),
@@ -32,6 +34,8 @@ connection_stats = [
Stat('cache_evict_slow',
'cache: eviction server unable to reach eviction goal'),
Stat('cache_evict_unmodified', 'cache: unmodified pages evicted'),
+ Stat('cache_pages_dirty', 'cache: tracked dirty pages in the cache'),
+ Stat('cache_pages_dirty_calc', 'cache: counted dirty pages in the cache'),
Stat('cache_pages_inuse',
'cache: pages currently held in the cache', perm=1),
Stat('checkpoint', 'checkpoints'),
diff --git a/examples/c/ex_all.c b/examples/c/ex_all.c
index 710065f32b5..a4512b33f28 100644
--- a/examples/c/ex_all.c
+++ b/examples/c/ex_all.c
@@ -806,7 +806,7 @@ connection_ops(WT_CONNECTION *conn)
/*! [Setup cache dirty target] */
ret = conn->reconfigure(conn, "eviction_dirty_target=75");
- /*! [Reconfigure a connection] */
+ /*! [Setup cache dirty target] */
/*! [Get the database home directory] */
printf("The database home is %s\n", conn->get_home(conn));
diff --git a/src/btree/bt_handle.c b/src/btree/bt_handle.c
index 64e692d1cbb..99e91566e46 100644
--- a/src/btree/bt_handle.c
+++ b/src/btree/bt_handle.c
@@ -380,7 +380,7 @@ __btree_tree_open_empty(WT_SESSION_IMPL *session, int created)
* or it's actually modified.
*/
WT_ERR(__wt_page_modify_init(session, leaf));
- __wt_page_modify_set(leaf);
+ __wt_page_modify_set(session, leaf);
btree->root_page = root;
diff --git a/src/btree/bt_page.c b/src/btree/bt_page.c
index cd74e3cdc87..7ea6318226f 100644
--- a/src/btree/bt_page.c
+++ b/src/btree/bt_page.c
@@ -389,7 +389,7 @@ __inmem_row_int(WT_SESSION_IMPL *session, WT_PAGE *page, size_t *inmem_sizep)
WT_ERR(__wt_page_modify_init(session, page));
page->modify->first_id = WT_TXN_NONE;
if (btree->modified)
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
}
++ref;
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index e86f4ccd8d7..0830963eb2c 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -33,7 +33,7 @@ __cache_read_row_deleted(
WT_RET(__wt_page_modify_init(session, page));
page->modify->first_id = ref->txnid;
if (btree->modified)
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
/* Allocate the update array. */
WT_RET(__wt_calloc_def(session, page->entries, &upd_array));
diff --git a/src/btree/bt_slvg.c b/src/btree/bt_slvg.c
index 4a1e5c4a77e..c332fd8e39e 100644
--- a/src/btree/bt_slvg.c
+++ b/src/btree/bt_slvg.c
@@ -1049,7 +1049,7 @@ __slvg_modify_init(WT_SESSION_IMPL *session, WT_PAGE *page)
/* The page is dirty. */
WT_RET(__wt_page_modify_init(session, page));
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
return (0);
}
diff --git a/src/btree/bt_sync.c b/src/btree/bt_sync.c
index bb05f966ee4..bf6505da3a7 100644
--- a/src/btree/bt_sync.c
+++ b/src/btree/bt_sync.c
@@ -22,7 +22,7 @@ __wt_bt_cache_force_write(WT_SESSION_IMPL *session)
/* Dirty the root page to ensure a write. */
WT_RET(__wt_page_modify_init(session, page));
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
return (0);
}
diff --git a/src/btree/bt_walk.c b/src/btree/bt_walk.c
index 7fcedbdd1e2..8c0e033ef80 100644
--- a/src/btree/bt_walk.c
+++ b/src/btree/bt_walk.c
@@ -95,7 +95,7 @@ __tree_walk_delete(
* we write the tree.
*/
WT_ERR(__wt_page_modify_init(session, page));
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
*skipp = 1;
diff --git a/src/btree/rec_write.c b/src/btree/rec_write.c
index 360e184da75..fa789072fda 100644
--- a/src/btree/rec_write.c
+++ b/src/btree/rec_write.c
@@ -476,7 +476,7 @@ __wt_rec_write(WT_SESSION_IMPL *session,
break;
}
WT_RET(__wt_page_modify_init(session, page));
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
return (0);
}
@@ -524,7 +524,7 @@ __wt_rec_write(WT_SESSION_IMPL *session,
WT_VERBOSE_RET(session, reconcile,
"root page split %p -> %p", page, page->modify->u.split);
page = page->modify->u.split;
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
F_CLR(page->modify, WT_PM_REC_SPLIT_MERGE);
WT_RET(__wt_rec_write(session, page, NULL, flags));
@@ -1389,7 +1389,7 @@ __wt_rec_bulk_wrapup(WT_CURSOR_BULK *cbulk)
/* Mark the page's parent dirty. */
WT_RET(__wt_page_modify_init(session, page->parent));
- __wt_page_modify_set(page->parent);
+ __wt_page_modify_set(session, page->parent);
__wt_rec_destroy(session, &cbulk->reconcile);
@@ -3178,6 +3178,7 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
WT_DECL_RET;
WT_PAGE_MODIFY *mod;
uint32_t i;
+ int was_modified;
btree = session->btree;
mod = page->modify;
@@ -3375,8 +3376,10 @@ err: __wt_scr_free(&tkey);
* started.
*/
if (!r->upd_skipped) {
- __wt_cache_dirty_decr(session, page->memory_footprint);
+ was_modified = __wt_page_is_modified(page);
mod->disk_gen = r->orig_write_gen;
+ if (was_modified && !__wt_page_is_modified(page))
+ __wt_cache_dirty_decr(session, page->memory_footprint);
}
return (0);
diff --git a/src/conn/conn_cache.c b/src/conn/conn_cache.c
index 1f8afc3fe97..ed056bb4fe5 100644
--- a/src/conn/conn_cache.c
+++ b/src/conn/conn_cache.c
@@ -7,6 +7,8 @@
#include "wt_internal.h"
+static void __cache_stats_traverse(WT_CONNECTION_IMPL *conn);
+
/*
* __wt_cache_config --
* Configure the underlying cache.
@@ -88,7 +90,7 @@ __wt_cache_create(WT_CONNECTION_IMPL *conn, const char *cfg[])
* We pull some values from the cache statistics (rather than have two
* copies). Set them.
*/
- __wt_cache_stats_update(conn);
+ __wt_cache_stats_update(conn, 0);
return (0);
@@ -101,7 +103,7 @@ err: __wt_cache_destroy(conn);
* Update the cache statistics for return to the application.
*/
void
-__wt_cache_stats_update(WT_CONNECTION_IMPL *conn)
+__wt_cache_stats_update(WT_CONNECTION_IMPL *conn, uint32_t flags)
{
WT_CACHE *cache;
@@ -112,6 +114,52 @@ __wt_cache_stats_update(WT_CONNECTION_IMPL *conn)
conn->stats, cache_bytes_inuse, __wt_cache_bytes_inuse(cache));
WT_STAT_SET(
conn->stats, cache_pages_inuse, __wt_cache_pages_inuse(cache));
+ WT_STAT_SET(
+ conn->stats, cache_bytes_dirty, __wt_cache_dirty_bytes(cache));
+ WT_STAT_SET(
+ conn->stats, cache_pages_dirty, cache->pages_dirty);
+
+ if (!LF_ISSET(WT_STATISTICS_FAST))
+ __cache_stats_traverse(conn);
+}
+
+/*
+ * __cache_stats_traverse --
+ * Generate statistics that require traversing the cache.
+ */
+static void
+__cache_stats_traverse(WT_CONNECTION_IMPL *conn)
+{
+ WT_BTREE *btree;
+ WT_CACHE *cache;
+ WT_DECL_RET;
+ WT_PAGE *page;
+ WT_SESSION_IMPL *session;
+
+ cache = conn->cache;
+ session = conn->default_session;
+ page = NULL;
+ btree = NULL;
+
+ WT_STAT_SET(conn->stats, cache_bytes_dirty_calc, 0);
+ WT_STAT_SET(conn->stats, cache_pages_dirty_calc, 0);
+
+ TAILQ_FOREACH(btree, &conn->btqh, q) {
+ /* Reference the correct WT_BTREE handle. */
+ WT_SET_BTREE_IN_SESSION(session, btree);
+ while ((ret = __wt_tree_walk(
+ session, &page, WT_TREE_EVICT)) == 0 &&
+ page != NULL) {
+ if (__wt_page_is_modified(page)) {
+ WT_STAT_INCRV(conn->stats,
+ cache_bytes_dirty_calc,
+ page->memory_footprint);
+ WT_STAT_INCRV(conn->stats,
+ cache_pages_dirty_calc, 1);
+ }
+ }
+ WT_CLEAR_BTREE_IN_SESSION(session);
+ }
}
/*
diff --git a/src/conn/conn_stat.c b/src/conn/conn_stat.c
index df861665b4b..154689f80de 100644
--- a/src/conn/conn_stat.c
+++ b/src/conn/conn_stat.c
@@ -19,5 +19,5 @@ __wt_conn_stat_init(WT_SESSION_IMPL *session, uint32_t flags)
WT_UNUSED(flags);
conn = S2C(session);
- __wt_cache_stats_update(conn);
+ __wt_cache_stats_update(conn, flags);
}
diff --git a/src/include/btree.i b/src/include/btree.i
index c98c3a33355..edc04e4959f 100644
--- a/src/include/btree.i
+++ b/src/include/btree.i
@@ -38,10 +38,13 @@ static inline void
__wt_cache_page_inmem_decr(
WT_SESSION_IMPL *session, WT_PAGE *page, size_t size)
{
- (void)WT_ATOMIC_SUB(S2C(session)->cache->bytes_inmem, size);
+ WT_CACHE *cache;
+ cache = S2C(session)->cache;
+
+ (void)WT_ATOMIC_SUB(cache->bytes_inmem, size);
(void)WT_ATOMIC_SUB(page->memory_footprint, WT_STORE_SIZE(size));
if (__wt_page_is_modified(page))
- (void)WT_ATOMIC_SUB(S2C(session)->cache->bytes_dirty, size);
+ (void)WT_ATOMIC_SUB(cache->bytes_dirty, size);
}
/*
@@ -53,8 +56,13 @@ static inline void
__wt_cache_dirty_decr(
WT_SESSION_IMPL *session, size_t size)
{
- (void)WT_ATOMIC_SUB(
- S2C(session)->cache->bytes_dirty, size);
+ WT_CACHE *cache;
+ cache = S2C(session)->cache;
+
+ WT_ASSERT(session,
+ cache->bytes_dirty >= size && cache->pages_dirty > 0);
+ (void)WT_ATOMIC_SUB(cache->bytes_dirty, size);
+ (void)WT_ATOMIC_SUB(cache->pages_dirty, 1);
}
/*
@@ -91,12 +99,6 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page)
(void)WT_ATOMIC_ADD(cache->pages_evict, 1);
(void)WT_ATOMIC_ADD(cache->bytes_evict, page->memory_footprint);
- if (__wt_page_is_modified(page)) {
- (void)WT_ATOMIC_SUB(cache->pages_dirty, 1);
- WT_ASSERT(session, cache->bytes_dirty > page->memory_footprint);
- (void)WT_ATOMIC_SUB(cache->bytes_dirty, page->memory_footprint);
- }
-
page->memory_footprint = 0;
}
@@ -176,11 +178,6 @@ __wt_page_modify_init(WT_SESSION_IMPL *session, WT_PAGE *page)
*/
if (!WT_ATOMIC_CAS(page->modify, NULL, modify))
__wt_free(session, modify);
- else {
- (void)WT_ATOMIC_ADD(S2C(session)->cache->pages_dirty, 1);
- (void)WT_ATOMIC_ADD(
- S2C(session)->cache->bytes_dirty, page->memory_footprint);
- }
return (0);
}
@@ -189,8 +186,13 @@ __wt_page_modify_init(WT_SESSION_IMPL *session, WT_PAGE *page)
* Mark the page dirty.
*/
static inline void
-__wt_page_modify_set(WT_PAGE *page)
+__wt_page_modify_set(WT_SESSION_IMPL *session, WT_PAGE *page)
{
+ if (!__wt_page_is_modified(page)) {
+ (void)WT_ATOMIC_ADD(S2C(session)->cache->pages_dirty, 1);
+ (void)WT_ATOMIC_ADD(
+ S2C(session)->cache->bytes_dirty, page->memory_footprint);
+ }
/*
* Publish: there must be a barrier to ensure all changes to the page
* are flushed before we update the page's write generation, otherwise
@@ -220,7 +222,7 @@ __wt_page_and_tree_modify_set(WT_SESSION_IMPL *session, WT_PAGE *page)
*/
btree->modified = 1;
- __wt_page_modify_set(page);
+ __wt_page_modify_set(session, page);
}
/*
diff --git a/src/include/extern.h b/src/include/extern.h
index 09826b23a4d..16f5328b421 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -605,7 +605,7 @@ extern const char *__wt_confdfl_wiredtiger_open;
extern WT_CONFIG_CHECK __wt_confchk_wiredtiger_open[];
extern int __wt_cache_config(WT_CONNECTION_IMPL *conn, const char *cfg[]);
extern int __wt_cache_create(WT_CONNECTION_IMPL *conn, const char *cfg[]);
-extern void __wt_cache_stats_update(WT_CONNECTION_IMPL *conn);
+extern void __wt_cache_stats_update(WT_CONNECTION_IMPL *conn, uint32_t flags);
extern void __wt_cache_destroy(WT_CONNECTION_IMPL *conn);
extern int __wt_conn_cache_pool_config(WT_SESSION_IMPL *session,
const char **cfg);
diff --git a/src/include/stat.h b/src/include/stat.h
index 9f8445cc5e8..9fa5e8b3e10 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -138,6 +138,8 @@ struct __wt_dsrc_stats {
struct __wt_connection_stats {
WT_STATS block_read;
WT_STATS block_write;
+ WT_STATS cache_bytes_dirty;
+ WT_STATS cache_bytes_dirty_calc;
WT_STATS cache_bytes_inuse;
WT_STATS cache_bytes_max;
WT_STATS cache_evict_hazard;
@@ -145,6 +147,8 @@ struct __wt_connection_stats {
WT_STATS cache_evict_modified;
WT_STATS cache_evict_slow;
WT_STATS cache_evict_unmodified;
+ WT_STATS cache_pages_dirty;
+ WT_STATS cache_pages_dirty_calc;
WT_STATS cache_pages_inuse;
WT_STATS checkpoint;
WT_STATS cond_wait;
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index dfbab5be762..5d5bdcb1fab 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1706,51 +1706,59 @@ extern int wiredtiger_extension_init(WT_SESSION *session,
#define WT_STAT_CONN_BLOCK_READ 0
/*! blocks written to a file */
#define WT_STAT_CONN_BLOCK_WRITE 1
+/*! cache: tracked dirty bytes in the cache */
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY 2
+/*! cache: counted dirty bytes in the cache */
+#define WT_STAT_CONN_CACHE_BYTES_DIRTY_CALC 3
/*! cache: bytes currently held in the cache */
-#define WT_STAT_CONN_CACHE_BYTES_INUSE 2
+#define WT_STAT_CONN_CACHE_BYTES_INUSE 4
/*! cache: maximum bytes configured */
-#define WT_STAT_CONN_CACHE_BYTES_MAX 3
+#define WT_STAT_CONN_CACHE_BYTES_MAX 5
/*! cache: pages selected for eviction not evicted because of a hazard
* reference */
-#define WT_STAT_CONN_CACHE_EVICT_HAZARD 4
+#define WT_STAT_CONN_CACHE_EVICT_HAZARD 6
/*! cache: internal pages evicted */
-#define WT_STAT_CONN_CACHE_EVICT_INTERNAL 5
+#define WT_STAT_CONN_CACHE_EVICT_INTERNAL 7
/*! cache: modified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICT_MODIFIED 6
+#define WT_STAT_CONN_CACHE_EVICT_MODIFIED 8
/*! cache: eviction server unable to reach eviction goal */
-#define WT_STAT_CONN_CACHE_EVICT_SLOW 7
+#define WT_STAT_CONN_CACHE_EVICT_SLOW 9
/*! cache: unmodified pages evicted */
-#define WT_STAT_CONN_CACHE_EVICT_UNMODIFIED 8
+#define WT_STAT_CONN_CACHE_EVICT_UNMODIFIED 10
+/*! cache: tracked dirty pages in the cache */
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY 11
+/*! cache: counted dirty pages in the cache */
+#define WT_STAT_CONN_CACHE_PAGES_DIRTY_CALC 12
/*! cache: pages currently held in the cache */
-#define WT_STAT_CONN_CACHE_PAGES_INUSE 9
+#define WT_STAT_CONN_CACHE_PAGES_INUSE 13
/*! checkpoints */
-#define WT_STAT_CONN_CHECKPOINT 10
+#define WT_STAT_CONN_CHECKPOINT 14
/*! condition wait calls */
-#define WT_STAT_CONN_COND_WAIT 11
+#define WT_STAT_CONN_COND_WAIT 15
/*! files currently open */
-#define WT_STAT_CONN_FILE_OPEN 12
+#define WT_STAT_CONN_FILE_OPEN 16
/*! total memory allocations */
-#define WT_STAT_CONN_MEMALLOC 13
+#define WT_STAT_CONN_MEMALLOC 17
/*! total memory frees */
-#define WT_STAT_CONN_MEMFREE 14
+#define WT_STAT_CONN_MEMFREE 18
/*! rwlock readlock calls */
-#define WT_STAT_CONN_RWLOCK_RDLOCK 15
+#define WT_STAT_CONN_RWLOCK_RDLOCK 19
/*! rwlock writelock calls */
-#define WT_STAT_CONN_RWLOCK_WRLOCK 16
+#define WT_STAT_CONN_RWLOCK_WRLOCK 20
/*! total read I/Os */
-#define WT_STAT_CONN_TOTAL_READ_IO 17
+#define WT_STAT_CONN_TOTAL_READ_IO 21
/*! total write I/Os */
-#define WT_STAT_CONN_TOTAL_WRITE_IO 18
+#define WT_STAT_CONN_TOTAL_WRITE_IO 22
/*! ancient transactions */
-#define WT_STAT_CONN_TXN_ANCIENT 19
+#define WT_STAT_CONN_TXN_ANCIENT 23
/*! transactions */
-#define WT_STAT_CONN_TXN_BEGIN 20
+#define WT_STAT_CONN_TXN_BEGIN 24
/*! transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 21
+#define WT_STAT_CONN_TXN_COMMIT 25
/*! transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 22
+#define WT_STAT_CONN_TXN_FAIL_CACHE 26
/*! transactions rolled-back */
-#define WT_STAT_CONN_TXN_ROLLBACK 23
+#define WT_STAT_CONN_TXN_ROLLBACK 27
/*!
* @}
diff --git a/src/support/stat.c b/src/support/stat.c
index b79f7f3e8e5..11d717824f5 100644
--- a/src/support/stat.c
+++ b/src/support/stat.c
@@ -155,6 +155,10 @@ __wt_stat_alloc_connection_stats(WT_SESSION_IMPL *session, WT_CONNECTION_STATS *
stats->block_read.desc = "blocks read from a file";
stats->block_write.desc = "blocks written to a file";
+ stats->cache_bytes_dirty.desc =
+ "cache: tracked dirty bytes in the cache";
+ stats->cache_bytes_dirty_calc.desc =
+ "cache: counted dirty bytes in the cache";
stats->cache_bytes_inuse.desc =
"cache: bytes currently held in the cache";
stats->cache_bytes_max.desc = "cache: maximum bytes configured";
@@ -165,6 +169,10 @@ __wt_stat_alloc_connection_stats(WT_SESSION_IMPL *session, WT_CONNECTION_STATS *
stats->cache_evict_slow.desc =
"cache: eviction server unable to reach eviction goal";
stats->cache_evict_unmodified.desc = "cache: unmodified pages evicted";
+ stats->cache_pages_dirty.desc =
+ "cache: tracked dirty pages in the cache";
+ stats->cache_pages_dirty_calc.desc =
+ "cache: counted dirty pages in the cache";
stats->cache_pages_inuse.desc =
"cache: pages currently held in the cache";
stats->checkpoint.desc = "checkpoints";
@@ -195,11 +203,15 @@ __wt_stat_clear_connection_stats(WT_STATS *stats_arg)
stats = (WT_CONNECTION_STATS *)stats_arg;
stats->block_read.v = 0;
stats->block_write.v = 0;
+ stats->cache_bytes_dirty.v = 0;
+ stats->cache_bytes_dirty_calc.v = 0;
stats->cache_evict_hazard.v = 0;
stats->cache_evict_internal.v = 0;
stats->cache_evict_modified.v = 0;
stats->cache_evict_slow.v = 0;
stats->cache_evict_unmodified.v = 0;
+ stats->cache_pages_dirty.v = 0;
+ stats->cache_pages_dirty_calc.v = 0;
stats->checkpoint.v = 0;
stats->cond_wait.v = 0;
stats->file_open.v = 0;