mysql主从复制

一 、实验环境

master 主服务器 192.168.198.120

slave 从服务器 192.168.198.121

[root@master_mysql ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@master_mysql ~]# uname -r
 2.6.32-431.el6.x86_64
[root@slave_mysql ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
[root@slave_mysql ~]# uname -r
 2.6.32-431.el6.x86_64

[root@master_mysql ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1 1024M  0 rom  
sdb      8:16   0  500G  0 disk 
└─sdb1   8:17   0  500G  0 part /home/data0
sdc      8:32   0  500G  0 disk 
└─sdc1   8:33   0  500G  0 part /home/data1
sdd      8:48   0  500G  0 disk 
└─sdd1   8:49   0  500G  0 part /home/data2
sda      8:0    0  500G  0 disk 
├─sda1   8:1    0  200M  0 part /boot
├─sda2   8:2    0  150G  0 part /
├─sda3   8:3    0    8G  0 part [SWAP]
├─sda4   8:4    0    1K  0 part 
├─sda5   8:5    0  300G  0 part /home
└─sda6   8:6    0 41.8G  0 part /opt
sde      8:64   0  500G  0 disk 
└─sde1   8:65   0  500G  0 part /home/data3

[root@slave_mysql ~]# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sr0     11:0    1  1024M  0 rom  
sda      8:0    0   500G  0 disk 
├─sda1   8:1    0   200M  0 part /boot
├─sda2   8:2    0   150G  0 part /
├─sda3   8:3    0     8G  0 part [SWAP]
├─sda4   8:4    0     1K  0 part 
├─sda5   8:5    0   200G  0 part /home
└─sda6   8:6    0 141.8G  0 part /opt
sdb      8:16   0   500G  0 disk 
└─sdb1   8:17   0   500G  0 part /home/data0
sdc      8:32   0   500G  0 disk 
└─sdc1   8:33   0   500G  0 part /home/data1
sde      8:64   0   500G  0 disk 
└─sde1   8:65   0   500G  0 part /home/data3
sdd      8:48   0   500G  0 disk 
└─sdd1   8:49   0   500G  0 part /home/data2

两台数据库服务器的的selinux都要disable(永久关闭selinux,请修改/etc/selinux/config,将SELINUX改为disabled)(两台机器重复同样操作)

[root@slave_mysql ~]# vi /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - SELinux is fully disabled.
SELINUX=disabled
# SELINUXTYPE= type of policy in use. Possible values are:
#       targeted - Only targeted network daemons are protected.
#       strict - Full SELinux protection.
SELINUXTYPE=targeted

重启操作系统

[root@slave_mysql ~]# reboot

二、MySQL源码编译安装mysql-5.6.38

1)、使用下面的命令检查是否安装有MySQL Server:,使用rpm -e 卸载mysql-server

[root@master_mysql ~]# rpm -qa |grep mysql
mysql-libs-5.1.73-8.el6_8.x86_64
mysql-5.1.73-8.el6_8.x86_64
mysql-server-5.1.73-8.el6_8.x86_64
[root@master_mysql ~]# rpm -e mysql-server
[root@master_mysql ~]# rpm -qa |grep mysql
mysql-libs-5.1.73-8.el6_8.x86_64
mysql-5.1.73-8.el6_8.x86_64

2)、两台服务器改防火墙设置,打开3306端口,编辑防火墙配置文件增加如下行:

 //*****************************************************************
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
//******************************************************************

[root@master_mysql ~]#  vi /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
重启防火墙
[root@master_mysql ~]# service iptables restart
iptables:将链设置为政策 ACCEPT:filter                    [确定]
iptables:清除防火墙规则:                                 [确定]
iptables:正在卸载模块:                                   [确定]
iptables:应用防火墙规则:                                 [确定]

[root@slave_mysql ~]#  vi /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
 重启防火墙
[root@slave_mysql ~]# service iptables restart
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]
iptables: Applying firewall rules:                         [  OK  ]

3)、新增mysql用户组:

[root@master_mysql ~]# groupadd mysql
[root@slave_mysql ~]#  groupadd mysql

4)、新增mysql用户,并添加到mysql用户组:

[root@master_mysql ~]# useradd -r -g mysql mysql
[root@slave_mysql ~]# useradd -r -g mysql mysql

