Commit Diff


commit - e0a9aed47b2fdef34db0bccf8a81b91e4b17e65f
commit + 70969d1d36faa0a9ae679afae71fc32f79853f90
blob - /dev/null
blob + 254b15d2598c3888978e11f60f9912a0296000a3 (mode 644)
--- /dev/null
+++ changelogs/unreleased/gh-7583-txn-stat.md
@@ -0,0 +1,5 @@
+## bugfix/core
+
+* Fixed `BEGIN`, `COMMIT`, and `ROLLBACK` counters in the `box.stat()` output.
+  Now they show the number of started, committed, and rolled back transactions
+  (gh-7583).
blob - a019298c413e6338c7b1dbfa17429ca74f4a491d
blob + c0ad0d0df27f3034f9c586562840c9b98bd879b2
--- src/box/txn.c
+++ src/box/txn.c
@@ -41,6 +41,7 @@
 #include "box.h"
 #include "session.h"
 #include "wal_ext.h"
+#include "rmean.h"
 
 double too_long_threshold;
 
@@ -593,6 +594,7 @@ txn_begin(void)
 		txn_free(txn);
 		return NULL;
 	}
+	rmean_collect(rmean_box, IPROTO_BEGIN, 1);
 	return txn;
 }
 
@@ -812,6 +814,7 @@ txn_complete_fail(struct txn *txn)
 		trigger_destroy(&txn->on_commit);
 	}
 	txn_free_or_wakeup(txn);
+	rmean_collect(rmean_box, IPROTO_ROLLBACK, 1);
 }
 
 void
@@ -839,6 +842,7 @@ txn_complete_success(struct txn *txn)
 		trigger_destroy(&txn->on_rollback);
 	}
 	txn_free_or_wakeup(txn);
+	rmean_collect(rmean_box, IPROTO_COMMIT, 1);
 }
 
 /** Callback invoked when the transaction's journal write is finished. */
blob - /dev/null
blob + 4316f585454db5512c008c1511d3e549a56ed242 (mode 644)
--- /dev/null
+++ test/box-luatest/gh_7583_txn_stat_test.lua
@@ -0,0 +1,154 @@
+local misc = require('test.luatest_helpers.misc')
+local server = require('test.luatest_helpers.server')
+local t = require('luatest')
+
+local g = t.group()
+
+g.before_all(function(cg)
+    cg.server = server:new({alias = 'default'})
+    cg.server:start()
+    cg.server:exec(function()
+        box.schema.create_space('test')
+        box.space.test:create_index('primary')
+    end)
+end)
+
+g.after_each(function(cg)
+    cg.server:exec(function()
+        box.space.test:truncate()
+    end)
+end)
+
+g.after_all(function(cg)
+    cg.server:drop()
+end)
+
+g.test_local = function(cg)
+    cg.server:exec(function()
+        local t = require('luatest')
+        local function stat()
+            local s = box.stat()
+            return {
+                begin = s.BEGIN.total,
+                commit = s.COMMIT.total,
+                rollback = s.ROLLBACK.total,
+            }
+        end
+        box.stat.reset()
+        t.assert_covers(stat(), {begin = 0, commit = 0, rollback = 0})
+        box.space.test:insert({1})
+        t.assert_covers(stat(), {begin = 1, commit = 1, rollback = 0})
+        box.begin()
+        box.space.test:insert({2})
+        box.space.test:insert({3})
+        t.assert_covers(stat(), {begin = 2, commit = 1, rollback = 0})
+        box.commit()
+        t.assert_covers(stat(), {begin = 2, commit = 2, rollback = 0})
+        box.begin()
+        box.space.test:insert({4})
+        t.assert_covers(stat(), {begin = 3, commit = 2, rollback = 0})
+        box.rollback()
+        t.assert_covers(stat(), {begin = 3, commit = 2, rollback = 1})
+    end)
+    cg.server:restart()
+    cg.server:exec(function()
+        local t = require('luatest')
+        local function stat()
+            local s = box.stat()
+            return {
+                begin = s.BEGIN.total,
+                commit = s.COMMIT.total,
+                rollback = s.ROLLBACK.total,
+            }
+        end
+        t.assert_covers(stat(), {begin = 0, commit = 0, rollback = 0})
+    end)
+end
+
+g.before_test('test_replication', function(cg)
+    cg.replica = server:new({
+        alias = 'replica',
+        box_cfg = {
+            replication = server.build_instance_uri('default'),
+        },
+    })
+end)
+
+g.after_test('test_replication', function(cg)
+    cg.replica:drop()
+end)
+
+g.test_replication = function(cg)
+    cg.server:exec(function()
+        box.space.test:insert({1})
+        box.snapshot()
+        box.space.test:insert({2})
+    end)
+    cg.replica:start()
+    cg.replica:exec(function()
+        local t = require('luatest')
+        local function stat()
+            local s = box.stat()
+            return {
+                begin = s.BEGIN.total,
+                commit = s.COMMIT.total,
+                rollback = s.ROLLBACK.total,
+            }
+        end
+        t.assert_covers(stat(), {begin = 0, commit = 0, rollback = 0})
+    end)
+    local vclock = cg.server:exec(function()
+        box.begin()
+        box.space.test:insert{3}
+        box.space.test:insert{4}
+        box.commit()
+        box.space.test:insert{5}
+        box.begin()
+        box.space.test:insert{6}
+        box.space.test:insert{7}
+        box.rollback()
+        return box.info.vclock
+    end)
+    cg.replica:wait_vclock(vclock)
+    cg.replica:exec(function()
+        local t = require('luatest')
+        local function stat()
+            local s = box.stat()
+            return {
+                begin = s.BEGIN.total,
+                commit = s.COMMIT.total,
+                rollback = s.ROLLBACK.total,
+            }
+        end
+        t.assert_covers(stat(), {begin = 2, commit = 2, rollback = 0})
+    end)
+end
+
+g.after_test('test_wal_error', function(cg)
+    cg.server:exec(function()
+        box.error.injection.set('ERRINJ_WAL_WRITE', false)
+    end)
+end)
+
+g.test_wal_error = function(cg)
+    misc.skip_if_not_debug()
+    cg.server:exec(function()
+        local t = require('luatest')
+        local function stat()
+            local s = box.stat()
+            return {
+                begin = s.BEGIN.total,
+                commit = s.COMMIT.total,
+                rollback = s.ROLLBACK.total,
+            }
+        end
+        box.stat.reset()
+        t.assert_covers(stat(), {begin = 0, commit = 0, rollback = 0})
+        box.begin()
+        t.assert_covers(stat(), {begin = 1, commit = 0, rollback = 0})
+        box.space.test:insert{1}
+        box.error.injection.set('ERRINJ_WAL_WRITE', true)
+        t.assert_error_msg_equals("Failed to write to disk", box.commit)
+        t.assert_covers(stat(), {begin = 1, commit = 0, rollback = 1})
+    end)
+end