Skip to content

Commit 945e59d

Browse files
AliSQLAliSQL
authored andcommitted
[feature] Issue #37: Support MTS distributing in table level
MySQL 5.6 introduce Multi-Threaded Slaves(MTS) which significantly improved replicating capability of slave. However, the original MTS only support distributing in schema level, which limits the parallelism of worker threads. For example, if all updates on master is under one schema, there will be only one worker applying events, and degenerate to signle thread replication. To solve this problem, we add a new distributing level, table mode. In the new mode, events can be distributing to different workers as long as different tables is involed. A new global option "slave_pr_mode" is introduced, which can be configured as: 1. schema, distributing in schema mode, same as origial; 2. table, distributing in table mode. Note: if changed dynamically, please remember to restart SQL thread, i.e. "stop slave sql_thread; start slave sql_thread", to make the changes take effect.
1 parent c39ebbc commit 945e59d

15 files changed

+132
-7
lines changed

mysql-test/r/mysqld--help-notwin.result

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,8 @@ The following options may be given as the first argument:
929929
Max size of Slave Worker queues holding yet not applied
930930
events.The least possible value must be not less than the
931931
master side max_allowed_packet.
932+
--slave-pr-mode=name
933+
Parallel-replication based on SCHEMA or TABLE
932934
--slave-rows-search-algorithms=name
933935
Set of searching algorithms that the slave will use while
934936
searching for records from the storage engine to either
@@ -1456,6 +1458,7 @@ slave-max-allowed-packet 1073741824
14561458
slave-net-timeout 3600
14571459
slave-parallel-workers 0
14581460
slave-pending-jobs-size-max 16777216
1461+
slave-pr-mode TABLE
14591462
slave-rows-search-algorithms TABLE_SCAN,INDEX_SCAN
14601463
slave-skip-errors (No default value)
14611464
slave-sql-verify-checksum TRUE
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
include/master-slave.inc
2+
Warnings:
3+
Note #### Sending passwords in plain text without SSL/TLS is extremely insecure.
4+
Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
5+
Warnings:
6+
Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop.
7+
[connection master]
8+
reset master;
9+
create table t1(c int) engine=innodb;
10+
create table t2(c int) engine=innodb;
11+
create table t3(c int) engine=innodb;
12+
insert into t1 values(1);
13+
insert into t2 values(2);
14+
insert into t3 values(3);
15+
insert into t2 values(2);
16+
stop slave;
17+
change master to master_auto_position=1;
18+
start slave;
19+
Warnings:
20+
Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop.
21+
stop slave;
22+
set global relay_log_info_repository='FILE';
23+
start slave;
24+
Warnings:
25+
Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop.
26+
insert into t3 values(3);
27+
drop table t3;
28+
drop table t2;
29+
drop table t1;
30+
stop slave;
31+
set global relay_log_info_repository='TABLE';
32+
change master to master_auto_position=0;
33+
start slave;
34+
Warnings:
35+
Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop.
36+
include/rpl_end.inc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--log-bin --gtid-mode=on --enforce-gtid-consistency --log-slave-updates --binlog_format=row
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--slave_pr_mode=TABLE --log-bin --gtid-mode=on --enforce-gtid-consistency --log-slave-updates --binlog_format=row --slave_parallel_workers=8 --master_info_repository=TABLE --relay_log_info_repository=TABLE
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--source include/have_log_bin.inc
2+
--source include/master-slave.inc
3+
connection master;
4+
reset master;
5+
create table t1(c int) engine=innodb;
6+
create table t2(c int) engine=innodb;
7+
create table t3(c int) engine=innodb;
8+
insert into t1 values(1);
9+
insert into t2 values(2);
10+
insert into t3 values(3);
11+
insert into t2 values(2);
12+
13+
connection slave;
14+
stop slave;
15+
change master to master_auto_position=1;
16+
start slave;
17+
18+
connection master;
19+
--sync_slave_with_master
20+
21+
stop slave;
22+
set global relay_log_info_repository='FILE';
23+
24+
start slave;
25+
connection master;
26+
insert into t3 values(3);
27+
drop table t3;
28+
drop table t2;
29+
drop table t1;
30+
--sync_slave_with_master
31+
stop slave;
32+
set global relay_log_info_repository='TABLE';
33+
change master to master_auto_position=0;
34+
start slave;
35+
--source include/rpl_end.inc
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
--slave-transaction-retries=0 --relay-log-info-repository=TABLE --master-info-repository=TABLE
1+
--slave-transaction-retries=0 --relay-log-info-repository=TABLE --master-info-repository=TABLE --slave_pr_mode=schema

mysql-test/suite/sys_vars/r/all_vars.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ RDS_THREADS_RUNNING_CTL_MODE
5656
RDS_THREADS_RUNNING_CTL_MODE
5757
RDS_THREADS_RUNNING_HIGH_WATERMARK
5858
RDS_THREADS_RUNNING_HIGH_WATERMARK
59+
SLAVE_PR_MODE
60+
SLAVE_PR_MODE
5961
TOKUDB_ALTER_PRINT_ERROR
6062
TOKUDB_ALTER_PRINT_ERROR
6163
TOKUDB_ANALYZE_DELETE_FRACTION

