Linux之mysql

######mysql######
#1.mysql的主从复制

1)下载mysql的rpm包
tar xf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar

2)安装需要的包
yum install -y mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm
#安装后会替换mariadb相关的库文件
#server2也需要装

3)修改配置文件,配合官方文档看
负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限

vim /etc/my.cnf

log-bin=mysql-bin ##文档最后加,二进制日志复制,id号来区分主机
server-id=1

4)启动mysql
systemctl start mysqld

5)会生成一个临时密码

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

2019-02-23T07:39:25.392617Z 1 [Note] A temporary password is generated for root@localhost: N7Nn<KkJsa!a

6)尝试连接,但是发现不能查看库
mysql -uroot -p’N7Nn<KkJsa!a’
mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

7)安全初始化
mysql_secure_installation
密码要求有大小写,数字,特殊字符,其他全选y
完成后可以登录数据库

8)创建并授权用来做复制的用户
在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中

mysql> grant replication slave on . to repl@‘172.25.136.%’ identified by ‘Wsp+123ld’;

mysql> show plugins; ##查看插件,因为有密码插件,所以密码必须设置为复杂的

mysql> show master status; ##查看master状态

##在server2上同样初始化mysql
修改/etc/my.cnf

vim /etc/my.cnf

server-id=2 ##文件最后加

启动mysql
systemctl start mysqld

#在物理机上尝试连接master的数据库,测试repl帐号
mysql -h 172.25.136.1 -urepl -pWsp+123ld
可以登录,但是查看不到任何信息,因为没有权限

#在server2上配置master信息
mysql> change master to master_host=‘172.25.136.1’, master_user=‘repl’, master_password=‘Wsp+123ld’, master_log_file=‘mysql-bin.000002’, master_log_pos=1004;
MASTER_LOG_POS 它是日志的开始位置
#其中master_log_file和maMASTER_LOG_POS的值为0,因为它是日志的开始位置ster_log_pos写在server1上执行show master status看到的信息

mysql> start slave;

mysql> show slave status\G ##查看主从复制状态
Slave_IO_Running: Yes
Slave_SQL_Running: Yes ##这两个参数是Yes,表示成功

9)创建新数据测试主从同步是否生效
‘注意:写操作只能在master节点上做,因为master节点不会去同步slave节点的内容’
mysql> create database westos; ##在server2上发现也能看到westos库
mysql> use westos
mysql> create table usertb (
-> username varchar(10) not null,
-> password varchar(15) not null); ##建表

mysql> desc usertb; ##查看表信息

mysql> insert into usertb values (‘user1’,‘123’); ##插入数据

mysql> select * from usertb; ##查看

###########基于GTID的主从复制 + 半同步(作业)
由于同一事务的GTID在所有节点上的值一致
我们都不需要知道GTID的具体值
‘前提:需要做好前面的binlog复制’
在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步

从服务器连接到主服务器之后,把自己执行过的GTID(Executed_Gtid_Set)<SQL线程> 、获取到的GTID(Retrieved_Gtid_Set)<IO线程>发给主服务器,主服务器把从服务器缺少的GTID及对应的transactions发过去补全即可。当主服务器挂掉的时候,找出同步最成功的那台从服务器,直接把它提升为主即可。如果硬要指定某一台不是最新的从服务器提升为主, 先change到同步最成功的那台从服务器, 等把GTID全部补全了,就可以把它提升为主了

show variables like ‘log_%’; #查看二进制日志

1)先在server1上添加配置

vim /etc/my.cnf ##在文件最后添加

gtid_mode=ON
enforce-gtid-consistency=true

mysql> select * from gtid_executed; ##是空的,因为还没重启 ##在slave上面看
Empty set (0.00 sec)

root@server1 mysql]# mysqlbinlog mysql-bin.000002 ##可以看到之前做的操作都在里面

[root@server1 mysql]# cat auto.cnf ##看到server1的uuid
[auto]
server-uuid=f84e8de1-38a2-11e9-b78c-5254009afece

systemctl restart mysqld

2)在server2上配置 (mysql5.6 slave必须开启binlog日志 但是5.7中不是必须的)

gtid_mode=ON(必选)
enforce-gtid-consistency(必选)
log_bin=ON(可选)–高可用切换,最好设置ON
log-slave-updates=ON(可选)–高可用切换,最好设置ON

vim /etc/my.cnf ##在文件最后添加

