文章目录
- 一、基本了解
- 二、主从原理
- 三、主从复制
- 3.1 从无到有
- 3.1.1 服务器初始化
- 3.1.2 配置主库
- 3.1.3 配置从库
- 3.1.4 效果验证
- 3.2 从有到无
- 3.2.1 主库全备,并同步到从库
- 3.2.2 配置主库
- 3.2.3 配置从库
- 3.2.4 效果验证
- 四、数据库运维
- 4.1 几个参数
- 4.2 查看进程列表
一、基本了解
什么是主从数据库?
- 从数据库是主数据库的备份,当主库数据变化时从数据库要更新,这些数据库软件可以设计更新周期。这是提高信息安全的手段。
- 主从数据库服务器不在一个地理位置上,当发生意外时数据库可以保存。
主从分工:
- Master负责写操作的负载,读操作则分摊到Slave上进行。
- 读/写的比例大概在 10:1左右 ,这样可以大大提高读取的效率。
为什么要读写分离?
- 写操作涉及到锁的问题,行锁、表锁、块锁,都是比较降低系统执行效率的事情。
- 读写分离可以把写操作集中在一个节点上,而读操作在其他的N个节点上进行,可以有效的提高了读的效率,保证系统的高可用性。
主从复制用途:
- 实时灾备,用于故障切换。
- 读写分离,提供查询服务。
- 备份,避免影响业务
主从部署必要条件:
- 主库开启binlog日志(设置log-bin参数)
- 主从server-id不同。
- 从库服务器能连通主库。
主从形式:
- 一主一从。
- 主主复制。
- 一主多从,可以扩展系统读取的性能,因为读是在从库读取的。
- 多主一从,5.7开始支持。
- 联级复制,不常用。
二、主从原理
master操作:
- 当master数据发生变化时,该事件变化会按照顺序写入bin-log中。当slave链接到master时,master会为slave开启binlog dump线程。
- 当master的bin-log发生变化时,bin-log dump线程会通知slave,并将相应的binlog内容发送给slave。
slave操作:
- 从库生成两个线程,一个I/O线程,一个SQL线程 。
- I/O线程请求主库的bin-log,并将得到的bin-log日志写到relay log(中继日志) 文件中。
- SQL线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,达到最终数据一致的目的
主从复制过程:
- MySQL之间数据复制的基础是二进制日志文件(binlog)。
- MySQL数据库一旦启用二进制日志后,库中所有写操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化。
- 若发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。
主从同步主要有三种形式:
- statement: 将对数据库操作的sql语句写入bin-log中。
- row: 将每一条数据的变化写入bin-log中。
- mixed: statement与row的混合。Mysql决定何时写statement格式的bin-log,何时写row格式的bin-log。
三、主从复制
配置思路:
- 确保从数据库与主数据库里的数据一样。
- 在主数据库里创建一个同步账号授权给从数据库使用。
- 配置主数据库(修改配置文件)。
- 配置从数据库(修改配置文件)。
1.脚本安装mysql,服务端和客户端都需要安装。
//准备安装包。
[root@localhost opt]# ll bck/
-rw-r--r--. 1 7161 31415 678018165 Dec 8 02:53 mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz
//安装脚本。
[root@localhost opt]# cat install.sh
#!/bin/bash
installdir=/usr/local
packname=mysql-5.7.41-linux-glibc2.12-x86_64.tar.gz ##需要修改。
unpck=$installdir/$(echo $packname| awk -F'.tar' '{print $1}')
port=3306
datadir=/data
PATH=$installdir/mysql/bin:$PATH
yum -y -q install perl ncurses-compat-libs &>/dev/null
read -p "请输入,你要创建几个实例就输入数字几:" num
read -p "请输入,你要为数据库设置什么密码:" num1
id mysql &>/dev/null || /usr/sbin/useradd -r -M -s /sbin/nologin mysql
[ ! -d $installdir ] && mkdir -p $installdir
if [ ! -d $unpck ];then
echo "正在解压$packname至$installdir下"
tar xf /opt/bck/$packname -C $installdir ##根据实际情况修改。
fi
ln -s $unpck $installdir/mysql &>/dev/null
chown -R mysql.mysql $installdir/mysql*
echo "export PATH=$installdir/mysql/bin:\$PATH" > /etc/profile.d/mysql.sh
source /etc/profile.d/mysql.sh
if [ $num -gt 1 ];then
cat > /etc/my.cnf <<EOF
[mysqld_multi]
mysqld = $installdir/mysql/bin/mysqld_safe
mysqladmin = $installdir/mysql/bin/mysqladmin
EOF
fi
for i in $(seq $num);do
if [ $i -ne 1 ]; then
let port++
fi
mkdir -p $datadir/$port &>/dev/null
chown -R mysql.mysql $datadir
wcinit=$(ls $datadir/$port|wc -l)
if [ $wcinit -eq 0 ];then
echo "正在初始化$port实例"
$installdir/mysql/bin/mysqld --initialize-insecure --datadir=$datadir/$port --user=mysql --explicit_defaults_for_timestamp &> /dev/null
fi
if [ $num -eq 1 ];then
cat > /etc/my.cnf <<EOF
[mysqld]
basedir = $installdir/mysql
datadir = $datadir/$port
socket = /tmp/mysql.sock
port = 3306
pid-file = $datadir/$port/mysql.pid
user = mysql
skip-name-resolve
EOF
\cp -a $installdir/mysql/support-files/mysql.server /etc/init.d/mysqld
sed -ri "s#^(basedir=).*#\1$installdir/mysql#g" /etc/init.d/mysqld
sed -ri "s#^(datadir=).*#\1$datadir#g" /etc/init.d/mysqld
service mysqld start
$installdir/mysql/bin/mysql -uroot -e "set password = password('$num1');"
else
cat >> /etc/my.cnf <<EOF
[mysqld$port]
datadir = $datadir/$port
port = $port
socket = /tmp/mysql$port.sock
pid-file = $datadir/$port/mysql_$port.pid
log-error=/var/log/$port.log
EOF
$installdir/mysql/bin/mysqld_multi start $port
sleep 3
$installdir/mysql/bin/mysql -uroot -S /tmp/mysql$port.sock -e "set password = password('$num1');"
fi
done
2.保证2台数据库都能登录。
3.1 从无到有
- 主库、从库都是从无到有,都是从部署开始。
- 两台服务器都需要安装mysql-5.7版本,且从库的配置不能低于主库,至少也是跟主库配置一样。
环境说明 | 释义 |
---|---|
主库192.168.130.160 | 无数据 |
从库192.168.130.161 | 无数据 |
3.1.1 服务器初始化
1.关闭防火墙和selinux。
//主库、从库服务器都要操作。
systemctl stop firewalld
systemctl disable firewalld
//关闭selinux。
setenforce 0
2.主库创建同步账号授权给从库使用。
grant replication slave on *.* to root@192.168.130.161 identified by 'citms';
flush privileges;
3.1.2 配置主库
1.配置文件/etc/my.cnf 添加2个参数,重启服务。
[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id = 10 //添加这两行
log-bin = mysql_bin
//重启。
service mysqld restart
2.查看主库状态。
mysql -uroot -pcitms -S /tmp/mysql.sock
show master status;
3.1.3 配置从库
1.配置文件/etc/my.cnf 添加2个参数,重启服务。
[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id = 20 //从库数值必须大于主库。
log-bin = myrelay //启用中继日志relay-log
//重启。
service mysqld restart
2.进入本地数据库,配置并启动主从复制。
mysql -uroot -pcitms -S /tmp/mysql.sock
mysql> change master to master_host='192.168.130.160',master_user='root',master_password='citms',master_log_file='mysql_bin.000001',master_log_pos=154;
mysql> start slave;
3.1.4 效果验证
1.主库创建数据库qingjun,从库查看结果。
3.2 从有到无
- 主库以提前存在,并有数据;从库不存在,需要部署后再同步主库数据。
- 两台服务器都需要安装mysql-5.7版本,且从库的配置不能低于主库,至少也是跟主库配置一样。
环境说明 | 释义 |
---|---|
主库192.168.130.160 | 有数据 |
从库192.168.130.161 | 无数据 |
1.主库创建一个库和表,插入数据;从库没有数据。
//主库插入数据。
mysql> create database school;
mysql> use school;
mysql> create table student(id int not null primary key auto_increment,name varchar(50),age tinyint);
mysql> insert student(name,age) values('tom',29),('jerry',24),(',zhangsan',18),('lisi',56);
3.2.1 主库全备,并同步到从库
- 为确保从库与主库里数据一样,先全备主库并还原到从库。
1.主库锁表。
flush tables with read lock;
2.主库全备,把数据文件传给从库恢复数据。
//主库全备。
mysqldump -uroot -pcitms --all-databases > all.sql
scp all.sql root@192.168.130.161:/opt/
//从库恢复数据。
mysql -uroot -pcitms < /opt/all.sql
3.主从数据一致后,主库退出解锁,创建授权账户给从库使用。
//主库退出解锁。
mysql> quit
Bye
//主库创建用户使其能在192.168.130.161上登陆。
create user qingjun@192.168.130.161 identified by '123456';
grant replication slave on *.* to 'qingjun'@'192.168.130.161';
flush privileges;
3.2.2 配置主库
1.配置文件/etc/my.cnf 添加2个参数,重启服务。
[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id = 10 //添加这两行
log-bin = mysql_bin
//重启。
service mysqld restart
2.查看主库状态。
mysql -uroot -pcitms -S /tmp/mysql.sock
show master status;
3.2.3 配置从库
1.配置文件/etc/my.cnf 添加2个参数,重启服务。
[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id = 20 //从库数值必须大于主库。
log-bin = myrelay //启用中继日志relay-log
//重启。
service mysqld restart
2.进入本地数据库,配置并启动主从复制。
mysql -uroot -pcitms -S /tmp/mysql.sock
mysql> change master to master_host='192.168.130.160',master_user='root',master_password='citms',master_log_file='mysql_bin.000001',master_log_pos=154;
mysql> start slave;
3.2.4 效果验证
1.主库插入数据,从库查看。
//主库插入数据。
use school;
insert student(name,age) values('qianliu',30);
四、数据库运维
4.1 几个参数
- Slave_IO_Running: Yes,参数表示主从数据库连接状态,防火墙和网络问题会影响该参数。
- Slave_SQL_Running: Yes,参数表示主从传输的数据过程出现问题,为NO时可以查看时哪条命令出现了问题。
- Seconds_Behind_Master: 0,参数表示主从数据同步的延迟时间。
- Last_IO_Errno: 0,若第一个yes出现问题问题,该参数会显示其错误日志。
- Last_SQL_Errno: 0,若第二个yes出现问题问题,该参数会显示其错误日志。
//从库检查。
mysql> show slave status\G
4.2 查看进程列表
1.查看进程。
//从库查看。
show processlist\G
2.根据id杀进程。
3.此时再查看从库状态,第二个yes变成no。
4.此时可以手动把进程启动起来。
//启动。
start slave;
//停止。
stop slave;