5)、新建MySQL执行文件目录(后面会把编译好的mysql程序安装到这个目录):

[root@master_mysql ~]# mkdir -p /usr/local/mysql
[root@slave_mysql ~]# mkdir -p /usr/local/mysql

6)、新建MySQL数据库数据文件目录

[root@master_mysql ~]#mkdir -p /home/data0/mysql/data
[root@master_mysql ~]#mkdir -p /home/data1/mysql/logs
[root@master_mysql ~]#mkdir -p /homedata2//mysql/temp
[root@slave_mysql ~]#mkdir -p /home/data0/mysql/data
[root@slave_mysql ~]#mkdir -p /home/data1/mysql/logs
[root@slave_mysql ~]#mkdir -p /homedata2//mysql/temp

(注意:上面的logs及temp目录是为了以后将MySQL的数据文件与执行程序文件分离,如果你打算设置
到不同的路径,注意修改对应的执行命令和数据库初始化脚本。正式生产环境,建议数据目录和日志目录
都使用单独的分区来挂载,不同分区属于不同的磁盘或磁盘组。)

7)、增加PATH环境变量搜索路径:在profile文件末尾增加两行

//*******************************************************
# mysql env param

PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH

export PATH
//*******************************************************

[root@master_mysql ~]# vi /etc/profile
# mysql env param
PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
export PATH
[root@master_mysql ~]#source /etc/profile

[root@slave_mysql ~]# vi /etc/profile
# mysql env param
PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
export PATH
[root@slave_mysql ~]# source /etc/profile

8)、安装编译MySQL需要的依赖包:

(mysql从5.5版本开始,不再使用./configure编译,而是使用cmake编译器,具体的cmake编译参数安装基本依赖包,先用yum安装cmake、automake 、autoconf ,另MySQL 5.5.x需要最少安装的包有:bison,gcc、gcc-c++、ncurses-devel):

[root@master_mysql ~]# yum install make cmake gcc gcc-c++ bison bison-devel ncurses ncurses-devel autoconf automake -y
[root@slave_mysql ~]# yum install make cmake gcc gcc-c++ bison bison-devel ncurses ncurses-devel autoconf automake -y

9) 、进入/opt目录,下载mysql-5.6.38.tar.gz 源代码到/opt目录:

[root@master_mysql ~]# cd /opt
[root@master_mysql opt]# wget http://ftp.ntu.edu.tw/MySQL/Downloads/MySQL-5.6/mysql-5.6.38.tar.gz
[root@slave_mysql ~]# cd /opt
[root@slave_mysql opt]# wget http://ftp.ntu.edu.tw/MySQL/Downloads/MySQL-5.6/mysql-5.6.38.tar.gz

10) 、开始编译安装mysql-5.6.38:

解压缩源码包:

[root@master_mysql opt]# tar -zxvf mysql-5.6.38
[root@slave_mysql opt]# tar -zxvf mysql-5.6.38

进入解压缩源码目录:

[root@master_mysql opt]# cd mysql-5.6.38
[root@slave_mysql opt]# cd mysql-5.6.38

使用cmake源码安装mysql(如果你打算安装到不同的路径,注意修改下面语句中/usr/local/mysql和/home/data0/mysql/data路径!)

[root@master_mysql mysql-5.6.38]#  cmake \

 -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \

 -DDEFAULT_CHARSET=utf8 \

 -DDEFAULT_COLLATION=utf8_general_ci \

 -DWITH_MYISAM_STORAGE_ENGINE=1 \

 -DWITH_INNOBASE_STORAGE_ENGINE=1 \

 -DWITH_ARCHIVE_STORAGE_ENGINE=1 \

 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

 -DWITH_MEMORY_STORAGE_ENGINE=1 \

 -DWITH_READLINE=1 \

 -DENABLED_LOCAL_INFILE=1 \

 -DMYSQL_DATADIR=/home/data0/mysql/data \

 -DMYSQL_USER=mysql \

 -DMYSQL_TCP_PORT=3306 \

 -DENABLE_DOWNLOADS=1