gtid_mode=ON
enforce-gtid-consistency=true

systemctl restart mysqld ##重启

#现在server2上查看主从复制状态是否正常
[root@server2 mysql]# pwd
/var/lib/mysql
#[root@server2 mysql]# cat relay-log.info #查看relay-log

mysql> stop slave; ##先停止复制
Query OK, 0 rows affected (0.01 sec)

mysql> CHANGE MASTER TO ##修改master信息
-> MASTER_HOST = ‘172.25.136.1’,
-> MASTER_USER = ‘repl’,
-> MASTER_PASSWORD = ‘Wsp+123ld’,
-> MASTER_AUTO_POSITION = 1; ##启用gtid,它是自动的

mysql> start slave;

mysql> show slave status\G ##查看状态,可以看到下面两个参数是空的
Retrieved_Gtid_Set:
Executed_Gtid_Set:

##在server1上插入数据
mysql> insert into usertb values (‘user2’,‘123’);
Query OK, 1 row affected (0.01 sec)

mysql> insert into usertb values (‘user3’,‘123’);
Query OK, 1 row affected (0.00 sec)

#再在server2上查看状态
Retrieved_Gtid_Set: f84e8de1-38a2-11e9-b78c-5254009afece:1-2
Executed_Gtid_Set: f84e8de1-38a2-11e9-b78c-5254009afece:1-2 ##发现这两个参数变了,从1位置开始复制的

再查看gtid模式复制的起始和结束位置
mysql> use mysql

mysql> select * from gtid_executed;
±————————————-±—————±————-+
| source_uuid | interval_start | interval_end |
±————————————-±—————±————-+
| f84e8de1-38a2-11e9-b78c-5254009afece | 1 | 1 |
| f84e8de1-38a2-11e9-b78c-5254009afece | 2 | 2 |
±————————————-±—————±————-+
2 rows in set (0.00 sec)

##########mysql半同步#########
异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

在2010年MySQL 5.5版本之前,一直采用的是这种异步复制的方式。主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失。于是在MySQL在5.5中就顺其自然地引入了半同步复制,主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中

##对照官方文档 https://dev.mysql.com/doc/refman/5.7/en/replication-semisync-installation.html
1)正常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。

2)异常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave因为网络不稳定,一直没有收到t1;master挂掉,slave提升为新的master,t1丢失。

3)很大的问题是:主机和从机事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。

为了弥补以上几种场景的不足,MySQL从5.5开始推出了半同步复制。相比异步复制,半同步复制提高了数据完整性,因为很明确知道,在一个事务提交成功之后,这个事务就至少会存在于两个地方。即在master的dumper线程通知slave后,增加了一个ack(消息确认),即是否成功收到t1的标志码,也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复后又会自动变为半同步复制。

1.在主库上(server1)安装插件

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;

2.查看插件是否安装

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE ‘%semi%’;

3.激活插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled =1;

4.在slave节点上(server2)也安装插件
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;

5.激活插件
SET GLOBAL rpl_semi_sync_slave_enabled =1;

6.重启IO线程使半同步生效
mysql> STOP SLAVE IO_THREAD;
mysql> START SLAVE IO_THREAD;

7.在master节点上查看
mysql> show status like ‘%rpl%’;
看到
| Rpl_semi_sync_master_status | ON |
表示已开启

mysql> show variables like ‘%rpl%’;
±——————————————±———–+
| Variable_name | Value |
±——————————————±———–+
| rpl_semi_sync_master_enabled | ON | 是否开启半同步
| rpl_semi_sync_master_timeout | 10000 | 切换复制的timeout
| rpl_semi_sync_master_trace_level | 32 |用于开启半同步复制模式时的调试级别,默认是32
| rpl_semi_sync_master_wait_for_slave_count | 1 |至少有N个slave接收到日志
| rpl_semi_sync_master_wait_no_slave | ON |是否允许master 每个事物提交后都要等待slave的receipt信号。默认为on
| rpl_semi_sync_master_wait_point | AFTER_SYNC | 等待的point
| rpl_stop_slave_timeout | 31536000 |
±——————————————±——-控制stop slave 的执行时间,在重放一个大的事务的时候,突然执行stop slave,命令 stop slave会执行很久,这个时候可能产生死锁或阻塞,严重影响性能—-+

https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html #具体参数可以看官方文档
默认延迟10s

