Skip to content

Commit 7ccdb48

Browse files
committed
WL7639 Ndb Active Active Manageability improvements
Implement status variables exposing last commit epochs for the server and each session. New status variables Ndb_last_commit_epoch_server and Ndb_last_commit_epoch_session are added to the MySQL server, allowing SQL layer code to determine e.g. - What was the epoch of the last transaction committed by this server (Same info as embedded in SHOW ENGINE NDB STATUS output) - What was the epoch of the last transaction committed by this session The session variant particularly is useful when determining when various post-commit activities have completed on a transaction. e.g. it could be used to determine k-safety round a replication ring by comparing with the Max_replicated_epoch, or if a latest-disk-durable epoch were exposed, it could be used to determine when a transaction becomes disk-durable. A new testcase is added to verify the behaviour of the variables.
1 parent c20b55e commit 7ccdb48

9 files changed

+211
-3
lines changed

mysql-test/suite/ndb/r/ndb_basic.result

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ Ndb_execute_count #
8989
Ndb_index_stat_cache_clean #
9090
Ndb_index_stat_cache_query #
9191
Ndb_index_stat_status #
92+
Ndb_last_commit_epoch_server #
93+
Ndb_last_commit_epoch_session #
9294
Ndb_number_of_data_nodes #
9395
Ndb_number_of_ready_data_nodes #
9496
Ndb_pruned_scan_count #
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
Reset binlog and show no state held
2+
reset master;
3+
select count(1) from mysql.ndb_binlog_index;
4+
count(1)
5+
0
6+
Create table for experiments
7+
use test;
8+
create table test.t1 (a int primary key, b varchar(1000), c text) engine=ndb;
9+
Basic test that an insert affects Server + Session epochs
10+
insert into test.t1 values (1, repeat("B", 1000), repeat("E", 500));
11+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
12+
1 1 1 1
13+
binlog_contains_last_session_epoch
14+
1
15+
Basic test that a read with exclusive lock has no effect
16+
begin;
17+
select count(1) from test.t1 where a=1 for update;
18+
count(1)
19+
1
20+
commit;
21+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
22+
1 1 1 1
23+
binlog_contains_last_session_epoch
24+
0
25+
Basic test that a read with shared lock has no effect
26+
begin;
27+
select count(1) from test.t1 where a=1 lock in share mode;
28+
count(1)
29+
1
30+
commit;
31+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
32+
1 1 1 1
33+
binlog_contains_last_session_epoch
34+
0
35+
Basic test that a committedread has no effect
36+
begin;
37+
select count(1) from test.t1 where a=1;
38+
count(1)
39+
1
40+
commit;
41+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
42+
1 1 1 1
43+
binlog_contains_last_session_epoch
44+
0
45+
Basic test that an update affects Server + Session epochs
46+
update test.t1 set b=repeat("E", 1000), c=repeat("A", 5000) where a=1;
47+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
48+
1 1 1 1
49+
binlog_contains_last_session_epoch
50+
1
51+
Basic test that a delete affects Server + Session epochs
52+
delete from test.t1 where a=1;
53+
init_server_epoch_includes_session_epoch curr_server_epoch_includes_session_epoch server_epoch_does_not_regress session_epoch_does_not_regress
54+
1 1 1 1
55+
binlog_contains_last_session_epoch
56+
1
57+
Show that server epoch is preserved across connections
58+
but session epoch is not
59+
server_epoch_preserved
60+
1
61+
session_epoch_reset
62+
1
63+
drop table test.t1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--disable_query_log
2+
--disable_result_log
3+
4+
select @curr_server_epoch:=Variable_value
5+
from information_schema.global_status
6+
where Variable_name ="ndb_last_commit_epoch_server";
7+
8+
select @curr_session_epoch:=Variable_value
9+
from information_schema.global_status
10+
where Variable_name ="ndb_last_commit_epoch_session";
11+
12+
show binlog events;
13+
14+
select @binlog_max_epoch:= max(epoch)
15+
from mysql.ndb_binlog_index;
16+
17+
--enable_result_log
18+
19+
select (@init_server_epoch + 0) >= (@init_session_epoch + 0)
20+
as init_server_epoch_includes_session_epoch,
21+
(@curr_server_epoch + 0) >= (@curr_session_epoch + 0)
22+
as curr_server_epoch_includes_session_epoch,
23+
(@curr_server_epoch + 0) >= (@init_server_epoch + 0)
24+
as server_epoch_does_not_regress,
25+
(@curr_session_epoch + 0) >= (@init_session_epoch + 0)
26+
as session_epoch_does_not_regress;
27+
28+
select @binlog_max_epoch = @curr_session_epoch as
29+
binlog_contains_last_session_epoch;
30+
31+
--enable_query_log
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--disable_query_log
2+
--disable_result_log
3+
4+
select @init_server_epoch:=Variable_value
5+
from information_schema.global_status
6+
where Variable_name ="ndb_last_commit_epoch_server";
7+
8+
select @init_session_epoch:=Variable_value
9+
from information_schema.global_status
10+
where Variable_name ="ndb_last_commit_epoch_session";
11+
12+
--enable_query_log
13+
--enable_result_log
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
-- source include/have_ndb.inc
2+
-- source include/have_binlog_format_mixed_or_row.inc
3+
4+
--echo Reset binlog and show no state held
5+
reset master;
6+
select count(1) from mysql.ndb_binlog_index;
7+
8+
--echo Create table for experiments
9+
use test;
10+
create table test.t1 (a int primary key, b varchar(1000), c text) engine=ndb;
11+
12+
--echo Basic test that an insert affects Server + Session epochs
13+
--source ndb_binlog_init_epoch_vals.inc
14+
insert into test.t1 values (1, repeat("B", 1000), repeat("E", 500));
15+
--source ndb_binlog_cmp_epoch_vals.inc
16+
17+
--echo Basic test that a read with exclusive lock has no effect
18+
--source ndb_binlog_init_epoch_vals.inc
19+
begin;
20+
select count(1) from test.t1 where a=1 for update;
21+
commit;
22+
--source ndb_binlog_cmp_epoch_vals.inc
23+
24+
--echo Basic test that a read with shared lock has no effect
25+
--source ndb_binlog_init_epoch_vals.inc
26+
begin;
27+
select count(1) from test.t1 where a=1 lock in share mode;
28+
commit;
29+
--source ndb_binlog_cmp_epoch_vals.inc
30+
31+
--echo Basic test that a committedread has no effect
32+
--source ndb_binlog_init_epoch_vals.inc
33+
begin;
34+
select count(1) from test.t1 where a=1;
35+
commit;
36+
--source ndb_binlog_cmp_epoch_vals.inc
37+
38+
--echo Basic test that an update affects Server + Session epochs
39+
--source ndb_binlog_init_epoch_vals.inc
40+
update test.t1 set b=repeat("E", 1000), c=repeat("A", 5000) where a=1;
41+
--source ndb_binlog_cmp_epoch_vals.inc
42+
43+
--echo Basic test that a delete affects Server + Session epochs
44+
--source ndb_binlog_init_epoch_vals.inc
45+
delete from test.t1 where a=1;
46+
--source ndb_binlog_cmp_epoch_vals.inc
47+
48+
--echo Show that server epoch is preserved across connections
49+
--echo but session epoch is not
50+
51+
--source ndb_binlog_init_epoch_vals.inc
52+
let $server_epoch= query_get_value(select @init_server_epoch as e, e, 1);
53+
let $session_epoch= query_get_value(select @init_session_epoch as e, e, 1);
54+
connect('ExtraConn', '127.0.0.1', 'root',,,$MASTER_MYPORT);
55+
--source ndb_binlog_init_epoch_vals.inc
56+
let $new_server_epoch= query_get_value(select @init_server_epoch as e, e, 1);
57+
let $new_session_epoch= query_get_value(select @init_session_epoch as e, e, 1);
58+
59+
--disable_query_log
60+
eval select $new_server_epoch >= $server_epoch as server_epoch_preserved;
61+
eval select $new_session_epoch < $session_epoch as session_epoch_reset;
62+
--enable_query_log
63+
64+
drop table test.t1;
65+

