实现mysql主从

主从作用:1)实时灾备,用于故障切换
2)读写分离,提供查询服务
3)备份,避免影响业务
主从形式:1)一主一从
2)主主复制
3)一主多从 (偏向于读)
4)多主一从 (分表机制,偏向于写,mysql5.7版本开始支持)
5)联级复制

主从原理:

实现mysql主从

主库将所有的写操作记录到binlog日志中,并生成一个log dump线程,将binlog日志传给从库的I/O线程
从库生成两个线程,一个I/O线程,一个SQL线程。I/O线程去请求主库的binlog,并将得到的binlog写到relay log(中继日志)文件中
SQL线程会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,达到最终数据一致的目的

两台主机:一台做主:192.16856.11 两台主机都需要关闭防火墙,selinux
一台做备:192.168.56.12

主机192.168.56.11上操作:
//二进制安装mysql
[root@heyuanjie ~]# cd /usr/src
[root@heyuanjie src]# ls
debug kernels mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz
[root@heyuanjie src]# groupadd -r mysql
[root@heyuanjie src]# useradd -M -s /sbin/nologin -g mysql mysql
[root@heyuanjie src]# tar xf mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
[root@heyuanjie src]# cd /usr/local/
[root@heyuanjie local]# ls
bin games lib libexec sbin src
etc include lib64 mysql-5.7.22-linux-glibc2.12-x86_64 share
[root@heyuanjie local]# ln -sv mysql-5.7.22-linux-glibc2.12-x86_64/ mysql
‘mysql’ -> ‘mysql-5.7.22-linux-glibc2.12-x86_64/’
//修改目录/usr/local/mysql 的属主属组
[root@heyuanjie ~]# chown -R mysql.mysql /usr/local/mysql
[root@heyuanjie ~]# ll /usr/local/mysql -d
lrwxrwxrwx. 1 mysql mysql 36 Sep 9 00:09 /usr/local/mysql -> mysql-5.7.22-linux-glibc2.12-x86_64/
//添加环境变量
[root@heyuanjie ~]# ls /usr/local/mysql
bin COPYING docs include lib man README share support-files
[root@heyuanjie ~]# echo 'export PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
[root@heyuanjie ~]# . /etc/profile.d/mysql.sh
[root@heyuanjie ~]# echo $PATH
/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

//建立数据存放目录并更改属主属组
[root@heyuanjie ~]# mkdir /opt/data
[root@heyuanjie ~]# chown -R mysql.mysql /opt/data/
[root@heyuanjie ~]# ll /opt/
total 0
drwxr-xr-x. 2 mysql mysql 6 Sep 9 00:13 data