8.在slave节点上查看
mysql> show variables like ‘%rpl%’;
±——————————–±———+
| Variable_name | Value |
±——————————–±———+
| rpl_semi_sync_slave_enabled | ON |是否开启半同步
| rpl_semi_sync_slave_trace_level | 32 |用于开启半同步复制模式时的调试级别,默认是32
| rpl_stop_slave_timeout | 31536000 |
±——————————–±———+

9.停止slave上的io线程再测试
mysql> STOP SLAVE IO_THREAD;

10.在master上插入数据
mysql> use westos;
mysql> insert into usertb values (‘user6’,‘123’);
Query OK, 1 row affected (10.01 sec) #等待10s才成功,因为上面超时时间是10s,10s后如果没有收到slave节点的返回,就会切换到异步复制

查看半同步状态也是off,待同步的事务也是1
mysql> show status like ‘%rpl%’;
±——————————————-±——+
| Variable_name | Value |
±——————————————-±——+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
±——————————————-±——+

再次插入时就不会延迟,因为已经是异步了
mysql> insert into usertb values (‘user7’,‘123’);
Query OK, 1 row affected (0.00 sec)

11.slave上开启io线程
mysql> START SLAVE IO_THREAD;

查看进程
mysql> show processlist;输出结果显示了有哪些线程在运行
########################################################################
说明各列的含义和用途
id列:一个标识
user列: 显示当前用户,如果不是root,这个命令就只显示你权限范围内的sql语句
host列:显示这个语句是从哪个ip 的哪个端口上发出的。可用来追踪出问题语句的用户
db列:显示这个进程目前连接的是哪个数据库
command列:显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)
time列:此这个状态持续的时间,单位是秒
state列:显示使用当前连接的sql语句的状态

########################################################################

查看表信息,已经复制过来
mysql> select * from westos.usertb;
±———±———+
| username | password |
±———±———+
| user1 | 123 |
| user2 | 123 |
| user3 | 123 |
| user6 | 123 |
| user7 | 123 |
±———±———+

12.master上查看进程
mysql> show processlist;

####mysql组复制(全同步复制)####
server1(master)节点:

1.关闭mysqld
systemctl stop mysqld