[root@slave_mysql mysql-5.6.38]# cmake \

 -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

 -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \

 -DDEFAULT_CHARSET=utf8 \

 -DDEFAULT_COLLATION=utf8_general_ci \

 -DWITH_MYISAM_STORAGE_ENGINE=1 \

 -DWITH_INNOBASE_STORAGE_ENGINE=1 \

 -DWITH_ARCHIVE_STORAGE_ENGINE=1 \

 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \

 -DWITH_MEMORY_STORAGE_ENGINE=1 \

 -DWITH_READLINE=1 \

 -DENABLED_LOCAL_INFILE=1 \

 -DMYSQL_DATADIR=/home/data0/mysql/data \

 -DMYSQL_USER=mysql \

 -DMYSQL_TCP_PORT=3306 \

 -DENABLE_DOWNLOADS=1

上面的这些复制完,回车,然后就开始cmake的过程,一般时间不会很长。

配置解释:

-DCMAKE_INSTALL_PREFIX=/usr/local/mysql 设置安装目录

-DMYSQL_DATADIR=/home/data0/mysql/data 设置数据库存放目录

-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock 设置UNIX socket 目录

-DMYSQL_USER=mysql 设置运行用户

-DDEFAULT_CHARSET=utf8 设置默认字符集,默认latin1

-DEFAULT_COLLATION=utf8_general_ci 设置默认校对规则,默认latin1_general_ci

-DWITH_INNOBASE_STORAGE_ENGINE=1 添加InnoDB引擎支持

-DENABLE_DOWNLOADS=1 自动下载可选文件,比如自动下载谷歌的测试包

-DMYSQL_TCP_PORT=3306 设置服务器监听端口,默认3306

-DSYSCONFDIR=/etc 设置my.cnf所在目录,默认为安装目录)  

cmake结束后开始编译源码,这一步时间会较长,请耐心等待:

[root@master_mysql mysql-5.6.38]# make
[root@slave_mysql mysql-5.6.38]#  make

安装编译好的程序:

[root@master_mysql mysql-5.6.38]# make install
[root@slave_mysql mysql-5.6.38]#  make install

(注意:如果需要重装mysql,在/usr/local/src/mysql-5.6.26在执行下make install就可以了,不需要再cmake和make)

清除安装临时文件:

[root@master_mysql mysql-5.6.38]# make clean
[root@slave_mysql mysql-5.6.38]# make clean

11 、修改mysql目录拥有者为mysql用户:

[root@master_mysql mysql-5.6.38]# chown -Rf mysql:mysql /usr/local/mysql
[root@master_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data0/mysql
[root@master_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data1/mysql
[root@master_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data2/mysql

[root@slave_mysql mysql-5.6.38]# chown -Rf mysql:mysql /usr/local/mysql
[root@slave_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data0/mysql
[root@slave_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data1/mysql
[root@slave_mysql mysql-5.6.38]# chown -Rf mysql:mysql /home/data2/mysql

12、进入mysql执行程序的安装路径:

[root@master_mysql mysql-5.6.38]# cd /usr/local/mysql
[root@slave_mysql mysql-5.6.38]# cd /usr/local/mysql

13、执行初始化配置脚本,创建系统自带的数据库和表(注意:路径/home/data0/mysql/data需要换成你自定定义的数据库存放路径):

[root@master_mysql mysql]# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/home/data0/mysql/data 

[root@slave_mysql mysql]# scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/home/data0/mysql/data 

14 、初始化脚本在/usr/local/mysql/下生成了配置文件my.cnf,需要更改该配置文件的所有者:

[root@master_mysql mysql]# ls -lah 
[root@slave_mysql mysql]# ls -lah
[root@master_mysql mysql]#chown -Rf mysql:mysql /usr/local/mysql/my.cnf
[root@slave_mysql mysql]#chown -Rf mysql:mysql /usr/local/mysql/my.cnf

15、注意:
(1)Tips:在启动MySQL服务时,会按照一定次序搜索my.cnf,先在/etc目录下找,找不到则会搜索
mysql程序目录下是否有my.cnf

(2)需要注意CentOS 6版操作系统的最小安装完成后,即使没有安装mysql,在/etc目录下也会存在一个my.cnf文件,建议将此文件更名为其他的名字,否则该文件会干扰源码安装的MySQL的正确配置,造成无法启动。修改/etc/my.cnf操作如下:

可以:mv /etc/my.cnf /etc/my.cnf.bak

也可以:删除掉/etc/my.cnf这个文件:rm /etc/my.cnf

如果你需要用于生产环境,不要急着做下面的mysql启动操作。建议把上一步骤中mysql初始化生成的/usr/local/mysql/my.cnf删除,然后把你优化好的mysql配置文件my.cnf放到/etc下。(这是做mysql主从复制和mysql优化的经验!)

(我们这里使用/etc/my.cnf)

16 、编辑/etc/my.cnf:

[root@master_mysql mysql]# vi /etc/my.cnf
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock

[mysqld]

character-set-server = utf8

collation-server = utf8_general_ci

skip-external-locking

skip-name-resolve

user = mysql

port = 3306

basedir = /usr/local/mysql

datadir = /home/data0/mysql/data

tmpdir = /home/data2/mysql/temp

# server_id = .....

socket = /usr/local/mysql/mysql.sock

log-error = /home/data0/mysql/logs/mysql_error.log

pid-file = /home/data0/mysql/mysql.pid

open_files_limit = 10240

back_log = 600

max_connections=500

max_connect_errors = 6000

wait_timeout=605800

#open_tables = 600

#table_cache = 650

#opened_tables = 630

max_allowed_packet = 32M

sort_buffer_size = 4M

join_buffer_size = 4M

thread_cache_size = 300

query_cache_type = 1

query_cache_size = 256M

query_cache_limit = 2M

query_cache_min_res_unit = 16k

tmp_table_size = 256M

max_heap_table_size = 256M

key_buffer_size = 256M

read_buffer_size = 1M

read_rnd_buffer_size = 16M

bulk_insert_buffer_size = 64M

lower_case_table_names=1

default-storage-engine = INNODB

innodb_buffer_pool_size = 2G

innodb_log_buffer_size = 32M

innodb_log_file_size = 128M

innodb_flush_method = O_DIRECT

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

thread_concurrency = 32

long_query_time= 2

slow-query-log = on

slow-query-log-file = /home/data0/mysql/logs/mysql-slow.log 

[mysqldump]

 quick

max_allowed_packet = 32M

[mysqld_safe]

log-error=/var/log/mysqld.log

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

[root@slave_mysql mysql]# vi /etc/my.cnf

[client]
port = 3306
socket = /usr/local/mysql/mysql.sock

[mysqld]

character-set-server = utf8

collation-server = utf8_general_ci

skip-external-locking

skip-name-resolve

user = mysql

port = 3306

basedir = /usr/local/mysql

datadir = /home/data0/mysql/data

tmpdir = /home/data2/mysql/temp

# server_id = .....

socket = /usr/local/mysql/mysql.sock

log-error = /home/data0/mysql/logs/mysql_error.log

pid-file = /home/data0/mysql/mysql.pid

open_files_limit = 10240

back_log = 600

max_connections=500

max_connect_errors = 6000

wait_timeout=605800

#open_tables = 600

#table_cache = 650

#opened_tables = 630

max_allowed_packet = 32M

sort_buffer_size = 4M

join_buffer_size = 4M

thread_cache_size = 300

query_cache_type = 1

query_cache_size = 256M

query_cache_limit = 2M

query_cache_min_res_unit = 16k

tmp_table_size = 256M

max_heap_table_size = 256M

key_buffer_size = 256M

read_buffer_size = 1M

read_rnd_buffer_size = 16M

bulk_insert_buffer_size = 64M

lower_case_table_names=1

default-storage-engine = INNODB

innodb_buffer_pool_size = 2G

innodb_log_buffer_size = 32M

innodb_log_file_size = 128M

innodb_flush_method = O_DIRECT

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

thread_concurrency = 32

long_query_time= 2

slow-query-log = on

slow-query-log-file = /home/data0/mysql/logs/mysql-slow.log 

[mysqldump]

 quick

max_allowed_packet = 32M

[mysqld_safe]

log-error=/var/log/mysqld.log

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

17 复制服务启动脚本:

[root@master_mysql mysql]#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
[root@slave_mysql mysql]#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql

18、启动MySQL服务:

[root@master_mysql mysql]# service mysql start

Starting MySQL.. SUCCESS!

[root@slave_mysql mysql]# service mysql start

Starting MySQL.. SUCCESS!

(初次启动会在/usr/local/mysql目录下生成mysql.sock文件)

19、设置MySQL开机自动启动服务:

[root@master_mysql mysql]#chkconfig mysql on

[root@slave_mysql mysql]# chkconfig mysql on

设置MySQL数据库root用户的本地登录密码(初始用户没有密码):

[root@master_mysql mysql]# mysqladmin -u root password 'baidu.com@ip'

[root@slave_mysql mysql]# mysqladmin -u root password 'baidu.com@ip'

20 、用密码登录MySQL

[root@master_mysql mysql]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.6.38-log Source distribution

Copyright (c) 2000, 2017, 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> 
## 允许root远程登录,设置远程登录密码:baidu.com@ip

mysql> use mysql;

mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'baidu.com@ip' WITH GRANT OPTION;

mysql> flush privileges;

mysql> exit;

注意:真实生产环境,应用操作不要使用root用户。



[root@slave_mysql mysql]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.38-log Source distribution

Copyright (c) 2000, 2017, 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> 

 ## 允许root远程登录,设置远程登录密码:baidu.com@ip

mysql> use mysql;

mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'baidu.com@ip' WITH GRANT OPTION;

mysql> flush privileges;

mysql> exit;

注意:真实生产环境,应用操作不要使用root用户。

21、两台服务器运行安全设置脚本,强烈建议生产服务器使用(可选):

[root@master_mysql ~]#/usr/local/mysql/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL

SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MySQL to secure it, we'll need the current

password for the root user.  If you've just installed MySQL, and

you haven't set the root password yet, the password will be blank,

so you should just press enter here.

Enter current password for root (enter for none):  ----->此处输入root密码

OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL

root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n  -----> 上已为root设置了密码,此处可输n

... skipping.

By default, a MySQL installation has an anonymous user, allowing anyone

to log into MySQL without having to have a user account created for

them.  This is intended only for testing, and to make the installation

go a bit smoother.  You should remove them before moving into a

production environment.

Remove anonymous users? [Y/n] Y  ------> 删除匿名用户

 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This

ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] n  -----> 一般不允许root远程登录,可添加普通用户,然后设置允许远程登录

... skipping.

By default, MySQL comes with a database named 'test' that anyone can

access.  This is also intended only for testing, and should be removed

before moving into a production environment.

Remove test database and access to it? [Y/n] Y  -----> 删除test库及相应权限

   - Dropping test database...

  ... Success!

  - Removing privileges on test database...

  ... Success!

  Reloading the privilege tables will ensure that all changes made so far

 will take effect immediately.

Reload privilege tables now? [Y/n] Y -----> 重新加载权限表使设置生效

... Success!

All done!  If you've completed all of the above steps, your MySQL

installation should now be secure.

Thanks for using MySQL!


 Cleaning up...

22 、重启服务器,检测mysql是否能开机自动启动:

[root@master_mysql ~]# reboot
[root@slave_mysql ~]# reboot

三、MySQL主从复制

a) 、MySQL主从复制的方式

MySQL5.6开始主从复制有两种方式:基于日志(binlog)、基于GTID(全局事务标示符)。

本实验主要讲基于日志(binlog)的复制。

MySQL主从复制(也称A/B复制)的原理

(1) Master将数据改变记录到二进制日志(binary log)中,也就是配置文件log-bin指定的文件,这些记录叫做二进制日志事件(binary log events);

(2) Slave通过I/O线程读取Master中的binary log events并写入到它的中继日志(relay log);

(3) Slave重做中继日志中的事件,把中继日志中的事件信息一条一条的在本地执行一次,完成数据在本地的存储,从而实现将改变反映到它自己的数据(数据重放)。

b)、主从配置需要注意的点

(1)主从服务器操作系统版本和位数一致;

(2) Master和Slave数据库的版本要一致;

(3) Master和Slave数据库中的数据要一致;

(4) Master开启二进制日志,Master和Slave的server_id在局域网内必须唯一;

c) 、主从配置的简要步骤

1、Master上的配置

(1) 安装数据库;

(2) 修改数据库配置文件,指明server_id,开启二进制日志(log-bin);

(3) 启动数据库,查看当前是哪个日志,position号是多少;

(4) 登录数据库,授权数据复制用户(IP地址为从机IP地址,如果是双向主从,这里的还需要授权本机的IP地址,此时自己的IP地址就是从IP地址);

(5) 备份数据库(记得加锁和解锁);

(6) 传送备份数据到Slave上;

(7) 启动数据库;

以下步骤,为单向主从搭建成功,想搭建双向主从需要的步骤:

(1) 登录数据库,指定Master的地址、用户、密码等信息(此步仅双向主从时需要);

(2) 开启同步,查看状态;

2 、Slave上的配置

(1) 安装数据库;

(2) 修改数据库配置文件,指明server_id(如果是搭建双向主从的话,也要开启二进制日志log-bin);

(3) 启动数据库,还原备份;

(4) 查看当前是哪个日志,position号是多少(单向主从此步不需要,双向主从需要);

(5) 指定Master的地址、用户、密码等信息;

(6) 开启同步,查看状态。

d)、修改Master的配置文件/etc/my.cnf

 ## 在 [mysqld] 中增加以下配置项