//初始化数据库
[root@heyuanjie ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --datadir=/opt/data/
//注意这个命令的最后会生成一个临时密码,需要记住之隔密码,用作登录数据库,然后修改密码
[root@heyuanjie ~]# echo 'bf5wX(%u)Rj_' > /etc/mima
//生成配置文件
[root@heyuanjie ~]# cat > /etc/my.cnf <<EOF

[mysqld]
basedir = /usr/local/mysql
socket = /tmp/mysql.sock
datadir = /opt/data
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
EOF
[root@heyuanjie ~]# cat /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
socket = /tmp/mysql.sock
datadir = /opt/data
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve

//配置服务启动脚本
[root@heyuanjie ~]# cp -a /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@heyuanjie ~]# sed -ri 's#^(basedir=).#\1/usr/local/mysql#g' /etc/init.d/mysqld
[root@heyuanjie ~]# sed -ri 's#^(datadir=).
#\1/opt/data#g' /etc/init.d/mysqld
//启动mysql
[root@heyuanjie ~]# service mysqld start
Starting MySQL.Logging to '/opt/data/heyuanjie.err'.
. SUCCESS!

//登录数据库并修改密码
[root@heyuanjie ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.22
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> set password = password('ran1027.');
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> quit
Bye

//在192.168.56.12主机上同样二进制安装好数据库,步骤略。

//在主机192.168.56.11上操作
看主库上有哪些库
[root@heyuanjie ~]# mysql -uroot -pran1027. -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
//再看看从库上有哪些库
[root@hyj ~]# mysql -uroot -pran1027. -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+

//在主库上创建数据库并创建表
mysql> create database hejie;
Query OK, 1 row affected (0.00 sec)

mysql> create database ranran;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hejie |
| mysql |
| performance_schema |
| ranran |
| sys |
+--------------------+
6 rows in set (0.00 sec)

mysql> use hejie;
Database changed

mysql> create table student(id int not null, name varchar(100) not null, age tinyint);
Query OK, 0 rows affected (0.13 sec)

mysql> insert student value (1,'ranran',25);
Query OK, 1 row affected (0.14 sec)

mysql> select * from student;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | ranran | 25 |
+----+--------+------+
1 row in set (0.00 sec)

//由于实现主从需要主库从库数据一致,那么现在将主库的数据全备到从库
//先备份主库,在这之前得给数据库加上读锁,避免在备份期间其他人写入数据导致数据不一致。然后再开启一个终端进行备份(如需解锁,直接退出交互式界面即可)
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
[root@heyuanjie ~]# mysqldump -uroot -pran1027. --all-databases > all-20180909.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@heyuanjie ~]# ls
all-20180909.sql anaconda-ks.cfg
//将备份文件传到从库
[root@heyuanjie ~]# scp all-20180909.sql [email protected]:/root/
The authenticity of host '192.168.56.12 (192.168.56.12)' can't be established.
ECDSA key fingerprint is SHA256:71Ed1qYBfDL2xft2UGW2uzdrUldbxLnvqAn3JckI6Lw.
ECDSA key fingerprint is MD5:f5:c0:a8:14:02:9d:91:2b:36:55:6d:00:0a:41:e2:bf.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.12' (ECDSA) to the list of known hosts.
[email protected]'s password:
all-20180909.sql 100% 783KB 14.5MB/s 00:00
//这时可以在在从库主机上的root目录下看到备份数据
[root@hyj ~]# ls
all-20180909.sql anaconda-ks.cfg
//在从库上恢复主库的备份,并查看有哪些库,确保与主库一致
[root@hyj ~]# mysql -uroot -pran1027. < all-20180909.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@hyj ~]# mysql -uroot -pran1027. -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| hejie |
| mysql |
| performance_schema |
| ranran |
| sys |
+--------------------+

//在主数据库里创建一个同步账号授权给从数据库试用
mysql> create user 'ran'@'192.168.56.12' identified by 'ran1027.';
Query OK, 0 rows affected (0.00 sec)

//赋予权限,并刷新权限
mysql> grant replication slave on . to 'ran'@'192.168.56.12';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

//配置主数据库
[root@heyuanjie ~]# vi /etc/my.cnf
[root@heyuanjie ~]# cat /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
socket = /tmp/mysql.sock
datadir = /opt/data
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
log-bin=mysql-bin //启动binlog日志
log-error=/opt/data/mysqld.log
server-id=1 //数据库服务器唯一标识符,主库的server-id值必须比从库的大
//重启mysql
[root@heyuanjie ~]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL.Logging to '/opt/data/mysqld.log'.
. SUCCESS!

//查看主库状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

//配置从库
[root@hyj ~]# vi /etc/my.cnf
[root@hyj ~]# cat /etc/my.cnf
[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve

server-id=2 //设置从库的唯一标识符,从库的server-id值必须小于主库的该值
relay-log=mysql-relay-bin //启用中继日志relay-log
log-error=/opt/data/mysqld.log
//重启mysql
[root@hyj ~]# service mysqld restart
//配置并启动主从复制
mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.11',MASTER_USER='ran',MASTER_PASSWORD='ran1027.',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
mysql> start slave;

//注意master_log_file='mysql-bin.000001',master_log_pos=154; 这里面的内容需要跟之前查看的主库状态一致
//查看从服务器状态
mysql> show slave status \G
mysql> show slave status \G
1. row
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.56.11
Master_User: ran
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 154
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes //这里必须是yes
Slave_SQL_Running: Yes //这里必须是yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 527
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 5d8f5d0b-b382-11e8-8e01-000c290e4542
Master_Info_File: /opt/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

//测试验证,主库student表中插入数据
mysql> use hejie;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------+
| Tables_in_hejie |
+-----------------+
| student |
+-----------------+
1 row in set (0.00 sec)

mysql> select from student;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | ranran | 25 |
+----+--------+------+
1 row in set (0.00 sec)
mysql> insert student value (2,'woaini',99);
Query OK, 1 row affected (0.00 sec)
mysql> select
from student;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | ranran | 25 |
| 2 | woaini | 99 |
+----+--------+------+
2 rows in set (0.00 sec)

//在从库中查看是否同步
mysql> use hejie;
mysql> select * from student;
+----+--------+------+
| id | name | age |
+----+--------+------+
| 1 | ranran | 25 |
| 2 | woaini | 99 |
+----+--------+------+
2 rows in set (0.00 sec)

猜你喜欢

转载自blog.51cto.com/13729085/2172774
今日推荐