2.删除mysql数据 ##注意 :删除数据之前先复制uuid /var/lib/mysql/auto.cnf
rm -fr /var/lib/mysql/*

3.修改配置文件 ##官网 https://dev.mysql.com/doc/refman/5.7/en/group-replication-configuring-instances.html

vim /etc/my.cnf

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE #关闭binlog校验
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW #组复制依赖基于行的复制格式

transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name=“c36cc649-3f17-11e9-960e-525400cf2a01” ##可以看/var/lib/mysql/auto.cnf
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= “172.25.136.1:24901”
loose-group_replication_group_seeds= “172.25.136.1:24901,172.25.136.2:24901,172.25.136.3:24901”
loose-group_replication_bootstrap_group=off ##插件是否自动引导,这个选项一般都要off掉,只需要由发起组复制的节点开启,并只启动一次,如果是on,下次再启动时,会生成一个同名的组,可能会发生脑裂
loose-group_replication_ip_whitelist=“127.0.0.1,172.25.136.0/24”
loose-group_replication_enforce_update_everywhere_checks=ON
loose-group_replication_single_primary_mode=OFF #后两行是开启多主模式的参数

4.启动mysqld
systemctl start mysqld

5.初始化数据库
[root@server1 mysql]# grep password /var/log/mysqld.log

2019-03-14T07:50:42.947487Z 1 [Note] A temporary password is generated for root@localhost: J)hjM=V39sw>

登录数据库,先修改密码
mysql> alter user root@localhost identified by ‘Wsp+123ld’;

6.配置 #看官网复制 https://dev.mysql.com/doc/refman/5.7/en/group-replication-user-credentials.html

mysql> SET SQL_LOG_BIN=0; #关闭二进制日志,防止传到其他server上
mysql> CREATE USER rpl_user@’%’ IDENTIFIED BY ‘Wsp+123ld’;

mysql> GRANT REPLICATION SLAVE ON . TO rpl_user@’%’;

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1; ##开启日志

mysql> CHANGE MASTER TO MASTER_USER=‘rpl_user’, MASTER_PASSWORD=‘Wsp+123ld’ FOR CHANNEL ‘group_replication_recovery’;

mysql> INSTALL PLUGIN group_replication SONAME ‘group_replication.so’;

mysql> SHOW PLUGINS; ##查看插件
| group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | GPL |
±—————————±———±——————-±———————±——–+

mysql> SET GLOBAL group_replication_bootstrap_group=ON; ##组复制发起节点开启这个参数

mysql> START GROUP_REPLICATION;

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

mysql> SELECT * FROM performance_schema.replication_group_members; ##查看server1是否online

###注意:先不要添加数据 最后测试的时候再添加
加入数据

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;

##添加server2到组内
server2上:
[root@server2 mysql]# systemctl stop mysqld

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=“c36cc649-3f17-11e9-960e-525400cf2a01” ##注意:这里和server1的保持一致!!!!!!
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= “172.25.136.2:24901”
loose-group_replication_group_seeds= “172.25.136.1:24901,172.25.136.2:24901,172.25.136.3:24901”
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist=“127.0.0.1,172.25.136.0/24”
loose-group_replication_enforce_update_everywhere_checks=ON
loose-group_replication_single_primary_mode=OFF

#启动mysqld
systemctl start mysqld

#初始化
grep password /var/log/mysqld.log

#进入数据库
mysql> alter user root@localhost identified by ‘Wsp+123ld’; #修改root用户密码

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@’%’ IDENTIFIED BY ‘Wsp+123ld’;

mysql> GRANT REPLICATION SLAVE ON . TO rpl_user@’%’;

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;

mysql> CHANGE MASTER TO MASTER_USER=‘rpl_user’, MASTER_PASSWORD=‘Wsp+123ld’ FOR CHANNEL ‘group_replication_recovery’;

mysql> INSTALL PLUGIN group_replication SONAME ‘group_replication.so’;

#这里不需要做server1上做的SET GLOBAL group_replication_bootstrap_group=ON;

mysql> START GROUP_REPLICATION;
‘这里开启组复制可能会报错,查看mysql日志’
‘cat /var/log/mysqld.log ,找到解决办法’
2019-03-14T08:51:52.838185Z 0 [Note] Plugin group_replication reported: ‘To force this member into the group you can use the group_replication_allow_local_disjoint_gtids_join option’

mysql -pWsp+123ld

mysql> STOP GROUP_REPLICATION;

mysql> set global group_replication_allow_local_disjoint_gtids_join=on; ##直接做这一步 不用等报错

mysql> START GROUP_REPLICATION;

恢复正常

#再配置server3,和server2配置相同

配置好后在server1上查看
mysql> SELECT * FROM performance_schema.replication_group_members;
±————————–±————————————-±————±————±————-+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
±————————–±————————————-±————±————±————-+
| group_replication_applier | 43a9e177-46c2-11e9-9b8a-52540039a8e5 | server3 | 3306 | ONLINE |
| group_replication_applier | 926e543f-4635-11e9-bb87-525400cf2a01 | server2 | 3306 | ONLINE |
| group_replication_applier | de5a155a-462d-11e9-b9df-5254004c61ed | server1 | 3306 | ONLINE |
±————————–±————————————-±————±————±————-+

看到3台都是online,表示正常
这时在任何一个节点都可以看到刚才插入的数据
在任何节点写入数据,其他节点也能看到
如在server3上:
mysql> INSERT INTO t1 VALUES (2, ‘wsp’);

在server2和server1上查看:
mysql> select * from t1;
±—±—–+
| c1 | c2 |
±—±—–+
| 1 | Luis |
| 2 | wsp |
±—±—–+

可以看到刚插入的数据

#############mysql-proxy实现读写分离##########
#读写分离可以用很多软件实现:mysql-proxy 、MyCat 、Amoeba
#上课演示proxy,其他下去自己看
先看官网,官网没有el7版本的mysql-proxy,所以还是用6的

用server3来做proxy,1和2一个读一个写
做以下实验之前,先做好server1和server2的gtid主从复制

#server3上:
#先关闭之前的mysql,因为proxy也用3306端口
tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local
cd /usr/local/
ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy #软链接便于访问

cd /usr/local/mysql-proxy/bin
./mysql-proxy –help ##查看帮助
./mysql-proxy –help-proxy ##查看proxy的帮助
./mysql-proxy –help-all ##查看所有帮助

cd /usr/local/mysql-proxy
mkdir conf ##建立配置文件目录

#编辑配置文件(自己手动新建)
vim mysql-proxy.conf

[mysql-proxy]
proxy-address=0.0.0.0:3306
proxy-backend-addresses=172.25.136.1:3306
proxy-read-only-backend-addresses=172.25.136.2:3306
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
pid-file=/usr/local/mysql-proxy/log/mysql-proxy.pid
plugins=proxy
log-file=/usr/local/mysql-proxy/log/mysql-proxy.log
log-level=debug
keepalive=true
daemon=true

#创建日志目录
mkdir /usr/local/mysql-proxy/log

#修改lua脚本
min_idle_connections = 1, ##把原来的4和8改为1和2,默认超过4个连接才会启动读写分离,改为1个好测试
max_idle_connections = 2,

#启动mysql-proxy
/usr/local/mysql-proxy/bin/mysql-proxy –defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf

启动报错:
2019-03-15 14:15:04: (critical) mysql-proxy-cli.c:326: loading config from ‘/usr/local/mysql-proxy/conf/mysql-proxy.conf’ failed: permissions of /usr/local/mysql-proxy/conf/mysql-proxy.conf aren’t secure (0660 or stricter required)
2019-03-15 14:15:04: (message) Initiating shutdown, requested from mysql-proxy-cli.c:328
2019-03-15 14:15:04: (message) shutting down normally, exit code is: 1

#因为配置文件权限过大
chmod 660 /usr/local/mysql-proxy/conf/mysql-proxy.conf

再启动,正常

#查看日志
cat /usr/local/mysql-proxy/log/mysql-proxy.log
看到两个节点都加进来了

2019-03-15 15:07:22: (message) chassis-unix-daemon.c:136: [angel] we try to keep PID=2521 alive
2019-03-15 15:07:22: (debug) chassis-unix-daemon.c:157: waiting for 2521
2019-03-15 15:07:22: (debug) chassis-unix-daemon.c:121: we are the child: 2521
2019-03-15 15:07:22: (critical) plugin proxy 0.8.5 started
2019-03-15 15:07:22: (debug) max open file-descriptors = 1024
2019-03-15 15:07:22: (message) proxy listening on port 0.0.0.0:3306
2019-03-15 15:07:22: (message) added read/write backend: 172.25.136.1:3306
2019-03-15 15:07:22: (message) added read-only backend: 172.25.136.2:3306

#在server1上授权新用户读写权限
mysql> grant insert,update,select on . to wsp@’%’ identified by ‘Wsp+123ld’;

mysql> flush privileges;

mysql> use westos;
Database changed
mysql> create table usertb (
-> username varchar(10) not null,
-> password varchar(15) not null);

mysql> desc usertb;

#在物理机上打开一个shell来连接数据库
[kiosk@foundation0 ~]$ mysql -h 172.25.136.3 -uwsp -pWsp+123ld

#然后在server3上看到连接已经建立
[root@server3 log]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2521 root 10u IPv4 28318 0t0 TCP *:mysql (LISTEN)
mysql-pro 2521 root 11u IPv4 28362 0t0 TCP server3:mysql->foundation0.ilt.example.com:55716 (ESTABLISHED)
mysql-pro 2521 root 12u IPv4 28363 0t0 TCP server3:47376->server1:mysql (ESTABLISHED)

#在物理机上再打开一个shell来连接数据库
#再到server3上查看
[root@server3 log]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2521 root 10u IPv4 28318 0t0 TCP *:mysql (LISTEN)
mysql-pro 2521 root 11u IPv4 28362 0t0 TCP server3:mysql->foundation0.ilt.example.com:55716 (ESTABLISHED)
mysql-pro 2521 root 12u IPv4 28363 0t0 TCP server3:47376->server1:mysql (ESTABLISHED)
mysql-pro 2521 root 13u IPv4 28709 0t0 TCP server3:mysql->foundation0.ilt.example.com:55722 (ESTABLISHED)
mysql-pro 2521 root 14u IPv4 28710 0t0 TCP server3:47382->server1:mysql (ESTABLISHED)

‘发现两次连接都指向server1’

#在物理机上再打开一个shell来连接数据库
#再到server3上查看
[root@server3 log]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2521 root 10u IPv4 28318 0t0 TCP *:mysql (LISTEN)
mysql-pro 2521 root 11u IPv4 28362 0t0 TCP server3:mysql->foundation0.ilt.example.com:55716 (ESTABLISHED)
mysql-pro 2521 root 12u IPv4 28363 0t0 TCP server3:47376->server1:mysql (ESTABLISHED)
mysql-pro 2521 root 13u IPv4 28709 0t0 TCP server3:mysql->foundation0.ilt.example.com:55722 (ESTABLISHED)
mysql-pro 2521 root 14u IPv4 28710 0t0 TCP server3:47382->server1:mysql (ESTABLISHED)
mysql-pro 2521 root 15u IPv4 28769 0t0 TCP server3:mysql->foundation0.ilt.example.com:55726 (ESTABLISHED)
mysql-pro 2521 root 16u IPv4 28770 0t0 TCP server3:55914->server2:mysql (ESTABLISHED)

‘这次连接到了server2,说明读写分离启用’

#测试读写分离
在物理机上插入数据:
MySQL [(none)]> use westos
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
MySQL [westos]> insert into usertb values(‘user1’,‘123’);
MySQL [westos]> select * from usertb;
±———±———+
| username | password |
±———±———+
| user1 | 123 |
±———±———+
1 row in set (0.00 sec)

发现server1和server2都能看到,看不出读写分离,因为存在主从复制

现在到server2上关闭复制
mysql> stop slave;

这时再在物理机上插入数据
MySQL [westos]> insert into usertb values (‘user4’,‘123’);
Query OK, 1 row affected (0.01 sec)

MySQL [westos]> select * from usertb;
±———±———+
| username | password |
±———±———+
| user1 | 123 |
| user2 | 123 |
±———±———+
2 rows in set (0.00 sec)

发现插入的数据看不到,但是在server1上可以看到,这就说明了它在读的时候读的是server2上的数据,而写操作却写在了server1上

建议:在做MHA之前 不要和之前的实验混淆 做好gtid复制就好

MHA是一套相对成熟的MySQL高可用方案,能做到在0~30s内自动完成数据库的故障切换操作,在master服务器不宕机的情况下,基本能保证数据的一致性
################mysql高可用之MHA################# (在有报错的时候,先测试主从数据是否同步)

关闭server3上的proxy

killall mysql-proxy

#修改server3的配置:
vim /etc/my.cnf

server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
log_bin=binlog

不需要做半同步复制

#在server1和server2上都安装半同步插件
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’; ##每个节点都安装master和slave插件是因为高可用需要每个节点都可以做master或者slave

#重启io线程使server1和server2同步

#server1和server2都激活半同步插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled =1;

#server2上先不用设置这个
mysql> SET GLOBAL rpl_semi_sync_master_timeout =10000000000000000000; ##半同步超时时间,生产环境应该设置为无穷大,这里这个值是我试出来的最大值,再大就会报错,上课时可以让学生自己试最大值

mysql> show variables like ‘%rpl%’; ##查看
##################################不需要

##配置server3
#先删除数据目录中的内容 rm -fr /var/lib/mysql/*

#启动mysqld
systemctl start mysqld

#初始化
mysql_secure_installation

#server3上配置mysql的GTID主从复制
mysql> change master to master_host=‘172.25.136.1’, master_user=‘repl’, master_password=‘Wsp+123ld’, master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;

#####这里如果出现server3无法同步的情况,怎么解决(1236错误)
先查看gtid执行了多少
mysql> show global variables like ‘%gtid%’;
±———————————±—————————————–+
| Variable_name | Value |
±———————————±—————————————–+
| binlog_gtid_simple_recovery | ON |
| enforce_gtid_consistency | ON |
| gtid_executed | 1a49d884-4b83-11e9-913f-5254008ec469:1-4 |
| gtid_executed_compression_period | 1000 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | 1a49d884-4b83-11e9-913f-5254008ec469:1-4 |
| session_track_gtids | OFF |
±———————————±—————————————–+

gtid_executed表示已经执行了多少,gtid_purged表示执行完清除了二进制日志清除了多少
因为日志已经清除,所以slave节点无法同步数据

先在server1上备份所有数据

mysqldump –all-databases –single-transaction –triggers –routines –events –host=127.0.0.1 –port=3306 –user=root –password=Wsp+123ld > wsp.sql

然后在server3上进行导入

[root@server3 ~]# mysql -p < wsp.sql

会有报错
[root@server3 ~]# mysql -p < wsp.sql
Enter password:
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.

登录数据库,清除原来数据

mysql> stop slave;

mysql> reset master;

再导入,正常

进入数据库,重新配置复制

mysql> CHANGE MASTER TO MASTER_HOST = ‘172.25.0.1’, MASTER_USER = ‘repl’, MASTER_PASSWORD = ‘Wsp+123ld’, MASTER_AUTO_POSITION = 1;

mysql> start slave;

主从复制正常

#安装并启用半同步插件 ##其实不需要这步
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;

mysql> SET GLOBAL rpl_semi_sync_slave_enabled =1;

#为了不每次启动数据库都激活插件,写入配置文件(server1 2 3都写,,写在配置文件最后)

vim /etc/my.cnf

rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000000000000000000

rpl_semi_sync_slave_enabled=1

#配置刚可用(再开一台server4来做master,因为高可用一般都是奇数个节点,因为如果master挂了,其他从节点需要投票选举一个新的master,偶数节点可能出现投票数相同)

从250上下载MHA-7目录
在server4上安装:

yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm perl-* mha4mysql-node-0.58-0.el7.centos.noarch.rpm

#配置免密访问(server4需要连接server1 2 3都免密码)
在server4上:
[root@server4 ~]# ssh-keygen ##先生成密钥

[root@server4 ~]# ssh-copy-id server1

[root@server4 ~]# ssh-copy-id server2 #发送密钥

[root@server4 ~]# ssh-copy-id server3

#其他3个节点都安装mha4mysql-node-0.58-0.el7.centos.noarch.rpm即可

yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm

#在server4上配置mha工作目录及配置文件
#参考https://www.cnblogs.com/gomysql/p/3675429.html
mkdir /etc/masterha

vim /etc/masterha/app1.cnf

[server default]
manager_workdir=/etc/masterha
manager_log=/var/log/masterha.log # manager 日志文件
master_binlog_dir=/etc/masterha
#master_ip_failover_script= /usr/local/bin/master_ip_failover
#master_ip_online_change_script= /usr/local/bin/master_ip_online_change
password=Wsp+123ld #MySQL管理帐号和密码
user=root
ping_interval=1
remote_workdir=/tmp
repl_password=Wsp+123ld
repl_user=repl # 复制帐号和密码
#report_script=/usr/local/send_report
#secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02
#shutdown_script=””
ssh_user=root # 系统ssh用户

[server1]
hostname=172.25.136.1
port=3306

[server2]
hostname=172.25.136.2
port=3306
candidate_master=1
check_repl_delay=0

[server3]
hostname=172.25.136.3
port=3306
no_master=1 ##no_master表示这个节点不能作为master

##检测ssh连接
[root@server4 masterha]# masterha_check_ssh –conf=/etc/masterha/app1.cnf

发现报错,server1 2 3互相之间不免密
拷贝server4上的密钥给server1 2 3

[root@server4 ~]# scp -r .ssh server1:
[root@server4 ~]# scp -r .ssh server2:
[root@server4 ~]# scp -r .ssh server3:

再检测ssh,成功

接下来检测复制功能
[root@server4 ~]# masterha_check_repl –conf=/etc/masterha/app1.cnf

发现有报错
Fri Mar 22 10:03:45 2019 – [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln180] Got MySQL error when connecting 172.25.0.2(172.25.0.2:3306) :1130:Host ‘server4’ is not allowed to connect to this MySQL server, but this is not a MySQL crash. Check MySQL server settings.

这是因为server4默认是用root远程连接数据库,但是在配置数据库是已经禁用了root的远程连接

在主库上授权用户
mysql> grant all on . to root@’%’ identified by ‘Wsp+123ld’;

再检测发现可能卡住了,因为之前半同步的配置写在了配置文件里,数据不同步就会卡住,在所有节点配置文件里删除半同步配置,只保留之前的
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
log_bin=binlog
##所有节点的配置文件必须一样!!!!(前面的内容其实都不需要做 只要保持三个server的my.cnf的内容与这里的一致就可以 三台做好gtid的复制就ok )
##而且三个节点必须有数据(数据必须同步)

再检测,成功

再在两个slave节点设置只读(不写在配置文件里,因为slave随时可能切换为master)

#测试manager能否开启
nohup masterha_manager –conf=/etc/masterha/app1.cnf –remove_dead_master_conf –ignore_last_failover < /dev/null > /var/log/masterha.log 2>&1 &

#测试手动failover切换
先关闭manager,不关的话切不了,manager就是自动切换的工具

[root@server4 masterha]# masterha_stop –conf=/etc/masterha/app1.cnf

server1:systemctl stop mysqld
#手动切换
masterha_master_switch –master_state=dead –conf=/etc/masterha/app1.cnf –dead_master_host=172.25.0.1 –dead_master_ip=172.25.0.1 –dead_master_port=3306 –new_master_host=172.25.0.2 –new_master_port=3306
‘手动切换之前,需要保证主从同步正常,repl复制用户能够远程连接’

中间都选yes

切换成功后,可以在server3上看到它的master已经变成了server2
而server2已经时master了

再手动开启server1,作为slave加入集群

[root@server1 ~]# systemctl start mysqld

mysql> CHANGE MASTER TO MASTER_HOST = ‘172.25.0.2’, MASTER_USER = ‘repl’, MASTER_PASSWORD = ‘Wsp+123ld’, MASTER_AUTO_POSITION = 1;

mysql> start slave;

mysql> show slave status\G

至次完成了一次手动切换

这时会在/etc/masterha目录下生成一个app1.failover.complete文件,是来记录failover情况的,再进行failover时必须先把这个文件删除,不然不会failover

#手动在线切换,刚才是master挂掉后切换
masterha_master_switch –conf=/etc/masterha/app1.cnf –master_state=alive –new_master_host=172.25.0.1 –new_master_port=3306 –orig_master_is_new_slave –running_updates_limit=10000

又切换回172.25.0.1为master

#测试半自动failover
首先清理app1.failover.complete

开启mha manager
[root@server4 masterha]# nohup masterha_manager –conf=/etc/masterha/app1.cnf &>/dev/null &

mha manager自带守护进程

在server1上查看
[root@server1 ~]# ps ax | grep mysql
2320 ? Sl 0:00 /usr/sbin/mysqld –daemonize –pid-file=/var/run/mysqld/mysqld.pid
2366 pts/0 S+ 0:00 grep –color=auto mysql

看到mysql的进程

kill -9 2320

再查看,发现mysql进程又开启了
[root@server1 ~]# ps ax | grep mysql
2400 ? Sl 0:00 /usr/sbin/mysqld –daemonize –pid-file=/var/run/mysqld/mysqld.pid
2431 pts/0 S+ 0:00 grep –color=auto mysql

在server1上手动关闭mysqld

[root@server1 ~]# systemctl stop mysqld

在server4上查看
[root@server4 masterha]# cat /var/log/masterha.log

发现已经切换,同时manager进程退出,所以全自动需要脚本

先把server1加回集群

mysql> CHANGE MASTER TO MASTER_HOST = ‘172.25.0.2’, MASTER_USER = ‘repl’, MASTER_PASSWORD = ‘Wsp+123ld’, MASTER_AUTO_POSITION = 1;

mysql> start slave;

#配置脚本和vip漂移
因为用户访问入口只能有一个,所以需要配置vip

编辑master_ip_failover 和 master_ip_online_change 两个脚本
修改内容:

my $ssh_start_vip = “/sbin/ip addr add $vip dev eth0”;
my $ssh_stop_vip = “/sbin/ip addr del $vip dev eth0”;

配置自动添加和删除vip

cp master_ip_failover master_ip_online_change /usr/local/bin
cd /usr/local/
cd bin/
chmod +x master_ip_failover master_ip_online_change

###注意在server4的配置文件种 这两行的注释要打开
master_ip_failover_script= /usr/local/bin/master_ip_failover
master_ip_online_change_script= /usr/local/bin/master_ip_online_change

#目前server2是master,所以先给server2添加vip

[root@server2 ~]# ip addr add 172.25.0.100/24 dev eth0

测试vip漂移

[root@server4 bin]# masterha_master_switch –conf=/etc/masterha/app1.cnf –master_state=alive –new_master_host=172.25.0.1 –new_master_port=3306 –orig_master_is_new_slave –running_updates_limit=10000

可以看到切换vip

Disabling the VIP – 172.25.0.100/24 on old master: 172.25.0.2

Enabling the VIP – 172.25.0.100/24 on new master: 172.25.0.1

#测试全自动切换
在server4上先删除app1.failover.complete

开启manager

nohup masterha_manager –conf=/etc/masterha/app1.cnf &>/dev/null &

然后在master(server1)上关闭mysql,模拟故障

再在server4上查看日志

cat /var/log/masterha.log
可以看到切换成功,vip也成功漂移

    原文作者:若无其事的苹果
    原文地址: https://blog.csdn.net/qq_36016375/article/details/94917080
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