准备:
4台vm (centos 7.3):
192.168.1.120 proxysql 192.168.1.121 node1 master 192.168.1.122 node2 slave 192.168.1.123 node3 slave
一. 在node1,node2,node3安装mariadb, mariadb-server
(以root用户安装)
1. yum安装
# yum install mariadb mariadb-server -y
2. 启动服务
# systemctl start mariadb.service
开机启动
# systemctl enable mariadb.service
3. 配置管理员密码
# mysql_secure_installation
4. 配置远程访问 (mysql提示符以 mysql>表示)
mysql> use mysql; mysql> grant all privileges on *.* to ‘root‘@‘ip‘ identified by ‘123456‘; 这个只允许指定ip访问 mysql> grant all privileges on *.* to ‘root‘@‘%‘ identified by ‘123456‘; 这个允许任意的ip访问 mysql> flush privileges;
二.配置主从复制
node1: /etc/my.cnf.d/server.cnf
[mysqld] skip_name_resolve=ON innodb_file_per_table=ON server_id=1 log_bin=master-bin
重启服务
# systemctl restart mariadb.service
创建用户mauser(用户名任意,这里是mauser): node2和node3通过用户mauser复制数据
mysql> grant replication slave, replication client on *.* to ‘mauser‘@‘192.168.1.%‘ identified by ‘123456‘; mysql> flush privileges;
然后:
mysql> show master status;
上面的数字一会要用到。
node2: /etc/my.cnf.d/server.cnf
和node1不一样的是多了read_only这一行,有了这一行,在proxysql的mysql_servers表中就会只有一行hostgroup_id=1,如果去掉这一行,mysql_servers表中每个从server会有两行:
hostgroup_id=0, hostgroup_id=1
[mysqld] skip_name_resolve=ON innodb_file_per_table=ON server_id=2 relay_log=relay-log read_only=ON
重启服务
# systemctl restart mariadb.service
设置成从数据库, master_log_pos要设置上面图片里那个数(756)
mysql> change master to master_host=‘192.168.1.121‘, master_user=‘mauser‘, master_password=‘123456‘, master_log_file=‘master-bin.000001‘,master_log_pos=756; mysql> start slave;
mysql> show slave status\\G; ...
Slave_IO_Running: Yes 这两行必须是Yes Slave_SQL_Running: Yes
...
node3: /etc/my.cnf.d/server.cnf
[mysqld] skip_name_resolve=ON innodb_file_per_table=ON server_id=3 relay_log=relay-log read_only=ON
重启服务
# systemctl restart mariadb.service
设置成从数据库
mysql> change master to master_host=‘192.168.1.121‘, master_user=‘mauser‘, master_password=‘123456‘, master_log_file=‘master-bin.000001‘,master_log_pos=756;
mysql> start slave;
回到node1, 建库,建表,插入数据:
mysql> create database mybatisdb;
mysql> create table person(id int not null primary key, name varchar(20), age int);
mysql> insert into person values(1,‘tom‘,20),(2,‘mary‘,30)
再回到node2, node3查看
mysql> use mybatisdb; mysql> select * from person;
可以看到person表数据。
主从复制完成。
三. 读写分离
下载proxysql: http://www.proxysql.com/ 这里下载的是1.4.7
在192.168.1.120 vm上
# yum install mariadb -y
# yum install proxysql-1.4.7-1-centos7.x86_64.rpm
安装完成后,修改 /etc/proxysql.cnf
datadir="/var/lib/proxysql" admin_variables= { admin_credentials="admin:admin" mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock" } mysql_variables= { threads=4 max_connections=2048 default_query_delay=0 default_query_timeout=36000000 have_compress=true poll_timeout=2000 interfaces="0.0.0.0:3306;/tmp/mysql.sock" default_schema="information_schema" stacksize=1048576 server_version="5.5.56" connect_timeout_server=3000 monitor_history=600000 monitor_connect_interval=60000 monitor_ping_interval=10000 monitor_read_only_interval=1500 monitor_read_only_timeout=500 ping_interval_server=120000 ping_timeout_server=500 commands_stats=true sessions_sort=true connect_retries_on_failure=10 } mysql_servers = ( { address = "192.168.1.121" port = 3306 hostgroup = 0 max_connections=100 }, { address = "192.168.1.122" port = 3306 hostgroup = 1 max_connections=100 }, { address = "192.168.1.123" port = 3306 hostgroup = 1 max_connections=100
}
)
mysql_users:
(
{
username = "root"
password = "123456"
default_hostgroup = 0
max_connections=1000
default_schema="mysql"
active = 1
}
)
mysql_query_rules:
(
{
rule_id=1
active=1
match_pattern="^SELECT .* FOR UPDATE$"
destination_hostgroup=0
apply=1
},
{
rule_id=2
active=1
match_pattern="^SELECT"
destination_hostgroup=1
apply=1
}
)
mysql_replication_hostgroups=
(
{
writer_hostgroup=0
reader_hostgroup=1
}
)
启动proxysql前:要在主数据库(node1)添加monitor用户,并给usage和replcation client权限,proxysql使用这个用户连接node1,node2,node3.
当然也可修改这个monitor,改成别的用户名和密码,这里不介绍。
proxysql默认的配置monitor的密码也是monitor (在main数据库的global_variables表中)
mysql> grant usage, replication client on *.* to ‘monitor‘@‘192.168.1.120‘ identified by ‘monitor‘; mysql> flush privileges; 就是允许proxysql使用monitor/monitor访问, 这个赋权也会同步到node2,node3,所以另外两个vm不用再这样处理了。
启动proxysql:
# systemctl start proxysql
连接proxysql:
# mysql -h127.0.0.1 -uadmin -padmin -P 6032
四.测试:
在其它vm上(不在proxysql那台vm上就好, 比如node1), 连接proxysql
# mysql -h 192.168.1.120 -uroot -p123456
...
mysql> use mybatisdb;
mysql> insert into person values(3,‘mike‘, 50), (4,‘jack‘, 39)
将 node1主数据库服务停掉:
systemctl stop mariadb.service
再连接proxysql, 此时仍可执行select, 但insert插入报错:
ERROR 9001 (HY000): Max connect timeout reached while reaching hostgroup 0 after 10000ms
说明,因为主数据库挂掉,insert已经不能执行。 但select仍可正常操作,说明读写分离已工作。
五. 重要的东西
上面是从头开始实现,实际上,一般情况下是先有一个数据库,由于性能问题,要实现读写分离和主从复制。
这种情况,要先将原有数据要进行一个完全的备份(mysqldump),导入后加的服务器,再把原数据库的show master status那个pos,写进后加的服务器(change master, start slave),
从而实现主从复制。
主数据库备份:
# mysqldump --all-databases --master-data=2 --routine --trigger --event --lock-all-tables > x.sql
在新加数据库导入:
# mysql -u ... -p ... < x.sq
将新加数据库改成从数据库,并启动
mysql> change master ...;
mysql> start slave;