[root@master_mysql ~]# vi /etc/my.cnf
## 设置server_id,一般设置为IP

server_id=120

## 复制过滤:需要备份的数据库,输出binlog

#binlog-do-db=baiduwaimai

## 复制过滤:不需要备份的数据库,不输出(mysql库一般不同步)

binlog-ignore-db=mysql

## 开启二进制日志功能,可以随便取,最好有含义 

log-bin=bigdata-mysql-bin

## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存

binlog_cache_size=1M

## 主从复制的格式(mixed,statement,row,默认格式是statement)

binlog_format=mixed

## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。

expire_logs_days=7

## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

e) 、启动/重启Master数据库服务,登录数据库,创建数据同步用户,并授予相应的权限

[root@master_mysql ~]# service mysql restart
[root@master_mysql ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.38-log Source distribution

Copyright (c) 2000, 2017, 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> 

 ##创建数据同步用户,并授予相应的权限
mysql> grant replication slave, replication client on *.* to 'repl'@'192.168.198.121' identified by 'baidu.com@ip';

Query OK, 0 rows affected (0.00 sec)

## 刷新授权表信息
mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

## 查看position号,记下position号(从机上需要用到这个position号和现在的日志文件)

mysql> show master status;

创建baiduwaimai库、表,并写入一定量的数据,用于模拟现有的业务系统数据库
mysql>create database if not exists baiduwaiami default charset utf8 collate mysql>utf8_general_ci;

mysql>use baiduwaimai;

mysql>DROP TABLE IF EXISTS `baiduwaimai_user`;

mysql>CREATE TABLE `baiduwaimai_user` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(255) NOT NULL DEFAULT '' COMMENT '用户名',
`pwd` varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息表';

mysql>INSERT INTO `baiduwaimai_user` VALUES (1,'吴添水','123456'),(2,'张俊杰','123456'),(3,'张成显','123456');

f) 、为保证Master和Slave的数据一致,我们采用主备份,从还原来实现初始数据一致