sql/log_event.cc

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,6 +2616,8 @@ Log_event::continue_group(Relay_log_info *rli)
26162616
/**
26172617
@param end_group_sets_max_dbs when true the group terminal event
26182618
can carry partition info, see a note below.
2619+
@param rli relay log info
2620+
26192621
@return true in cases the current event
26202622
carries partition data,
26212623
false otherwise
@@ -2627,9 +2629,11 @@ Log_event::continue_group(Relay_log_info *rli)
26272629
assigning OVER_MAX_DBS_IN_EVENT_MTS to mts_accessed_dbs
26282630
of COMMIT query event.
26292631
*/
2630-
bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2632+
bool Log_event::contains_partition_info(bool end_group_sets_max_dbs,
2633+
Relay_log_info *rli)
26312634
{
26322635
bool res;
2636+
bool table_mode = (rli->pr_mode == SLAVE_PR_MODE_TABLE);
26332637

26342638
switch (get_type_code()) {
26352639
case TABLE_MAP_EVENT:
@@ -2645,6 +2649,16 @@ bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
26452649
static_cast<Query_log_event*>(this)->mts_accessed_dbs=
26462650
OVER_MAX_DBS_IN_EVENT_MTS;
26472651
}
2652+
else if (table_mode && (!starts_group() && !ends_group()))
2653+
{
2654+
/*
2655+
In table mode MTS replication, all query event is executed
2656+
serially by worker 0.
2657+
*/
2658+
res= true;
2659+
static_cast<Query_log_event*>(this)->mts_accessed_dbs=
2660+
OVER_MAX_DBS_IN_EVENT_MTS;
2661+
}
26482662
else
26492663
res= (!ends_group() && !starts_group()) ? true : false;
26502664

@@ -2776,7 +2790,7 @@ Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
27762790

27772791
// mini-group representative
27782792

2779-
if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
2793+
if (contains_partition_info(rli->mts_end_group_sets_max_dbs, rli))
27802794
{
27812795
int i= 0;
27822796
Mts_db_names mts_dbs;
@@ -2830,9 +2844,24 @@ Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
28302844
to satisfy hashcmp() implementation.
28312845
*/
28322846
const char all_db[NAME_LEN]= {0};
2847+
2848+
char map_key[NAME_LEN * 2 + 3] = {0};
2849+
2850+
if (mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS)
2851+
{
2852+
if (get_type_code() == TABLE_MAP_EVENT &&
2853+
rli->pr_mode == SLAVE_PR_MODE_TABLE)
2854+
{
2855+
Table_map_log_event *ev= (Table_map_log_event *) this;
2856+
ev->set_full_name(map_key);
2857+
}
2858+
else
2859+
strcpy(map_key, mts_dbs.name[i]);
2860+
}
2861+
28332862
if (!(ret_worker=
28342863
map_db_to_worker(mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS ?
2835-
all_db : mts_dbs.name[i], rli,
2864+
all_db : map_key, rli,
28362865
&mts_assigned_partitions[i],
28372866
/*
28382867
todo: optimize it. Although pure
@@ -2851,7 +2880,7 @@ Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
28512880
DBUG_ASSERT(mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
28522881
DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db,
28532882
mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS ?
2854-
mts_dbs.name[i] : all_db));
2883+
map_key : all_db));
28552884
DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
28562885
DBUG_ASSERT(mts_assigned_partitions[i]->usage >= 0);
28572886
}

sql/log_event.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ class Log_event
15171517
/**
15181518
@return TRUE if events carries partitioning data (database names).
15191519
*/
1520-
bool contains_partition_info(bool);
1520+
bool contains_partition_info(bool, Relay_log_info*);
15211521

15221522
/*
15231523
@return the number of updated by the event databases.
@@ -3902,6 +3902,10 @@ class Table_map_log_event : public Log_event
39023902
const Table_id& get_table_id() const { return m_table_id; }
39033903
const char *get_table_name() const { return m_tblnam; }
39043904
const char *get_db_name() const { return m_dbnam; }
3905+
void set_full_name(char *buf)
3906+
{
3907+
sprintf(buf, "%s\1%s", m_dbnam, m_tblnam);
3908+
}
39053909

39063910
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
39073911
virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }

sql/mysqld.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ bool thread_cache_size_specified= false;
551551
bool host_cache_size_specified= false;
552552
bool table_definition_cache_specified= false;
553553
my_bool opt_rds_allow_unsafe_stmt_with_gtid= FALSE;
554+
ulong slave_pr_mode_options;
554555

555556
my_bool ic_reduce_hint_enable= 0;
556557
HASH ic_gather_hash;

0 commit comments

Comments
 (0)