mysql的主从复制与读写分离

1.环境:

RHEL6.5   mysql-5.7.17-1.el6.x86_64

Master=server1-172.25.4.1

Slave= server4-172.25.4.4

 

2.安装mysql

server1.4

tar xf mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar

yum install mysql-community-libs-5.7.17-1.el6.x86_64.rpm mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm mysql-community-server-5.7.17-1.el6.x86_64.rpm mysql-community-client-5.7.17-1.el6.x86_64.rpm mysql-community-common-5.7.17-1.el6.x86_64.rpm

 

/etc/init.d/mysqld start

如果服务起不来就rm -f /var/lib/mysql

cat /var/log/mysqld.log |grep password

mysql -p

mysql> show database;

ALTER USER root@localhost identified by 'Syx.123456';

 

3.主从复制基本配置

master server配置

 

1 )配置 /etc/my.cnf 配置文件

[mysqld]下添加一下参数

log-bin=mysql-bin         启动二进制日志系统

binlog-do-db=test         二进制需要同步的数据库名

server-id=1               必须为1232–1之间的一个正整数值 

binlog-ignore-db=mysql   避免同步mysql用户配置,以免不必要的麻烦

 

 

2)创建同步帐户,并给予权限

mysql -p

mysql>grant replication slave on *.* to test@'172.25.4.%' identified by 'Syx.123456';        #授予从机对test库有复制的权限

mysql>Flush privileges;    刷新数据使其生效

mysql>show master status;  如果是在对库进行操作之后查询状态,就需要去

                               cd /var/lib/mysql  

                               mysqlbinlog mysql-bin.000001

                               查询到对数据库进行操作之前的线程id

 

+------------------+----------+--------------+------------------+-------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000001 |      446 | test         | mysql            |                   |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

记录FilePosition的值,下面会用到

 

3)建立数据库,并建表

mysql> create database test;

mysql> use test

mysql> create table usertb (

    -> username varchar(15) not null,

    -> password varchar(25) not null);

mysql> desc usertb;

 

4)/etc/init.d/mysqld restart

 

 

slave server 配置

1 ) 配置 /etc/ my.cnf 文件

server-id=2                从服务器ID,不要和主 ID相同,如果设置多个服

                            务器,每个从服务器必须有一个唯一的server-id

                            值,必须与主服务器的以及其它从服务器的不相同。                          

                            可以认为server-id值类似于IP地址:这些ID

                            能唯一识别复制服务器群集中的每个服务器实例。                            

master-host=172.25.18.1   指定主服务器 IP 地址

master-user=test           制定在主服务器上可以进行同步的用户名

master-password=test      密码

master-port=3306          同步所用的端口

master-connect-retry=60    断点重新连接时间

replicate-ignore-db=mysql  屏蔽对 mysql 库的同步,以免有麻烦

replicate-do-db=test         同步数据库名称

 

 

mysql -p

mysql> show slave status;

mysql> change master to master_host='172.25.4.1',master_user='test',master_password='Syx.123456',master_log_file='mysql-bin.000001',master_log_pos=446;

 

ERROR 1201 (HY000): Could not initialize master info structure; more error messages can be found in the MySQL error log

如果出现这种报错,是由于新的slave改变了服务端口和文件路径,分析应该是由于mysql-relay-bin.index中仍然保存着旧relay日志文件的路径,而这些路径下又找不到合适的文件,因此报错。重置slave的参照即可,只需要执行下面的命令:

mysql> reset slave;

Query OK, 0 rows affected (0.00 sec)

 

mysql> start slave

 

/etc/init.d/mysqld restart

 

 

测试:

mysql> show slave status\G;

.....

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

.....

 

Slave_IO_Running:连接到主库,并读取主库的日志到本地,生成本地日志文件
Slave_SQL_Running:读取本地日志文件,并执行日志里的SQL命令。

如果数据不同步:

master

mysqldump -pSyx.123456 --set-gtid-purged=OFF test > test.sql

如果想备份全部文件,就不要红色字体部分,如果加上就是步备份gtid部分

然后将该文件发送到slave

