提示:本博文演示环境是基于centos7.2 x86_64位,最小化安装系统,MariaDB.10.5.1二进制安装来进行的
一、简单介绍下slave库的并行复制模式
slave_parallel_mode的 slave并行复制的5种模式:
官方给的5种模式
Description: Controls what transactions are applied in parallel when using parallel replication.
optimistic: tries to apply most transactional DML in parallel, and handles any conflicts with rollback and retry. See optimistic mode.
conservative: limits parallelism in an effort to avoid any conflicts. See conservative mode.
aggressive: tries to maximize the parallelism, possibly at the cost of increased conflict rate.
minimal: only parallelizes the commit steps of transactions.
none: disables parallel apply completely.
in-order 有序并行复制的optimistic乐观模式为在slave上并行应用提供了很多机会,同时从应用程序的角度来看,仍然保留精确的事务语义。这是MariaDB 10.5.1中的默认模式
二、master_use_gtid 参数说明:
配置主从复制时, CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no } 这3个参数介绍:
2.1、CHANGE MASTER TO master_use_gtid=slave_pos 介绍:
假如:
A slave is configured to use GTID by CHANGE MASTER TO master_use_gtid=slave_pos
当slave从站连接到master主站时,它将在复制到从站的最后一个GTID的位置开始复制,这可以在变量gtid_slave_pos中看到。由于所有复制服务器上的GTID均相同,因此可以将从属服务器指向其他主服务器,并自动确定正确的位置。
如果不希望更改从属服务器上的binlog会影响GTID复制位置,则应使用master_use_gtid = slave_pos。然后,从站将始终在最后复制的GTID位置连接到主站。
对于期望与传统复制保持一致行为的用户来说,这可以避免一些意外,因为复制位置永远不会因服务器上进行的本地更改而改变
如果在从站上写入任何本地事务,则在使用值current_pos时可能会遇到问题。例如,如果在slave从属线程停止时发出INSERT语句或以其他方式写入表,则可能在gtid_binlog_pos中生成新的本地GTID,这将影响从属的gtid_current_pos值。重新启动从属线程时,这可能会导致错误,因为主控制器将不存在本地GTID。您可以通过将MASTER_USE_GTID复制参数设置为slave_pos而不是current_pos来纠正此问题。
重要提示:下面3种场景的演示环境: centos7.2_x86_64位 MariaDB.10.5.1 二进制安装
mgr01 172.16.0.130 master
mgr03 172.16.0.131 slave
1.场景1:当线上的master库运行了一段时间,而且数据库的数据很少。针对此场景给master库部署一个全新的slave库
mgr03启动后默认情况下GTID位点都是空的,尤其是gtid_slave_pos 这个是空的
([email protected]‘mgr03‘:mysql.sock)[(none)]>show variables like ‘Gtid%‘;
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| gtid_binlog_pos | |
| gtid_binlog_state | |
| gtid_cleanup_batch_size | 64 |
| gtid_current_pos | |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_pos_auto_engines | |
| gtid_seq_no | 0 |
| gtid_slave_pos | |
| gtid_strict_mode | OFF |
+-------------------------+-------+
10 rows in set (0.00 sec)
([email protected]‘mgr03‘:mysql.sock)[(none)]>ALTER USER ‘root‘@‘localhost‘ IDENTIFIED BY ‘123456‘;
Query OK, 0 rows affected (0.02 sec)
([email protected]‘mgr03‘:mysql.sock)[(none)]>show variables like ‘Gtid%‘;
+-------------------------+-------------+
| Variable_name | Value |
+-------------------------+-------------+
| gtid_binlog_pos | 0-1313306-1 |
| gtid_binlog_state | 0-1313306-1 |
| gtid_cleanup_batch_size | 64 |
| gtid_current_pos | 0-1313306-1 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_pos_auto_engines | |
| gtid_seq_no | 0 |
| gtid_slave_pos | |
| gtid_strict_mode | OFF |
+-------------------------+-------------+
10 rows in set (0.01 sec)
master操作:
提示:reset master 这一步操作不是必须的,除非在这个库之前,此数据库做过别的集群的slave库。尤其是在master库上,严禁此操作,除非你清楚的知道自己在干什么
mysql -e "grant replication slave on *.* to [email protected]‘172.16.0.%‘ identified by ‘JuwoSdk21TbUser‘; flush privileges;"
mysqldump -uroot -p‘123456‘ -B -A -F --master-data=2 --single-transaction --events|gzip >test.sql.gz
scp -rp -P52110 /opt/tes.sql.gz [email protected]:/root
slave操作:
([email protected]‘mgr03‘:mysql.sock)[test]>source /root/test.sql
CHANGE MASTER TO MASTER_HOST=‘mgr01‘,MASTER_PORT=3306,MASTER_USER=‘repuser‘,MASTER_PASSWORD=‘JuwoSdk21TbUser‘,master_use_gtid=slave_pos;start slave;show slave status\G
2.场景2: 当线上的master库运行了一段时间,而且数据库的数据很少。针对此场景给master库部署一个slave库。但是这个新slave库之前有做过其他的项目的主库
那么初始位置需要手动设置为空:SET GLOBAL gtid_slave_pos = "";
mgr01-master :
当前gtid情况:
[email protected] [test]>show variables like ‘Gtid%‘;
+-------------------------+--------------+
| Variable_name | Value |
+-------------------------+--------------+
| gtid_binlog_pos | 0-1283306-50 |
| gtid_binlog_state | 0-1283306-50 |
| gtid_cleanup_batch_size | 64 |
| gtid_current_pos | 0-1283306-50 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_pos_auto_engines | |
| gtid_seq_no | 0 |
| gtid_slave_pos | 0-1313306-41 |
| gtid_strict_mode | OFF |
+-------------------------+--------------+
10 rows in set (0.001 sec)
mgr03-slave:
当前gtid情况:
([email protected]‘mgr03‘:mysql.sock)[test]>show variables like ‘Gtid%‘;
+-------------------------+---------------------------+
| Variable_name | Value |
+-------------------------+---------------------------+
| gtid_binlog_pos | 0-1313306-45 |
| gtid_binlog_state | 0-1283306-42,0-1313306-45 |
| gtid_cleanup_batch_size | 64 |
| gtid_current_pos | 0-1313306-45 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_pos_auto_engines | |
| gtid_seq_no | 0 |
| gtid_slave_pos | 0-1283306-42 |
| gtid_strict_mode | OFF |
+-------------------------+---------------------------+
10 rows in set (0.00 sec)
具体操作:
master操作:
mysql -e "grant replication slave on *.* to [email protected]‘172.16.0.%‘ identified by ‘JuwoSdk21TbUser‘; flush privileges;"
mysqldump -uroot -p‘123456‘ -B -A -F --master-data=2 --single-transaction --events|gzip >test.sql.gz
scp -rp -P52110 /opt/test.sql.gz [email protected]:/root
slave操作:
([email protected]‘mgr03‘:mysql.sock)[test]>source /root/test.sql
([email protected]‘mgr03‘:mysql.sock)[test]>reset master ;
([email protected]‘mgr03‘:mysql.sock)[test]>stop slave;
Query OK, 0 rows affected (0.12 sec)
([email protected]‘mgr03‘:mysql.sock)[test]>reset slave all;
([email protected]‘mgr03‘:mysql.sock)[test]>SET GLOBAL gtid_slave_pos = "";
Query OK, 0 rows affected (0.03 sec)
([email protected]‘mgr03‘:mysql.sock)[test]>show variables like ‘Gtid%‘;
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| gtid_binlog_pos | |
| gtid_binlog_state | |
| gtid_cleanup_batch_size | 64 |
| gtid_current_pos | |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_pos_auto_engines | |
| gtid_seq_no | 0 |
| gtid_slave_pos | |
| gtid_strict_mode | OFF |
+-------------------------+-------+
10 rows in set (0.00 sec)
([email protected]‘mgr03‘:mysql.sock)[test]>CHANGE MASTER TO MASTER_HOST=‘mgr01‘,MASTER_PORT=3306,MASTER_USER=‘repuser‘,MASTER_PASSWORD=‘JuwoSdk21TbUser‘,master_use_gtid=slave_pos;start slave;show slave status\G
3.场景三:从mysqldump或者XtraBackup或者Mariabackup备份集设置
这两种方式都可以在非阻塞的情况下获得备份时正确的Binlog位点(所有表都要是事务引擎),当然,如果备份时不会有写入,那么 SHOW MASTER STATUS 也能提供正确的位点。
一旦获取了备份时正确的Binlog位点(文件名和偏移量),那么就可以用BINLOG_GTID_POS()函数来计算GTID:SELECT BINLOG_GTID_POS("mysql-bin.000011",342);
使用mysqldump +gtid 方式新建slave:
从MariaDB 10.0.13版本开始,mysqldump会自动完成这个工作,并且把GTID的写在导出文件中,只要设置 –master-data 或 -dump-slave 的同时设置 --gtid 即可。
mgr01-master:
[[email protected] ~]# mysqldump -uroot -p‘123456‘ -B -A -F --master-data=1 --gtid --single-transaction --events >2.sql
[[email protected] ~]#
[[email protected] ~]# grep ‘CHANGE MASTER TO‘ 2.sql
-- CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000011‘, MASTER_LOG_POS=342;
CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
([email protected]‘mgr01‘:mysql.sock)[(none)]>SELECT BINLOG_GTID_POS("mysql-bin.000011",342);
+-----------------------------------------+
| BINLOG_GTID_POS("mysql-bin.000011",342) |
+-----------------------------------------+
| 0-1283306-68 |
+-----------------------------------------+
1 row in set (0.009 sec)
[[email protected] ~]# scp -rp -P52110 2.sql [email protected]‘172.16.0.131‘:/root
slave库操作:
([email protected]‘mgr03‘:mysql.sock)[test]>source /root/2.sql
([email protected]‘mgr03‘:mysql.sock)[test]>show variables like ‘gtid_slave_pos‘;
+----------------+--------------+
| Variable_name | Value |
+----------------+--------------+
| gtid_slave_pos | 0-1283306-68 |
+----------------+--------------+
1 row in set (0.00 sec)
([email protected]‘mgr03‘:mysql.sock)[test]>SET GLOBAL gtid_slave_pos = "0-1283306-68"; 这一步可有可无
([email protected]‘mgr03‘:mysql.sock)[test]>CHANGE MASTER TO MASTER_HOST=‘mgr01‘,MASTER_PORT=3306,MASTER_USER=‘repuser‘,MASTER_PASSWORD=‘JuwoSdk21TbUser‘,master_use_gtid=slave_pos;start slave;show slave status\G
使用当日Mariabackup的全备份来新建一个slave库:
mgr01 master 库上操作:
master主库上创建备份用户
[email protected] [(none)]>grant reload,replication client,lock tables,process,super on *.* to [email protected]‘127.0.0.1‘ identified by ‘mypassword‘;flush privileges;
mariabackup --backup --target-dir=/data/backup/ --user=mariabackup --password=mypassword --host=127.0.0.1
mariabackup --prepare --target-dir=/data/backup/
cd /data/; tar zcf bak.tar.gz ./backup
scp -rp -P22 bak.tar.gz [email protected]72.16.0.131:/root
[[email protected] data]# cat /data/backup/xtrabackup_binlog_info
mysql-bin.000013 746 0-1283306-74
mgr03 slave库上操作:
[[email protected] ~]# mariabackup --defaults-file=/etc/my.cnf --copy-back --target-dir=/data/backup/
chown -R mysql.mysql /data/mysql/mysql3306/data
/etc/init.d/mysql start
基于Gtid复制配置:
SET GLOBAL gtid_slave_pos = "0-1283306-74";
CHANGE MASTER TO MASTER_HOST=‘mgr01‘,MASTER_PORT=3306,MASTER_USER=‘repuser‘,MASTER_PASSWORD=‘JuwoSdk21TbUser‘,master_use_gtid=slave_pos;start slave;show slave status\G
基于File and Position复制配置:
CHANGE MASTER TO
MASTER_HOST=‘mgr01‘,
MASTER_PORT=3306,
MASTER_USER="repuser",
MASTER_PASSWORD="JuwoSdk21TbUser",
MASTER_LOG_FILE=‘mysql-bin.000013‘,
MASTER_LOG_POS=746;
START SLAVE;
从一个线上的slave库进行 mariabackup备份数据库,然后利用这个备份做当前master库的slave库:
基于Gtid复制配置:
master库操作:
mariabackup --backup --slave-info --safe-slave-backup --target-dir=/data/backup/ --user=mariabackup --password=mypassword
mariabackup --prepare --target-dir=/data/backup/
cd /data/; tar zcf bak.tar.gz ./backup
scp -rp -P22 bak.tar.gz [email protected]:/root
[[email protected] data]# cat /data/backup/xtrabackup_binlog_info
mysql-bin.000013 746 0-1283306-74
slave库操作:
SET GLOBAL gtid_slave_pos = "0-1283306-74";
CHANGE MASTER TO MASTER_HOST=‘mgr01‘,MASTER_PORT=3306,MASTER_USER=‘repuser‘,MASTER_PASSWORD=‘JuwoSdk21TbUser‘,master_use_gtid=slave_pos;start slave;show slave status\G
2.2、CHANGE MASTER TO master_use_gtid=curren_pos 介绍:
假设我们设置了两个服务器A和B,让A作为master主服务器,而B作为slave从服务器。它运行了一段时间。然后在某个时候,masterA挂掉了,而slaveB成为了新的master。
然后,稍后我们想添加源masterA作为备库,也就是作为新的master 的slave库。
因为A之前从来不是slave库,它没有任何先前复制的GTID,并且gtid_slave_pos是空的,
为了允许A自动添加为slave库,可以使用master_use_gtid = current_pos,这将使用变量gtid_current_pos的值而不是gtid_slave_pos进行连接,gtid_current_pos该变量还考虑了当服务器作为主服务器时写入二进制日志中的GTID。
使用master_use_gtid = current_pos时,在使用CHANGE MASTER之前无需考虑服务器是master还是slave.
但是必须注意不要将多余的事务注入到slave 上的binlog中,这些事务不打算复制到其他服务器。
如果这样的额外事务是slave服务器启动时最新的事务,它将用作复制的起点。这可能会失败,因为该事务不在master主服务器上。为了避免slave从属服务器上的本地事务更改进入binlog,请将slave上的sql_log_bin设置为0。
启用GTID严格模式(通过将@@ GLOBAL.gtid_strict_mode设置为1)时,通常最好使用current_pos。在严格模式下,不允许在主服务器上进行额外的事务
提示:
不应以任何其他方式修改mysql.gtid_slave_pos表。特别是,请勿尝试更新表中的行以更改从站对当前GTID位置的想法
2.3、CHANGE MASTER TO master_use_gtid =no
这个是配置基于filename,pos传统复制的配置,这个在此不再演示描述,具体配置可以自行搜索本博主的文章或者百度。
到此处关于mariadb的主从复制介绍完毕,欢迎一起交流学习
原文地址:https://blog.51cto.com/wujianwei/2473718