sql/ha_ndbcluster.cc

+24-1
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ static int update_status_variables(Thd_ndb *thd_ndb,
595595
}
596596
ns->number_of_data_nodes= c->no_db_nodes();
597597
ns->connect_count= c->get_connect_count();
598+
ns->last_commit_epoch_server= ndb_get_latest_trans_gci();
598599
if (thd_ndb)
599600
{
600601
ns->execute_count= thd_ndb->m_execute_count;
@@ -605,6 +606,7 @@ static int update_status_variables(Thd_ndb *thd_ndb,
605606
ns->pushed_queries_dropped= thd_ndb->m_pushed_queries_dropped;
606607
ns->pushed_queries_executed= thd_ndb->m_pushed_queries_executed;
607608
ns->pushed_reads= thd_ndb->m_pushed_reads;
609+
ns->last_commit_epoch_session = thd_ndb->m_last_commit_epoch_session;
608610
for (int i= 0; i < MAX_NDB_NODES; i++)
609611
{
610612
ns->transaction_no_hint_count[i]= thd_ndb->m_transaction_no_hint_count[i];
@@ -708,6 +710,12 @@ SHOW_VAR ndb_status_variables_dynamic[]= {
708710
{"pushed_queries_executed", (char*) &g_ndb_status.pushed_queries_executed,
709711
SHOW_LONG},
710712
{"pushed_reads", (char*) &g_ndb_status.pushed_reads, SHOW_LONG},
713+
{"last_commit_epoch_server",
714+
(char*) &g_ndb_status.last_commit_epoch_server,
715+
SHOW_LONGLONG},
716+
{"last_commit_epoch_session",
717+
(char*) &g_ndb_status.last_commit_epoch_session,
718+
SHOW_LONGLONG},
711719
{NullS, NullS, SHOW_LONG}
712720
};
713721

@@ -1143,6 +1151,20 @@ execute_commit(Thd_ndb *thd_ndb, NdbTransaction *trans,
11431151
ignore_count);
11441152
} while (0);
11451153

1154+
if (likely(rc == 0))
1155+
{
1156+
/* Committed ok, update session GCI, if it's available
1157+
* (Not available for reads, empty transactions etc...)
1158+
*/
1159+
Uint64 reportedGCI;
1160+
if (trans->getGCI(&reportedGCI) == 0 &&
1161+
reportedGCI != 0)
1162+
{
1163+
assert(reportedGCI >= thd_ndb->m_last_commit_epoch_session);
1164+
thd_ndb->m_last_commit_epoch_session = reportedGCI;
1165+
}
1166+
}
1167+
11461168
if (thd_ndb->is_slave_thread())
11471169
{
11481170
if (likely(rc == 0))
@@ -1193,7 +1215,8 @@ Thd_ndb::Thd_ndb(THD* thd) :
11931215
m_thd(thd),
11941216
m_slave_thread(thd->slave_thread),
11951217
m_skip_binlog_setup_in_find_files(false),
1196-
schema_locks_count(0)
1218+
schema_locks_count(0),
1219+
m_last_commit_epoch_session(0)
11971220
{
11981221
connection= ndb_get_cluster_connection();
11991222
m_connect_count= connection->get_connect_count();

sql/ha_ndbcluster.h

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct st_ndb_status {
124124
long pushed_queries_dropped;
125125
long pushed_queries_executed;
126126
long pushed_reads;
127+
long last_commit_epoch_server;
128+
long last_commit_epoch_session;
127129
long transaction_no_hint_count[MAX_NDB_NODES];
128130
long transaction_hint_count[MAX_NDB_NODES];
129131
long long api_client_stats[Ndb::NumClientStatistics];

sql/ndb_thd_ndb.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2011, 2014 Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -89,6 +89,10 @@ Thd_ndb::recycle_ndb(void)
8989
{
9090
ndb->setCustomData64(thd_get_thread_id(m_thd));
9191
}
92+
93+
/* Reset last commit epoch for this 'session'. */
94+
m_last_commit_epoch_session = 0;
95+
9296
DBUG_RETURN(true);
9397
}
9498

sql/ndb_thd_ndb.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2011, 2014 Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -135,6 +135,11 @@ class Thd_ndb
135135
uint schema_locks_count; // Number of global schema locks taken by thread
136136
bool has_required_global_schema_lock(const char* func);
137137

138+
/**
139+
Epoch of last committed transaction in this session, 0 if none so far
140+
*/
141+
Uint64 m_last_commit_epoch_session;
142+
138143
unsigned m_connect_count;
139144
bool valid_ndb(void) const;
140145
bool recycle_ndb(void);

0 commit comments

Comments
 (0)