主从复制、读写分离一般是一起使用的。目的很简单,就是为了提高数据库的并发性能。如果一台mater只负责写操作,两台salve只负责读操作,性能不就能大大提高了吗?所以主从复制、读写分离就是为了数据库能支持更大的并发。随着业务量的扩展、如果是单机部署的MySQL,会导致I/O频率过高。采用主从复制、读写分离可以提高数据库的可用性。
1、当Master节点进行insert、update、delete操作时,会按顺序写入到binlog中。
2、salve从库连接master主库,Master有多少个slave就会创建多少个binlog dump线程。
3、当Master节点的binlog发生变化时,binlog dump 线程会通知所有的salve节点,并将相应的binlog内容推送给slave节点。
4、I/O线程接收到 binlog 内容后,将内容写入到本地的 relay-log。
5、SQL线程读取I/O线程写入的relay-log,并且根据 relay-log 的内容对从数据库做对应的操作。
二台虚拟机CentOS演示,IP分别是26(Master),27(Slave)。
[root@shigj ~]# rpm -qa|grep ntp
python-ntplib-0.3.2-1.el7.noarch
ntpdate-4.2.6p5-29.el7.centos.2.x86_64
ntp-4.2.6p5-29.el7.centos.2.x86_64
fontpackages-filesystem-1.44-8.el7.noarch
[root@shigj ~]# vim /etc/ntp.conf
注释一下内容
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
#新增如下配置文件
#授权这个网段上的所有机器都可以从这台机器上查询和同步时间
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
#时间服务器列表
server ntp1.aliyun.com
server ntp2.aliyun.com
server ntp3.aliyun.com
#当外部时间不可用时,使用本地时间
server 127.0.0.1
fudge 127.0.0.1 stratum 10
#允许上层时间服务器主动修改本机时间
restrict ntp1.aliyun.com nomodify notrap noquery
restrict ntp2.aliyun.com nomodify notrap noquery
restrict ntp3.aliyun.com nomodify notrap noquery
[root@shigj ~]# systemctl restart ntpd
[root@shigj ~]# systemctl restart ntpd
同样查询是否安装ntp、ntpdate如果没有直接安装
[root@shigj ~]# yum -y install ntp
修改配置文件/etc/ntp.conf
#注释一下内容
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
#新增以下内容
server 192.168.10.20
restrict 192.168.10.20 nomodify notrap noquery
#当外部时间不用时使用本地时间
server 127.0.0.1
fudge 127.0.0.1 stratum 10
保存后重启加入开机自启动
[root@shigj ~]# systemctl restart ntpd
[root@shigj ~]# systemctl restart ntpd
查看ntp服务器信息
[root@shigj ~]# ntpq -p
[root@shigj ~]# ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
192.168.10.20 203.107.6.88 3 u 4 64 1 0.576 5940618 0.000
localhost .INIT. 16 l - 64 0 0.000 0.000 0.000
客户端修改时间
[root@shigj ~]# date -s '2020-01-01 00:00:00'
2020年 01月 01日 星期三 00:00:18 CST
[root@shigj ~]# date
2020年 01月 01日 星期三 00:00:19 CST
[root@shigj ~]# date
2020年 01月 01日 星期三 00:00:20 CST
[root@shigj ~]# date
2020年 01月 01日 星期三 00:00:21 CST
[root@shigj ~]# systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since 四 2021-11-18 13:30:21 CST; 1 years 10 months left
Main PID: 702 (crond)
CGroup: /system.slice/crond.service
└─702 /usr/sbin/crond -n
11月 18 13:30:21 shigj systemd[1]: Started Command Scheduler.
11月 18 13:30:21 shigj crond[702]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 42% if used.)
11月 18 13:30:22 shigj crond[702]: (CRON) INFO (running with inotify support)
需要在crontab加入以下相关信息
[root@shigj ~]# crontab -l
* * * * * /usr/sbin/ntpdate -u 192.168.10.20 &> /dev/null
[root@shigj ~]# date
2021年 11月 18日 星期四 13:54:24 CST
如:mysql-8.0.24-linux-glibc2.12-x86_64.tar.gz
917MB
#!/bin/bash
#软件目录:/data/
#数据目录:/data/mysql/data
#setup-mysql8.0.24.sh
#
MYSQL_FILE='/data/'
MYSQL_HOME='/data/'
MYSQL_DATA='/data/mysql/data'
MYSQL_TAR='/data/mysql-8.0.24-linux-glibc2.12-x86_64.tar.gz'
MYSQL_UNZIP_FILE='/data/mysql-8.0.24-linux-glibc2.12-x86_64'
TIME=`date +%Y%m%d%H%M%S`
#安装环境准备
find / -name "mysql" -exec rm -rf {} \; >/dev/null 2>&1
id mysql
if [ "0" == "$?" ];then
echo "mysql用户存在,删除mysql用户和组"
pid=`pidof mysqld`
kill -9 $pid >/dev/null 2>&1
/usr/sbin/userdel -r mysql > /dev/null 2>&1
echo "1创建mysql用户和组" && sleep 2
/usr/sbin/groupadd mysql
/usr/sbin/useradd -s /sbin/nologin -g mysql mysql
else
echo "2创建mysql用户和组" && sleep 2
/usr/sbin/groupadd mysql
/usr/sbin/useradd -s /sbin/nologin -g mysql mysql
fi
#配置文件限制
cat >>/etc/security/limits.conf<* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF
echo "fs.file-max=65535" >> /etc/sysctl.conf
#安装程序
#安装前准备
echo "unzip starting......"
tar -zxf $MYSQL_TAR -C $MYSQL_HOME
#创建软链接
cd $MYSQL_HOME
ln -s $MYSQL_UNZIP_FILE mysql
#创建目录
echo "创建mysql相关文件目录" && sleep 2
mkdir -p $MYSQL_DATA
chown -R mysql:mysql $MYSQL_DATA
chmod -R 770 $MYSQL_DATA
#配置用户环境变量
echo "export PATH=/data/mysql/bin:$PATH" >> /etc/profile
source /etc/profile
#配置文件(先备份后创建)
if [ -s /etc/my.cnf ]; then
mv /etc/my.cnf /etc/my.cnf.$TIME.bak
fi
echo "#设置mysql客户端默认字符集
[client]
default-character-set=utf8
[mysql]
#设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录
basedir=/data/mysql
# 设置mysql数据库的数据的存放目录
datadir=/data/mysql/data
# 允许最大连接数
max_connections=1000
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
lower_case_table_names=1
max_allowed_packet=102400M
character-set-server=utf8
#绑定ipv4
bind-address=0.0.0.0
#设置缓冲池大小:
innodb_buffer_pool_size=1024M
#设置密码验证默认加密方式
default-authentication-plugin=mysql_native_password
#设置隔离级别
transaction-isolation=read-committed
#关闭主从关闭binlog
#log-bin=mysql-bin
#binlog_format=mixed
#innodb_sort_buffer_size = 67108864">/etc/my.cnf
echo "export PATH=$PATH:/usr/local/mysql/bin">>/etc/profile
#初始化数据库
echo "initializing......"
#mysqld --initialize --user=mysql
mysqld --initialize --console --user=mysql --lower_case_table_names=1
#yum remove mariadb -y && yum install -y -q libaio libaio-devel
#mysql服务设置,启动mysql
cd $MYSQL_HOME/mysql
#将启动脚本加入到系统服务,并设置为开机启动启动
cp -rf $MYSQL_HOME/mysql/support-files/mysql.server /etc/init.d/mysql.server
chkconfig --add mysql.server
chkconfig mysql.server on
chkconfig --list
echo "mysql starting......"
service mysql.server start
echo "安装完毕,密码在上面的输出中,请复制密码,然后修改密码
mysqladmin -uroot -p密码 password 新密码
进入到数据库修改远程连接
select host from user where user='root';
update user set host='%' where user='root'
create user oa;
#修改密码
ALTER USER oa@'%' IDENTIFIED WITH mysql_native_password BY 'oa123456';
grant all privileges on *.* to 'oa'@'%';
flush privileges;
"
登录数据库进行授权
mysql> GRANT REPLICATION SLAVE ON *.* TO 'root'@'%';
mysql> flush privileges;
修改配置文件/etc/my.cnf
#启用主从binlog
server_id = 26
log-bin=master-bin
log-slave-updates=true
#防止日志文件过大,导致磁盘空间不足
expire-logs-days=10
#必须有这句话
binlog_checksum=none
重启数据库
[root@shigj ~]# systemctl restart mysql
[root@shigj ~]# mysql -uroot -p
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000004 | 328 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
修改配置文件/etc/my.cnf
#启用主从binlog
server_id = 27
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
#防止日志文件过大,导致磁盘空间不足
expire-logs-days=10
#必须有这句话
binlog_checksum=none
重启数据库
[root@shigj ~]# mysql -uroot -p
mysql>CHANGE MASTER TO
MASTER_HOST='192.168.10.26',
MASTER_USER='root',
MASTER_PASSWORD='密码',
MASTER_LOG_FILE='master-bin.000004',
MASTER_LOG_POS=328,
MASTER_SSL=1;
mysql>start slave;
mysql>show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.26
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000004
Read_Master_Log_Pos: 328
Relay_Log_File: relay-log-bin.000011
Relay_Log_Pos: 493
Relay_Master_Log_File: master-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: 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: 328
Relay_Log_Space: 857
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
只要出现下面的2个内容均为Yes表示配置成功,如果任何一个出现no都无法成功进行数据同步
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
企业中的业务通常数据量都比较大,而单台数据库在数据存储、安全性和高并发方面都无法满足实际的需求,所以需要配置多台主从数据服务器,以实现主从复制,增加数据可靠性,读写分离,也减少数据库压力和存储引擎带来的表锁定和行锁定问题,本文目前仅仅只是介绍了主从复制功能的详细介绍,未涉及到读写分离、负载均衡、高可用的场景。