在这之前要stop slave;

mysql -pSyx.123456 test < test.sql

Start slave

 

如果都是yes ,表示从库的I/O,Slave_SQL线程都正确开启.表明数据库正在同步

I/O出错往往时授权问题,SQL出错往往时数据不一致

 

你也可以通过在master server上的test库中添加数据,slave server是否同步,建议使用phpmyadmin,比较方便

 

Master

mysql -p

Mysql> use test

mysql> insert into usertb values ('user1','111');

mysql> insert into usertb values ('user2','222');

mysql> select * from usertb

 

Slave

mysql -p

mysql> use test

mysql> select * from usertb; 

 

 

4.GTID的主从复制(在主从复制配置好的基础上部署比较方便)

Master

Cat auto.cnf      #可以看到全局的server-uuid,主从机一样

vim /etc/my.cnf

gtid_mode=ON

enforce-gtid-consistency=true

/etc/init.d/mysqld restart

 

mysql -p

use test

Insert into usertb value (‘user3’,’6666’);

 

Slave

vim /etc/my.cnf

gtid_mode=ON

enforce-gtid-consistency=true

/etc/init.d/mysqld restart


mysql -p

mysql> stop slave;

mysql>  change master to master_host='172.25.4.1',master_user='test',master_password='Syx.123456',MASTER_AUTO_POSITION=1;

mysql> start slave;

mysql> set global read-only=on;   #全局变量只读

mysql> select *from test.usertb;   #数据已经同步

mysql> use mysql

mysql> show tables;

mysql> select * from gtid_executed;

 

5.并行复制(又叫多线程复制)

基于库的并行复制(单库多表,更多见)--mysql5.6以前

基于组的并行复制,用表的方式存储--mysql5.7开始

Slave

vim /etc/my.cnf

slave-parallel-type=LOGICAL_CLOCK

slave-parallel-workers=16

master_info_repository=TABLE

relay_log_info_repository=TABLE

relay_log_recovery=ON

 

/etc/init.d/mysqld restart

mysql> show processlist;  ##可以看到16个并发worker

 

 

6.半同步复制

(基于异步的,如果半同步失败,自动转换成异步,异步效率最高,但是无法完全保证数据的一致性,但是全同步和半同步可以相对保证数据的一致性。)

Master

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  添加半同步模块,并重命名

 

slave

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

mysql> show variables like '%semi_sync%'  查看半同步的参数状态

+-------------------------------------------+------------+

| Variable_name                             | Value      |

+-------------------------------------------+------------+

| rpl_semi_sync_master_enabled              | ON         |

| rpl_semi_sync_master_timeout              | 10000      |

| rpl_semi_sync_master_trace_level          | 32         |

| rpl_semi_sync_master_wait_for_slave_count | 1          |

| rpl_semi_sync_master_wait_no_slave        | ON         |

| rpl_semi_sync_master_wait_point           | AFTER_SYNC |

+-------------------------------------------+------------+

timeout  #半同步等待时间10秒,10秒后没收到同步信息就会转会异步

| rpl_semi_sync_master_wait_for_slave_count | 1          |

等待slave成功同步的主机数

 

mysql> set global rpl_semi_sync_slave_enabled=1;

 

Master

mysql> show variables like '%semi_sync%'

mysql> set global rpl_semi_sync_master_enabled=1;

mysql> show status like '%semi_sync%'; (只能在mater上看到参数)

+--------------------------------------------+-------+

| Variable_name                              | Value |

+--------------------------------------------+-------+

| Rpl_semi_sync_master_clients               | 1     |

| Rpl_semi_sync_master_net_avg_wait_time     | 0     |

| Rpl_semi_sync_master_net_wait_time         | 0     |

| Rpl_semi_sync_master_net_waits             | 1     |

| Rpl_semi_sync_master_no_times              | 1     |

| Rpl_semi_sync_master_no_tx                 | 1     |

| Rpl_semi_sync_master_status                | ON    |

| Rpl_semi_sync_master_timefunc_failures     | 0     |

