主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。
使用主从同步的好处:
- 通过增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整整个数据库的性能。
- 提高数据安全,因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据
- 在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能
主从同步机制
Mysql服务器之间的主从同步是基于二进制日志机制,主服务器使用二进制日志来记录数据库的变动情况,从服务器通过读取和执行该日志文件来保持和主服务器的数据一致。
在使用二进制日志时,主服务器的所有操作都会被记录下来,然后从服务器会接收到该日志的一个副本。从服务器可以指定执行该日志中的哪一类事件(譬如只插入数据或者只更新数据),默认会执行日志中的所有语句。
每一个从服务器会记录关于二进制日志的信息:文件名和已经处理过的语句,这样意味着不同的从服务器可以分别执行同一个二进制日志的不同部分,并且从服务器可以随时连接或者中断和服务器的连接。
主服务器和每一个从服务器都必须配置一个唯一的ID号(在my.cnf文件的[mysqld]模块下有一个server-id配置项),另外,每一个从服务器还需要通过CHANGE MASTER TO语句来配置它要连接的主服务器的ip地址,日志文件名称和该日志里面的位置(这些信息存储在主服务器的数据库里)
有很多种配置主从同步的方法,可以总结为如下的步骤:
- 在主服务器上,必须开启二进制日志机制和配置一个独立的ID
- 在每一个从服务器上,配置一个唯一的ID,创建一个用来专门复制主服务器数据的账号
- 在开始复制进程前,在主服务器上记录二进制文件的位置信息
- 如果在开始复制之前,数据库中已经有数据,就必须先创建一个数据快照(可以使用mysqldump导出数据库,或者直接复制数据文件)
- 配置从服务器要连接的主服务器的IP地址和登陆授权,二进制日志文件名和位置
操作:
#关闭防火墙
service iptables stop
root下
useradd mysql # 加用户 echo 'root123'|passwd --stdin mysql # 设置密码 tar -zxf mysql-5.6.34-linux-glibc2.5-x86_64.tar.gz -C /usr/local/ # 解压 mv mysql-5.6.34-linux-glibc2.5-x86_64 mysql # 重命名 cd /usr/local/mysql #mysql5.7没有data目录,手动创建 mkdir data chown -R mysql:mysql mysql/ # 赋予权限
# 切换用户 su - mysql cd /usr/local/mysql # 初始化 # mysql5.7和之前版本不同,很多资料上都是这个命令初始化:../scripts/mysql_install_db --user=mysql,而mysql5.7的mysql_install_db命令是在bin目录下 的并且建议 用 mysqld --initialize命令 bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data #在低于5.7版本可以用下面这个命令初始化 cd /usr/local/mysql/scripts/ ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
bash-4.1$ bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data 2020-09-24T17:18:06.303755Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000) 2020-09-24T17:18:06.303877Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000) 2020-09-24T17:18:06.304157Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2020-09-24T17:18:07.357897Z 0 [Warning] InnoDB: New log files created, LSN=45790 2020-09-24T17:18:07.649634Z 0 [Warning] InnoDB: Creating foreign key constraint system tables. 2020-09-24T17:18:07.798293Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: e9febf85-fe89-11ea-b247-000c2932f416. 2020-09-24T17:18:07.814479Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened. 2020-09-24T17:18:07.842511Z 1 [Note] A temporary password is generated for root@localhost: =;pWEA#kr1zi
注意最后一行,这也是和之有版本不同的地方,它给了root一个初始密码,后面要登录的时候要用到这个密码。
mysql5.7版本主从同步部署
切换用户到root
# 备份原来的my.cnf文件 mv my.cnf my.cnf.bak
cd /usr/local/mysql/support-files cp my-default.cnf /etc/my.cnf # 配置成服务 cp mysql.server /etc/init.d/mysql
# 配置环境变量 vi /etc/profile #添加以下两行 export MYSQL_HOME=/usr/local/mysql export PATH=$MYSQL_HOME/bin:$PATH # 环境变量立即生效 source /etc/profile
#配置mysql服务开机自动启动 chkconfig --add mysql chkconfig mysql on
启动mysql
service mysql start
#登录MySQL
mysql -uroot -p
> 输入初始化最后一行中的密码就可以登录
#登录后,第一次修改密码必须用alter语句
alter user 'root'@'localhost' identified by 'root123' PASSWORD EXPIRE NEVER account unlock;
#设置登录权限(使得root用户可以从任何机器上登录数据库)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root123' WITH GRANT OPTION;
#立即生效
flush privileges;
配置master my.cnf配置文件
vi /etc/my.cnf
[mysqld] #修改忽略大小写 lower_case_table_names=1 #[mysqld]下 #修改连接数 max_connections=1000 #[mysqld]下 server-id = 151 #唯一 log-bin = mysql-bin-1 basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/usr/local/mysql/data/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/usr/local/mysql/data/master.pid
配置slave my.cnf配置文件
[mysqld] #修改忽略大小写 lower_case_table_names=1 #[mysqld]下 #修改连接数 max_connections=1000 #[mysqld]下 server-id = 171 #唯一 log-bin = mysql-bin-2 log_slave_updates = 1 #将复制事件写进自己的二进制日志 read_only=1 #防止改变数据(除了特殊的线程) log_slave_updates=1 #log_slave_updates表示slave将复制事件写进自己的二进制日志 expire_logs_days=7 #二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。 basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/usr/local/mysql/data/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/var/log/mysqld.log #pid-file=/usr/local/mysql/data/mysqld.pid pid-file=/usr/local/mysql/data/slave.pid
#重启MySQL
service mysql restart
主192.168.174.3;从192.168.174.4
master
赋予slave链接主库的权限
mysql> grant replication slave, replication client on *.* to 'slave'@'192.168.174.4' identified by 'root123';
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin-1.000002 | 1353 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
slave
在从库配置master主库的IP,连接主库的用户密码,同步主库的master_log_file,master_log_pos
master_log_file='mysql-bin-1.000002',master_log_pos=1353;是在主 show master status;
change master to master_host='192.168.174.3',master_user='slave',master_password='root123',master_log_file='mysql-bin-1.000002',master_log_pos=1353;
#启动slave
start slave;
验证:
#在从库执行下面命令,这两项是yes说明主从配置完成
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> SHOW SLAVE STATUS\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.174.3 Master_User: slave Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin-1.000002 Read_Master_Log_Pos: 1353 Relay_Log_File: yaoyao-relay-bin.000002 Relay_Log_Pos: 322 Relay_Master_Log_File: mysql-bin-1.000002 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: 1353 Relay_Log_Space: 530 Until_Condition: None