## 先临时锁表
mysql> flush tables with read lock;

Query OK, 0 rows affected (0.00 sec)

## 这里我们实行全库备份,在实际中,我们可能只同步某一个库,那也可以只备份一个库

[root@master_mysql ~]# mysqldump -p3306 -uroot -p --add-drop-table baiduwaimai > /tmp/baiduwaimai-master_bak.sql;

Warning: Using a password on the command line interface can be insecure.
Enter password:

[root@master_mysql ~]# cd /tmp
[root@master_mysql tmp]# ll
总用量 4
 -rw-r--r-- 1 root root 2153 1月  10 00:53 baiduwaimai-master_bak.sql

注意:实际生产环境中大数据量(超2G数据)的备份,建议不要使用mysqldump进行比分,因为会非常慢。此时推荐使用XtraBackup 进行备份。

解锁表
mysql> unlock tables;

Query OK, 0 rows affected (0.00 sec)

将Master上备份的数据远程传送到Slave上,以用于Slave配置时恢复数据

[root@master_mysql ~]#scp /tmp/baiduwaimai-master_bak.sql root@192.168.198.121:/tmp/

root@192.168.198.121's password:
baiduwaimai-master_bak.sql                         100%  629KB 629.2KB/s   00:00   

g) 接下来处理Slave(192.168.198.121),配置文件只需修改一项,其余配置用命令来操作

root@slave_mysql ~]# vi /etc/my.cnf

## 在 [mysqld] 中增加以下配置项
## 设置server_id,一般设置为IP

server_id=121

## 复制过滤:需要备份的数据库,输出binlog

#binlog-do-db=baiduwaimai