| Rpl_semi_sync_master_tx_avg_wait_time      | 4297  |

| Rpl_semi_sync_master_tx_wait_time          | 4297  |

| Rpl_semi_sync_master_tx_waits              | 1     |

| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |

| Rpl_semi_sync_master_wait_sessions         | 0     |

| Rpl_semi_sync_master_yes_tx                | 1     |

+--------------------------------------------+-------+

 

| Rpl_semi_sync_master_no_tx                 | 1     |

半同步失败次数

| Rpl_semi_sync_master_yes_tx                | 1     |

半同步成功次数

 

Slave

mysql> stop slave io_thread;  #关掉IO线程,如果超过10秒没有启用,就会转为异步。

mysql> start slave io_thread;  #再次启用,则转为半同步

 

 

 

 

7.读写分离

添加调度器Proxy :server2-172.25.4.2
tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz

mv mysql-proxy-0.8.5-linux-el6-x86-64bit /usr/local/

cd /usr/local/

ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy

mkdir etc

cd /etc

 

vim mysql-proxy.conf

[mysql-proxy]

user=root

daemon=true

keepalive=true

log-level=debug

log-file=/usr/local/mysql-proxy/log/mysql-proxy.log

admin-username=admin

admin-password=westos

admin-lua-script=/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua

#proxy-address=172.25.4.2:3306

proxy-backend-addresses=172.25.4.1:3306

proxy-read-only-backend-addresses=172.25.4.4:3306

plugins=proxy,admin

 

mkdir /usr/local/mysql-proxy/log

 

cd /usr/local/mysql-proxy/share/doc/mysql-proxy

vim rw-splitting.lua

40                 min_idle_connections = 1,  最小连接数

41                 max_idle_connections = 2,  最大连接数

 

proxy

/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/etc/mysql-proxy.conf   #启动调度服务

 

如果出现以下错误:

2017-08-04 03:06:48: (critical) mysql-proxy-cli.c:326: loading config from '/usr/local/mysql-proxy/etc/mysql-proxy.conf' failed: permissions of /usr/local/mysql-proxy/etc/mysql-proxy.conf aren't secure 

(0660 or stricter required)

提示这个文件权限应该为660

 

cd /usr/local/mysql-proxy/etc

chmod 660 mysql-proxy.conf

 

killall mysql-proxy ##如果配置文件有问题,要先停掉服务,在重启

 

Master上

mysql> grant insert, select, update on *.* to admin@'172.25.4.%' identified by 'Syx.123456';

 

slave

mysql> stop slave;

mysql> grant insert, select, update on *.* to admin@'172.25.4.%' identified by 'Syx.123456';

mysql> start slave;

mysql> show slave status\G;

Slave_IO_Running: Yes

      Slave_SQL_Running: Yes

mysql> set global read_only=1; ##打开只读模式(flush tables with read lock; 锁表   unlock tables; 解表)

 

测试:

proxy

mysql -h 172.25.4.2 -P 4040 -u admin -p   访问后端的调度

mysql> use test

mysql> select * from usertb;

 

#mysql -h 172.25.4.2 -P 4041 -u admin -p 访问管理用户的调度

mysql> select * from backends;

+-------------+-------------------+---------+------+------+-------------------+

| backend_ndx | address           | state   | type | uuid | connected_clients |

+-------------+-------------------+---------+------+------+-------------------+

|           1 | 172.25.4.1:3306 | up      | rw   | NULL |                 0 |

|           2 | 172.25.4.4:3306 | up      | ro   | NULL |                 0 |

+-------------+-------------------+---------+------+------+-------------------+

测试读写分离:

<1>确认半同步复制没有错误,即确认slave2Yes,masterslave上安装lsof用于查看连接的主机

yum install -y lsof   #显示当前操作系统打开的文件

master:

# lsof -i :3306 

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  2217 mysql   33u  IPv6  11010  0t0  TCP *:mysql (LISTEN)

mysqld  2217 mysql   49u  IPv6  11704  0t0  TCP server1:mysql->server2:45796 (ESTABLISHED)

