1. 历史
5.7.17+以后,出现的组复制技术。MySQL Group Replication。
为了复制环境中,数据一致性考虑、多写的场景研发的技术。
2. 架构原理
在2N+1个节点组成的单主模式组复制集群中,主库上一个事务提交时,会将事务修改记录相关的信息和
事务产生的BINLOG事件打包生成一个写集(WRITE SET),将写集发送给所有节点,并通过至少N个节
点投票通过才能事务提交成功。
在事务执行期间,会将:
1、事务操作生成的map event/query event/dml event等写入BINLOG CACHE中(内存)
2、将Write Set写入到Rpl_transaction_write_set_ctx中(内存)
在事务提交时,具体在MYSQL_BIN_LOG::prepare之后,但是在
MYSQL_BIN_LOG::ordered_commit之前,即事务相关的BINLOG Event还在BINLOG CACHE没有
写入到BINLOG FILE前,将BINLOG CACHE中和Rpl_transaction_write_set_ctx中的数据进行
处理并写入到transaction_msg中,由gcs_module负责发送transaction_msg到各个节点,等待
各节点进行事务认证。
由于transaction_msg中包含BINLOG信息,并在事务认证期间发送给MGR各节点,因此无需等待主节
点的BINLOG落盘后再发送给备用节点。
每个MGR群集中的节点上,都存在IO线程和SQL线程,IO线程会解析transaction_msg获取到BINLOG
EVENT并保存到RELAY LOG中,再由SQL线程执行重放到辅助节点上。
总结:
single-primary:
begin;
update t1 set name=‘zs’ where id=10;
commit;
1. 主库发生新的事务,事务执行期间,会将事务binlog 刷到binlog cache。
2. 生成write_set ,包含binlog日志+表、库hash值。写入
Rpl_transaction_write_set_ctx。
3. MYSQL_BIN_LOG::prepare之后,在MYSQL_BIN_LOG::ordered_commit之前
通过gcs_module将所有的Rpl_transaction_write_set_ctx,以transaction_msg传输
给各个节点。
4. 通过certify验证(Paxos),通过投票机制,判断此次事务是否满足半数以上节点通过(不
冲突)。
5. 主库binlog flush && sync disk
6. 此时,各个从库开始回放relaylog。
3.安装搭建
3.1 主节点
[client]
port = 3306
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysql]
prompt="\u@\h \R:\m:\s [\d]> "
no-auto-rehash
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysqld]
user = mysql
port = 3306
admin_address = 127.0.0.1
basedir = /usr/local/mysql
datadir = /data/mysql/mysql_3306/data
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
pid-file = mysql_3306.pid
character-set-server = utf8mb4
secure-file-priv=/tmp
skip_name_resolve = 1
lower_case_table_names = 1
report_host=10.0.0.57
report_port=3306
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="ca842376-1c50-42ac-bb57-a5adc7da7a12"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "10.0.0.57:33067"
loose-group_replication_group_seeds="10.0.0.51:33067,10.0.0.52:33068,10.0.0.53:33069"
loose-group_replication_bootstrap_group=OFF
#replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
# Two-Master configure
#server-1
#auto-increment-offset = 1
#auto-increment-increment = 2
#server-2
#auto-increment-offset = 2
#auto-increment-increment = 2
# semi sync replication settings #
#plugin_dir = /usr/local/mysql/lib/mysql/plugin
#plugin_load = "validate_password.so;rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
plugin_dir = /usr/local/mysql/lib/plugin #官方版本的路径
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" #官方版本的路径
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
open_files_limit = 65535
back_log = 1024
max_connections = 1024
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
table_open_cache_instances = 64
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 4M
join_buffer_size = 4M
thread_cache_size = 1536
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
slow_query_log = 1
log_timestamps = SYSTEM
slow_query_log_file = /data/mysql/mysql_3306/logs/slow.log
log-error = /data/mysql/mysql_3306/logs/error.log
long_query_time = 0.1
log_queries_not_using_indexes =1
log_throttle_queries_not_using_indexes = 60
min_examined_row_limit = 100
log_slow_admin_statements = 1
log_slow_slave_statements = 1
server-id = 1
log-bin = /data/mysql/mysql_3306/logs/mysql-bin
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
binlog_expire_logs_seconds=2592000
master_info_repository = TABLE
relay_log_info_repository = TABLE
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates
slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
binlog_format = ROW
binlog_row_image=FULL
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
#myisam_repair_threads = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
innodb_thread_concurrency = 0
innodb_sync_spin_loops = 100
innodb_spin_wait_delay = 30
#transaction_isolation = REPEATABLE-READ
transaction_isolation = READ-COMMITTED
#innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 2867M
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 3
innodb_max_undo_log_size = 4G
innodb_undo_directory = /data/mysql/mysql_3306/undolog
innodb_undo_tablespaces = 95
# 根据您的服务器IOPS能力适当调整
# 一般配普通SSD盘的话,可以调整到 10000 - 20000
# 配置高端PCIe SSD卡的话,则可以调整的更高,比如 50000 - 80000
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_flush_sync = 0
innodb_flush_neighbors = 0
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_purge_threads = 4
innodb_page_cleaners = 4
innodb_open_files = 65535
innodb_max_dirty_pages_pct = 50
innodb_flush_method = O_DIRECT
innodb_lru_scan_depth = 4000
innodb_checksum_algorithm = crc32
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_file_per_table = 1
innodb_online_alter_log_max_size = 4G
innodb_stats_on_metadata = 0
# some var for MySQL 8
log_error_verbosity = 3
innodb_print_ddl_logs = 1
binlog_expire_logs_seconds = 2592000
#innodb_dedicated_server = 0
innodb_status_file = 1
# 注意: 开启 innodb_status_output & innodb_status_output_locks 后, 可能会导致log-error文件增长较快
innodb_status_output = 0
innodb_status_output_locks = 0
#performance_schema
performance_schema = 1
performance_schema_instrument = '%memory%=on'
performance_schema_instrument = '%lock%=on'
#innodb monitor
innodb_monitor_enable="module_innodb"
innodb_monitor_enable="module_server"
innodb_monitor_enable="module_dml"
innodb_monitor_enable="module_ddl"
innodb_monitor_enable="module_trx"
innodb_monitor_enable="module_os"
innodb_monitor_enable="module_purge"
innodb_monitor_enable="module_log"
innodb_monitor_enable="module_lock"
innodb_monitor_enable="module_buffer"
innodb_monitor_enable="module_index"
innodb_monitor_enable="module_ibuf_system"
innodb_monitor_enable="module_buffer_page"
innodb_monitor_enable="module_adaptive_hash"
[mysqldump]
quick
max_allowed_packet = 32M
[mysqld_safe]
#malloc-lib=/usr/local/mysql/lib/jmalloc.so
nice=-19
open-files-limit=65535
3.2 从1
[client]
port = 3306
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysql]
prompt="\u@\h \R:\m:\s [\d]> "
no-auto-rehash
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysqld]
user = mysql
port = 3306
admin_address = 127.0.0.1
basedir = /usr/local/mysql
datadir = /data/mysql/mysql_3306/data
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
pid-file = mysql_3306.pid
character-set-server = utf8mb4
skip_name_resolve = 1
lower_case_table_names = 1
secure-file-priv=/tmp
report_host=10.0.0.58
report_port=3306
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="ca842376-1c50-42ac-bb57-a5adc7da7a12"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "10.0.0.58:33068"
loose-group_replication_group_seeds="10.0.0.57:33067,10.0.0.58:33068,10.0.0.59:33069"
loose-group_replication_bootstrap_group=OFF
#replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
# Two-Master configure
#server-1
#auto-increment-offset = 1
#auto-increment-increment = 2
#server-2
#auto-increment-offset = 2
#auto-increment-increment = 2
# semi sync replication settings #
#plugin_dir = /usr/local/mysql/lib/mysql/plugin
#plugin_load = "validate_password.so;rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
plugin_dir = /usr/local/mysql/lib/plugin #官方版本的路径
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" #官方版本的路径
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
open_files_limit = 65535
back_log = 1024
max_connections = 1024
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
table_open_cache_instances = 64
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 4M
join_buffer_size = 4M
thread_cache_size = 1536
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
slow_query_log = 1
log_timestamps = SYSTEM
slow_query_log_file = /data/mysql/mysql_3306/logs/slow.log
log-error = /data/mysql/mysql_3306/logs/error.log
long_query_time = 0.1
log_queries_not_using_indexes =1
log_throttle_queries_not_using_indexes = 60
min_examined_row_limit = 100
log_slow_admin_statements = 1
log_slow_slave_statements = 1
server-id = 2
log-bin = /data/mysql/mysql_3306/logs/mysql-bin
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
binlog_expire_logs_seconds=2592000
master_info_repository = TABLE
relay_log_info_repository = TABLE
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates
slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
binlog_format = ROW
binlog_row_image=FULL
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
#myisam_repair_threads = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
innodb_thread_concurrency = 0
innodb_sync_spin_loops = 100
innodb_spin_wait_delay = 30
#transaction_isolation = REPEATABLE-READ
transaction_isolation = READ-COMMITTED
#innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 2867M
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 3
innodb_max_undo_log_size = 4G
innodb_undo_directory = /data/mysql/mysql_3306/undolog
innodb_undo_tablespaces = 95
# 根据您的服务器IOPS能力适当调整
# 一般配普通SSD盘的话,可以调整到 10000 - 20000
# 配置高端PCIe SSD卡的话,则可以调整的更高,比如 50000 - 80000
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_flush_sync = 0
innodb_flush_neighbors = 0
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_purge_threads = 4
innodb_page_cleaners = 4
innodb_open_files = 65535
innodb_max_dirty_pages_pct = 50
innodb_flush_method = O_DIRECT
innodb_lru_scan_depth = 4000
innodb_checksum_algorithm = crc32
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_file_per_table = 1
innodb_online_alter_log_max_size = 4G
innodb_stats_on_metadata = 0
# some var for MySQL 8
log_error_verbosity = 3
innodb_print_ddl_logs = 1
binlog_expire_logs_seconds = 2592000
#innodb_dedicated_server = 0
innodb_status_file = 1
# 注意: 开启 innodb_status_output & innodb_status_output_locks 后, 可能会导致log-error文件增长较快
innodb_status_output = 0
innodb_status_output_locks = 0
#performance_schema
performance_schema = 1
performance_schema_instrument = '%memory%=on'
performance_schema_instrument = '%lock%=on'
#innodb monitor
innodb_monitor_enable="module_innodb"
innodb_monitor_enable="module_server"
innodb_monitor_enable="module_dml"
innodb_monitor_enable="module_ddl"
innodb_monitor_enable="module_trx"
innodb_monitor_enable="module_os"
innodb_monitor_enable="module_purge"
innodb_monitor_enable="module_log"
innodb_monitor_enable="module_lock"
innodb_monitor_enable="module_buffer"
innodb_monitor_enable="module_index"
innodb_monitor_enable="module_ibuf_system"
innodb_monitor_enable="module_buffer_page"
innodb_monitor_enable="module_adaptive_hash"
[mysqldump]
quick
max_allowed_packet = 32M
[mysqld_safe]
#malloc-lib=/usr/local/mysql/lib/jmalloc.so
nice=-19
open-files-limit=65535
3.3 从2
[client]
port = 3306
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysql]
prompt="\u@\h \R:\m:\s [\d]> "
no-auto-rehash
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
[mysqld]
user = mysql
port = 3306
admin_address = 127.0.0.1
basedir = /usr/local/mysql
datadir = /data/mysql/mysql_3306/data
socket = /data/mysql/mysql_3306/tmp/mysql_3306.sock
pid-file = mysql_3306.pid
character-set-server = utf8mb4
skip_name_resolve = 1
lower_case_table_names = 1
secure-file-priv=/tmp
report_host=10.0.0.59
report_port=3306
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
binlog_transaction_dependency_tracking = WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="ca842376-1c50-42ac-bb57-a5adc7da7a12"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "10.0.0.59:33069"
loose-group_replication_group_seeds="10.0.0.57:33067,10.0.0.58:33068,10.0.0.59:33069"
loose-group_replication_bootstrap_group=OFF
#replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
# Two-Master configure
#server-1
#auto-increment-offset = 1
#auto-increment-increment = 2
#server-2
#auto-increment-offset = 2
#auto-increment-increment = 2
# semi sync replication settings #
#plugin_dir = /usr/local/mysql/lib/mysql/plugin
#plugin_load = "validate_password.so;rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
plugin_dir = /usr/local/mysql/lib/plugin #官方版本的路径
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so" #官方版本的路径
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
open_files_limit = 65535
back_log = 1024
max_connections = 1024
max_connect_errors = 1000000
table_open_cache = 1024
table_definition_cache = 1024
table_open_cache_instances = 64
thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 4M
join_buffer_size = 4M
thread_cache_size = 1536
interactive_timeout = 600
wait_timeout = 600
tmp_table_size = 32M
max_heap_table_size = 32M
slow_query_log = 1
log_timestamps = SYSTEM
slow_query_log_file = /data/mysql/mysql_3306/logs/slow.log
log-error = /data/mysql/mysql_3306/logs/error.log
long_query_time = 0.1
log_queries_not_using_indexes =1
log_throttle_queries_not_using_indexes = 60
min_examined_row_limit = 100
log_slow_admin_statements = 1
log_slow_slave_statements = 1
server-id = 3306
log-bin = /data/mysql/mysql_3306/logs/mysql-bin
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
binlog_expire_logs_seconds=2592000
master_info_repository = TABLE
relay_log_info_repository = TABLE
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates
slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
binlog_format = ROW
binlog_row_image=FULL
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1
key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 4M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
#myisam_repair_threads = 1
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1
innodb_thread_concurrency = 0
innodb_sync_spin_loops = 100
innodb_spin_wait_delay = 30
#transaction_isolation = REPEATABLE-READ
transaction_isolation = READ-COMMITTED
#innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 2867M
innodb_buffer_pool_instances = 4
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
innodb_log_file_size = 2G
innodb_log_files_in_group = 3
innodb_max_undo_log_size = 4G
innodb_undo_directory = /data/mysql/mysql_3306/undolog
innodb_undo_tablespaces = 95
# 根据您的服务器IOPS能力适当调整
# 一般配普通SSD盘的话,可以调整到 10000 - 20000
# 配置高端PCIe SSD卡的话,则可以调整的更高,比如 50000 - 80000
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_flush_sync = 0
innodb_flush_neighbors = 0
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_purge_threads = 4
innodb_page_cleaners = 4
innodb_open_files = 65535
innodb_max_dirty_pages_pct = 50
innodb_flush_method = O_DIRECT
innodb_lru_scan_depth = 4000
innodb_checksum_algorithm = crc32
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_file_per_table = 1
innodb_online_alter_log_max_size = 4G
innodb_stats_on_metadata = 0
# some var for MySQL 8
log_error_verbosity = 3
innodb_print_ddl_logs = 1
binlog_expire_logs_seconds = 2592000
#innodb_dedicated_server = 0
innodb_status_file = 1
# 注意: 开启 innodb_status_output & innodb_status_output_locks 后, 可能会导致log-error文件增长较快
innodb_status_output = 0
innodb_status_output_locks = 0
#performance_schema
performance_schema = 1
performance_schema_instrument = '%memory%=on'
performance_schema_instrument = '%lock%=on'
#innodb monitor
innodb_monitor_enable="module_innodb"
innodb_monitor_enable="module_server"
innodb_monitor_enable="module_dml"
innodb_monitor_enable="module_ddl"
innodb_monitor_enable="module_trx"
innodb_monitor_enable="module_os"
innodb_monitor_enable="module_purge"
innodb_monitor_enable="module_log"
innodb_monitor_enable="module_lock"
innodb_monitor_enable="module_buffer"
innodb_monitor_enable="module_index"
innodb_monitor_enable="module_ibuf_system"
innodb_monitor_enable="module_buffer_page"
innodb_monitor_enable="module_adaptive_hash"
[mysqldump]
quick
max_allowed_packet = 32M
[mysqld_safe]
#malloc-lib=/usr/local/mysql/lib/jmalloc.so
nice=-19
open-files-limit=65535
3.3 实现单主模式
初始化
/usr/local/mysql/bin/mysqld --defaults-file=/data/mysql/mysql_3306/my_3306.cnf --initialize-insecure --lower-case-table-names=1 --user=mysql
启动
/usr/local/mysql/bin/mysqld_safe --defaults-file=/data/mysql/mysql_3306/my_3306.cnf &
设置本地root用户密码和密码插件(所有节点)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED
-> WITH mysql_native_password BY '123';
安装MGR插件(所有节点)
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
设置复制账号(所有节点)
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY '123';
CREATE USER repl@'localhost' IDENTIFIED BY '123';
CREATE USER repl@'127.0.0.1' IDENTIFIED BY '123';
GRANT REPLICATION SLAVE,replication client ON *.* TO repl@'%';
grant replication slave,replication client on *.* to repl@'localhost' ;
grant replication slave,replication client on *.* to repl@'127.0.0.1' ;
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
j. 启动MGR单主模式
# 启动MGR,在主库(10.0.0.57)上执行
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL
'group_replication_recovery';
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
SELECT * FROM performance_schema.replication_group_members;
其他节点加入MGR,在从库上执行
reset master;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;
查看MGR组信息(主库查看)
SELECT * FROM performance_schema.replication_group_members;
可以看到,3个节点状态为online,并且主节点为192.168.56.101,只有主节点可以写入,其
他节点只读,MGR单主模式搭建成功。
如果需要重置,那么需要执行如下命令:
STOP GROUP_REPLICATION;
reset master;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
start GROUP_REPLICATION;
3.4 切换到多主模式
MGR切换模式需要重新启动组复制,因些需要在所有节点上先关闭组复制,设置
group_replication_single_primary_mode=OFF 等参数,再启动组复制。
1、该模式启用需设置两个参数
group_replication_single_primary_mode=0 #这个参数很好理解,就是关闭单master模式
group_replication_enforce_update_everywhere_checks=1 #这个参数设置多主模式下各
个节点严格一致性检查
================
db02 [(none)]>stop GROUP_REPLICATION;
db02 [(none)]>set global group_replication_single_primary_mode=OFF;
db02 [(none)]>set global group_replication_enforce_update_everywhere_checks=1;
db03 [(none)]>stop GROUP_REPLICATION;
db03 [(none)]>set global group_replication_single_primary_mode=OFF;
db03 [(none)]>set global group_replication_enforce_update_everywhere_checks=1;
select @@group_replication_single_primary_mode,@@group_replication_enforce_update_everywhere_checks;
===============
2、 默认启动的都是单master模式,其他节点都设置了read_only、super_read_only这两个参
数,需要修改这两个配置
===========
db03 [(none)]>set global read_only=0;
db03 [(none)]>set global super_read_only=0;
===========
3、 完成上面的配置后就可以执行多点写入了,多点写入会存在冲突检查,这耗损性能挺大的,官方
建议采用网络分区功能,在程序端把相同的业务定位到同一节点,尽量减少冲突发生几率。
# 停止组复制(所有节点执行):
stop group_replication;
set global group_replication_single_primary_mode=OFF;
set global group_replication_enforce_update_everywhere_checks=ON;
# 随便选择某个节点执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
# 其他节点执行
START GROUP_REPLICATION;
# 查看组信息,所有节点的 MEMBER_ROLE 都为 PRIMARY,
SELECT * FROM performance_schema.replication_group_members;
切回单主模式
# 所有节点执行
stop group_replication;
set global group_replication_enforce_update_everywhere_checks=OFF;
set global group_replication_single_primary_mode=ON;
# 主节点执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
# 从节点执行
START GROUP_REPLICATION;
# 查看MGR组信息,SELECT * FROM performance_schema.replication_group_members;
4.运维
4.1 MGR的监控
SELECT * FROM performance_schema.replication_group_members;
4.2 MGR故障处理
1. 宕掉主节点测试。-->自动切换,类似、MHA ,切换过程中所有节点为只读
db02 [(none)]>SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 0a10985b-4183-11ee-a843-000c2917e898 | 10.0.0.58 | 3306 | ONLINE | PRIMARY | 8.0.30 | XCom |
| group_replication_applier | fe9e2ab7-4183-11ee-a8d7-000c29f7dccf | 10.0.0.59 | 3306 | ONLINE | SECONDARY | 8.0.30 | XCom |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
2 rows in set (0.00 sec)
2. 启动主节点-->不会自动加入到集群中
db02 [(none)]>SELECT * FROM performance_schema.replication_group_members;
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | | | NULL | OFFLINE | | | |
+---------------------------+-----------+-------------+-------------+--------------+-------------+----------------+----------------------------+
1 row in set (0.00 sec)
3. 宕机后添加到集群
3.1 clone plugin 克隆目前主库数据
主库:
[root@db01 ~]# mysql -uroot -p123 -S /data/mysql/mysql_3306/tmp/mysql_3306.sock -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so';create user test@'%' identified by '123';grant backup_admin on *.* to test@'%';"
mysql: [Warning] Using a password on the command line interface can be insecure
宕掉的从库
mysql -uroot -p123 -S /data/mysql/mysql_3306/tmp/mysql_3306.sock -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so';create user test1@'%' identified by '123';grant clone_admin on *.* to test1@'%';SET GLOBAL clone_valid_donor_list='10.0.0.58:3306';"
mysql -utest1 -p123 -h10.0.0.57 -P3306 -e "CLONE INSTANCE FROM test@'10.0.0.58':3306 IDENTIFIED BY '123';"
宕机的库加入集群
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;
4.3 MGR的限制
1. 仅支持innodb存储引擎
MGR集群中,只支持innodb存储引擎,能够创建非innodb引擎的表,但是无法写入数据,向非innodb表写数据直接报错。
2. 表必须有主键,或者非Null的唯一键
MGR集群中,只支持innodb引擎的表,并且该表必须有显式的主键,或者非Null的唯一键,否则即使能够创建表,也无法向表中写入数据。
3. 网络限制
MGR 组通信引擎目前仅支持IPv4网络,并且对节点间的网络性能要求较高,低延迟、高带宽的网络是
部署MGR集群的基础。
4. MGR忽略表锁和命名锁,在MGR中lock tables、unlock tables、get_lock、release_lock等这些表锁和命名锁将被忽略。
5. MGR多主模式中,默认不支持 SERIALIZABLE 隔离级别。建议使用RC。
6. 多主模式下,对同一个对象进行并发的有冲突的ddl和dml操作导致这种冲突在部分成员节点中无法检测到,最终可能导致数据不一致。
7. 多主模式下,不支持级联约束的外键,可能造成有冲突的操作无法检测。
8. 不支持超大事务。
9. 多主模式下可能导致死锁,比如select ...for update在不同节点执行,由于多节点锁无法共享,很容易导致死锁。
10.不支持复制过滤,如果有节点设置了复制过滤,将影响节点间决议的达成。
11. MGR最多支持9个节点,大于9个节点,将拒绝新节点的加入。
MGR在8.0版本读写一致性保证
MGR相对于半同步复制,在relay log前增加了冲突检查协调,但是binlog回放仍然可能延时,也就是跟我们熟悉的半同步复制存在SQL线程的回放延迟情况类似。当然关于SQL线程回放慢的原因,跟半同步
也类似,比如大事务!!
所以MGR并不是全同步方案,关于如何处理一致性读写的问题,MySQL 在8.0.14版本中加入了“读写一致性”特性,并引入了参数:group_replication_consistency,下面将对读写一致性的相关参数及
不同应用场景进行详细说明。
MGR读写一致性的优缺点
官方引入的MGR读写一致性既有它自身的天然优势,也不可避免的存在相应的不足,其优缺点如下:
优点:MGR配合中间件,比如读写分离功能的中间件,在MGR单主模式下,可以根据业务场景进行读写分离,不用担心会产生延迟,充分利用了MGR主节点以外的节点。
缺点:使用读写一致性会对性能有极大影响,尤其是网络环境不稳定的场景下。
在实际应用中需要大家因地制宜,根据实际情况选择最适配的方案
MGR读写一致性的方案
针对不同应用场景应当如何选择MGR读写一致性的相关方式,官方提供了几个参数以及与其相对应的应
用场景:
AFTER
适用场景1:写少读多的场景进行读写分离,担心读取到过期事务,可选择AFTER。
适用场景2:只读为主的集群,有RW的事务需要保证提交的事务能被其他后序事务读到最新读数据,可
选择AFTER。
BEFORE
适用场景1:应用大量写入数据,偶尔进行读取一致性数据,应当选择BEFORE。
适用场景2:有特定事务需要读写一致性,以便对敏感数据操作时,始终读取最新的数据;应当选择
BEFORE。
BEFORE_AND_AFTER
适用场景:有一个读为主的集群,有RW的事务既要保证读到最新的数据,又要保证这个事务提交后,被
其他后序事务读到;在这种情况下可选择BEFORE_AND_AFTER。
4.4 故障案例
MGR环境下要求每个表都需要有主键,没有主键就会报错。
MGR 在生成binlog前,先去从节点做校验,能不能执行,或者提交
binlog 刷盘之前,对别的节点进行校验