##复制过滤:不需要备份的数据库,不输出(mysql库一般不同步)

binlog-ignore-db=mysql

## 开启二进制日志,以备Slave作为其它Slave的Master时使用

log-bin=bigdata-mysql-slave1-bin

## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存

binlog_cache_size = 1M

## 主从复制的格式(mixed,statement,row,默认格式是statement)

binlog_format=mixed

## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。

expire_logs_days=7

## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。

## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致

slave_skip_errors=1062

## relay_log配置中继日志

relay_log=bigdata-mysql-relay-bin

## log_slave_updates表示slave将复制事件写进自己的二进制日志

log_slave_updates=1

## 防止改变数据(除了特殊的线程)

read_only=1

h) 、保存后重启MySQL服务,还原备份数据

[root@slave_mysql ~]# service mysql restart
Shutting down MySQL..[  OK  ]
Starting MySQL..[  OK  ]

Slave上创建相同库:

mysql>create database if not exists baiduwaimai default charset utf8 collate utf8_general_ci;

mysql>use baiduwaimai;

导入数据

[root@slave_mysql ~]# mysql -uroot -p baiduwaimai < /tmp/baiduwaimai-master_bak.sql
Enter password:

i) 、登录Slave数据库,添加相关参数
(Master的IP、端口、同步用户、密码、position号、读取哪个日志文件)

[root@slave_mysql ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.6.38-log Source distribution

Copyright (c) 2000, 2017, 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> change master to master_host='192.168.198.120', master_user='sys-root', master_password='baidu.com@ip', master_port=3306, master_log_file='bigdata-mysql-bin.000002', master_log_pos= 1842, master_connect_retry=30;

上面执行的命令的解释:
master_host='192.168.198.120'                  ## Master的IP地址
master_user='sys-root'                         ## 用于同步数据的用户(在Master中授权的用户)
master_password='baidu.com@ip'                 ## 同步数据用户的密码
master_port=3306                               ## Master数据库服务的端口
master_log_file='bigdata-mysql-bin.000002'     ##指定Slave从哪个日志文件开始读复制数据(可在Master上使用show master status查看到日志文件名)
master_log_pos=1842                            ## 从哪个POSITION号开始读
master_connect_retry=30                        ##当重新建立主从连接时,如果连接建立失败,间隔多久后重试。单位为秒,默认设置为60秒,同步延迟调优参数。

j) 、查看主从同步状态

mysql> show slave status\G;

可看到Slave_IO_State为空, Slave_IO_Running和Slave_SQL_Running是No,表明Slave还没有开始复制过程。

## 开启主从同步

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

## 再查看主从同步状态
mysql> show slave status\G;

主要看以下两个参数,这两个参数如果是Yes就表示主从同步正常

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

由截图中的主从同步状态信息可以看出,我们配置的主从同步是正常的。

k) 、主从数据复制同步测试

在Master中的baiduwaimai库上变更数据的同步测试;

mysql> INSERT INTO `baiduwaimai_user` VALUES (6,'林士哲','123456'),(7,'吴旭康2','123456');

1 、Master中添加完之后,登录Slave中查看数据是否已同步

mysql> select * from baiduwaimai_user;
+----+------------+--------+
| Id | userName   | pwd    |
+----+------------+--------+
|  1 | 吴添水     | 123456 |
|  2 | 张俊杰     | 123456 |
|  3 | 张成显     | 123456 |
|  6 | 林士哲     | 123456 |
|  7 | 吴旭康2    | 123456 |
+----+------------+--------+
5 rows in set (0.00 sec)

2 、 在Master上新建一个didi库

mysql> create database if not exists didi default charset utf8 collate utf8_general_ci;

在Slave中查看数据库

mysql> show databases;


 mysql> show databases;
 +--------------------+
 | Database           |
 +--------------------+
 | information_schema |
 | baiduwaimai        |
 | didi               |
 | mysql              |
 | performance_schema |
 +--------------------+
 5 rows in set (0.00 sec)

最终的测试结果是,在Master中的操作,都成功同步到了Slave。
如果您觉得这篇文章对您有帮助,不妨支持我一下!
------ 本文结束 ------

版权声明

Stefanie'Notes by Stefanie is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Stefanie创作并维护的Stefanie'Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Stefanie'Notes 博客( https://linshizhe.github.io/ ),版权所有,侵权必究。