mysqld  2217 mysql   53u  IPv6  11151  0t0  TCP server1:mysql->server4:40416 (ESTABLISHED)

 

slave:

# lsof -i :3306 

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  2760 mysql   17u  IPv6  11407      0t0  TCP *:mysql (LISTEN)

mysqld  2760 mysql   54u  IPv4  11584      0t0  TCP server2:40416->server1:mysql (ESTABLISHED)

 

<2>server2上进行mysql读写操作,测试读写是否分离

server2:

# mysql -h 172.25.4.2 -P 3306 -u admin -p

 

mysql> select * from test.usertb; ##查看数据(读操作)

 

此时再查看slave上的连接:

slave:

# lsof -i :3306 

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  2760 mysql   17u  IPv6  11407      0t0  TCP *:mysql (LISTEN)

mysqld  2760 mysql   49u  IPv6  12712      0t0  TCP server4:mysql->server2:41194 (ESTABLISHED) ##新的连接来自server2,即读操作被调度到slave

mysqld  2760 mysql   54u  IPv4  11584      0t0  TCP server4:40416->server1:mysql (ESTABLISHED)

 

再在server2进行数据的写入

server2:

mysql> insert into test.usertb values ('user6','666');

 

再查看master上的连接:

master:

# lsof -i :3306

COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  2217 mysql   33u  IPv6  11010      0t0  TCP *:mysql (LISTEN)

mysqld  2217 mysql   49u  IPv6  11704      0t0  TCP server1:mysql->server2:45796 (ESTABLISHED)

mysqld  2217 mysql   52u  IPv6  11786      0t0  TCP server1:mysql->server2:45808 (ESTABLISHED) ##新的lianjie来自server2,写操作备调度到master

mysqld  2217 mysql   53u  IPv6  11151      0t0  TCP server1:mysql->server4:40416 (ESTABLISHED)

 

测试结果:server2上对mysql的读操作是在slave上进行的,写操作是在master上进行的,实现了mysql的读写分离。(还可以用真机测试,篇幅的原因真机测试就不写了)

 

 

8.慢查询

mysqlbinlog mysql-bin.000006 --base64-output=DECODE-ROWS -vv  查看修改过的数据库加密内容

 

mysql> set binlog_row_image=minimal;

mysql> set global binlog_row_image=minimal; 

修改参数,使日志只记录,修改过的数据库内容

 

mysql> update test.usertb set password='123';

更新数据库数据,进行测试

 

 

mysql> set global slow_query_log=1;

mysql> show variables like '%slow%'; 查看慢查询的属性

mysql> show status like '%slow%';  查看慢查询的状态

 

mysql> select sleep(10); 设置一条慢查询

mysql> show status like '%slow%';

+---------------------+-------+

| Variable_name       | Value |

+---------------------+-------+

| Slow_launch_threads | 0     |

| Slow_queries        | 1     |

+---------------------+-------+

2 rows in set (0.01 sec)

 

cat /var/lib/mysql/server1-slow.log  查看筛选出来的慢查询语句

/usr/sbin/mysqld, Version: 5.7.17-log (MySQL Community Server (GPL)). started with:

Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock

Time                 Id Command    Argument

# Time: 2017-08-06T06:50:36.932388Z

# User@Host: root[root] @ localhost []  Id:    38

# Query_time: 10.005069  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0

SET timestamp=1502002236;

select sleep(10);

 

通过筛选出慢查询语句,从而做出优化

 

mysql> show variables like '%query%';

long_query_time              | 10.000000   #可以设置你的慢查询判断时间阀门

 

Percona-xtrabackup  支持在不锁表的情况下备份

Mysqldump     备份必须锁表

 

 

 

9.分布式集群

(为了保证所有节点数据一致,全同步复制)

Master

 

/etc/init.d/mysqld stop

rm -fr *  /varserver-id=1

 

vim /etc/my.cnf

server-id=1

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

 

transaction_write_set_extraction=XXHASH64

loose-group_replication_group_name="292b82bc-7a7c-11e7-8954-525400542c39"

loose-group_replication_start_on_boot=off

loose-group_replication_local_address="172.25.4.1:24901"

loose-group_replication_group_seeds="172.25.4.1:24901,172.25.4.3:24901,172.25.4.4:24901"

loose-group_replication_bootstrap_group=off

loose-group_replication_single_primary_mode=FALSE

loose-group_replication_enforce_update_everywhere_checks=TRUE

 

loose  在第一次加载replication模块时需要加上,不然系统不识别参数,无法加载模块

 

/etc/init.d/mysqld start

cat /var/log/mysqld.log |grep password  ##查看密码

 

mysql -p

mysql> SET SQL_LOG_BIN=0;

Query OK, 0 rows affected (0.00 sec)

 

mysql> alter user root@localhost identified by 'Syx.123456';

Query OK, 0 rows affected (0.00 sec)

 

mysql> select uuid();  可以用此方式随便查询一个数据库的UUID然后添加到/etc/my.cnf的配置文件里面

+--------------------------------------+

| uuid()                               |

+--------------------------------------+

| 6b01105d-7a83-11e7-a8e3-5254001481aa |

+--------------------------------------+

1 row in set (0.00 sec)

 

 

mysql> SET SQL_LOG_BIN=0;

mysql> GRANT REPLICATION SLAVE ON *.* TO test@'%' IDENTIFIED BY 'Syx.123456';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;

mysql> CHANGE MASTER TO MASTER_USER='test', MASTER_PASSWORD='Syx.123456' FOR CHANNEL 'group_replication_recovery';

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';

mysql> show plugins;

mysql> SET GLOBAL group_replication_bootstrap_group=ON;

mysql> STOP GROUP_REPLICATION;

mysql> SET GLOBAL group_replication_ip_whitelist="172.25.4.0/24,127.0.0.1/8";

mysql> START GROUP_REPLICATION;

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

mysql> SELECT * FROM performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | a821bdf5-7a82-11e7-9348-5254001481aa | server1     |        3306 | ONLINE       |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

1 row in set (0.00 sec)

 

mysql> create database test;

mysql > use test

mysql > create table t1 (c1 int primary key,c2 text not null);

mysql > insert into t1 values (1,’Luis’);

mysql > select * from t1;

 

 

Slave

 

/etc/init.d/mysqld stop

rm -fr * /var/lib/mysql/

 

vim /etc/my.cnf

 

server-id=2

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

 

transaction_write_set_extraction=XXHASH64

loose-group_replication_group_name="292b82bc-7a7c-11e7-8954-525400542c39"

loose-group_replication_start_on_boot=off

loose-group_replication_local_address="172.25.4.1:24901"

loose-group_replication_group_seeds="172.25.4.1:24901,172.25.4.3:24901,172.25.4.4:24901"

loose-group_replication_bootstrap_group=off

loose-group_replication_single_primary_mode=FALSE

loose-group_replication_enforce_update_everywhere_checks=TRUE

Loose-group_replication_ip_whitelist="172.25.4.0/24,127.0.0.1/8"

Loose-group_replication_allow_local_disjoint_gtids_join=ON

 

 

/etc/init.d/mysqld start

cat /var/log/mysqld.log |grep password

 

mysql> SET SQL_LOG_BIN=0

mysql> alter user root@localhost identified by 'Syx.123456';

mysql> GRANT REPLICATION SLAVE ON *.* TO test@'%' IDENTIFIED BY 'Syx.123456';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;

mysql> CHANGE MASTER TO MASTER_USER='test', MASTER_PASSWORD='Syx.123456' FOR CHANNEL 'group_replication_recovery';

mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';

mysql> SET GLOBAL group_replication_ip_whitelist="172.25.4.0/24,127.0.0.1/8";

set global group_replication_allow_local_disjoint_gtids_join=ON;

Mysql> uninstall plugin validate_password;

mysql> START GROUP_REPLICATION;

mysql> SELECT * FROM performance_schema.replication_group_members;

 

测试:

可以在任意一个节点上,插入数据

mysql> INSERT INTO test.t1 VALUES (3,’hello’);

再去别的节点查看,是否更新


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值