转: https://www.cnblogs.com/xing-29391/p/12880095.html
https://my.oschina.net/warm6Y/blog/3003452

一.mysql主从同步原理

  1. Slave上面的IO线程连接上Master,并请求从指定Binary log文件的指定位置(或者从最开始的日志)之后的日志内容;
  2. Master接收到来自Slave的IO线程的请求后,通过负责复制的IO线程根据请求信息读取指定日志指定位置之后的日志信息,返回给Slave端的IO线程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息在Master端Binary log文件的名称以及在Binary log中的位置;
  3. Slave的IO线程收到信息后,将接收到的日志内容依次写入到Slave端的RelayLog文件(mysql-relay-lin.xxxxx)的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”
  4. Slave的SQL线程检测到Relay Log中新增加了内容后,会马上解析该Log文件中的内容成为在Master端真实执行时候的那些可执行的查询或操作语句,并在自身执行那些查询或操作语句,这样,实际上就是在master端和Slave端执行了同样的查询或操作语句,所以两端的数据是完全一样的。

binlog输出线程。每当有从库连接到主库的时候,主库都会创建一个线程然后发送binlog内容到从库。
对于每一个即将发送给从库的sql事件,binlog输出线程会将其锁住。一旦该事件被线程读取完之后,该锁会被释放,即使在该事件完全发送到从库的时候,该锁也会被释放。
在从库里,当复制开始的时候,从库就会创建两个线程进行处理:
从库I/O线程。当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。
从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件。
从库的SQL线程。从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行。
可以知道,对于每一个主从复制的连接,都有三个线程。拥有多个从库的主库为每一个连接到主库的从库创建一个binlog输出线程,每一个从库都有它自己的I/O线程和SQL线程。
从库通过创建两个独立的线程,使得在进行复制时,从库的读和写进行了分离。因此,即使负责执行的线程运行较慢,负责读取更新语句的线程并不会因此变得缓慢。比如说,如果从库有一段时间没运行了,当它在此启动的时候,尽管它的SQL线程执行比较慢,它的I/O线程可以快速地从主库里读取所有的binlog内容。这样一来,即使从库在SQL线程执行完所有读取到的语句前停止运行了,I/O线程也至少完全读取了所有的内容,并将其安全地备份在从库本地的relay log,随时准备在从库下一次启动的时候执行语句

二.mysql8.0.13主从配置

环境介绍及说明
1、主库所在的操作系统:windows 10 (64位);
主库目录:C:\mysql-8.0.13\master\3307
主库的版本:mysql-8.0.13-winx64.zip;
主库的ip地址:127.0.0.1;
主库的端口:3307;
2、从库所在的操作系统:windows10 (64位);
从库目录:C:\mysql-8.0.13\slave\3308
从库的版本:mysql-8.0.13-winx64.zip;
从库的ip地址:127.0.0.1;
从库的端口:3308;
注:主库和从库版本可以一致也可以不一致,需要说明一点,如果两者版本不一致,一般主库的版本需要比从库的版本低,这样就可以避免由于版本问题,有些sql不能执行的问题。
数据库配置及注册服务
1、主库(master)的配置(因为在虚拟机上,C盘为例)

  • 将下载的数据库解压到:C:\mysql-8.0.13\master\3307;
  • 在3307目录下建立my.ini;配置内容如下:

[mysqld] #主库配置 server-id=1 #开启二进制日志 log_bin=master-bin log_bin-index=master-bin.index # 设置3307端口 port=3307 # 设置mysql的安装目录 basedir=C:/mysql-8.0.13/master/3307 # 设置mysql数据库的数据的存放目 datadir=C:/mysql-8.0.13/master/3307/data # 允许最大连接数 max_connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3307 default-character-set=utf8

  • 管理员身份(必须,必须,必须)运行cmd,并cd到C:\mysql-8.0.13\master\3307\bin下,输入命令:

mysqld —initialize —user=mysql —console(bin目录下生成data文件,系统默认创建数据库,此时还会生成一个临时的密码!找不到密码点击这里

  • 注册服务,输入命令:

mysqld —install mysql-master —defaults-file=”C:\mysql-8.0.13\master\3307\my.ini”

  • 启动MySQL服务,输入命令:(默认是启动的,可以先登陆数据库,如果服务没有启动,再执行此命令)

net start mysql-master

  • 登陆mysql,输入命令:

mysql -u root -P3307 -p

  • 修改密码,输入命令:

ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘新密码’;

  • 退出mysql,输入命令:

    exit;
    重新登陆OK。恭喜,主库完成!!!
    2、从库(slave)的配置(因为在虚拟机上,C盘为例)

  • 将下载的数据库解压到:C:\mysql-8.0.13\slave\3308;

  • 在3308目录下建立my.ini;配置内容如下:

    [mysqld] #从库配置 server_id=2 relay-log-index=slave-relay-bin.index relay-log=slave-relay-bin # 设置3308端口 port=3308 # 设置mysql的安装目录 basedir=C:/mysql-8.0.13/slave/3308 # 设置mysql数据库的数据的存放目录 datadir=C:/mysql-8.0.13/slave/3308/data # 允许最大连接数 max_connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3308 default-character-set=utf8

  • 管理员身份(必须,必须,必须)运行cmd,并cd到C:\mysql-8.0.13\slave\3308\bin下,输入命令:

mysqld —initialize —user=mysql —console

  • 注册服务,输入命令:

mysqld —install mysql-slave3308 —defaults-file=”C:\mysql-8.0.13\slave\3308\my.ini”

  • 启动MySQL服务,输入命令:(默认是启动的,可以先登陆数据库,如果服务没有启动,再执行此命令)

net start mysql-slave3308

  • 登陆mysql,输入命令:

mysql -u root -P3308 -p

  • 修改密码,输入命令:

ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘新密码’;

  • 退出mysql,输入命令:

    exit;
    重新登陆OK。恭喜,从库完成!!!
    3、主库(master)关联从库(slave)配置

  • 登陆master主库,创建一个用于让从数据库连接的用户,输入命令(自定义用户warm,密码为warm123456)

CREATE USER ‘warm’@’%’ IDENTIFIED WITH mysql_native_password BY ‘warm123456’;

  • 给用户授权,输入命令

GRANT REPLICATION SLAVE ON . TO ‘warm’@’%’;

  • 刷新权限,输入命令

flush privileges;

  • 查看master的状态,输入命令

    show master status;
    mysql主从配置 - 图1

  • 登陆slave从库,在slave从库节点上设置master主库主节点参数,输入命令

CHANGE MASTER TO
MASTERHOST=’172.0.0.1’, MASTER_PORT=3307,
MASTER_USER=’warm’,
MASTER_PASSWORD=’warm123456’,
MASTER_LOG_FILE=’binlog.000012’,
MASTER_LOG_POS=631746;
注意,
MASTER_LOG_FILE和master状态里的File保持一致,MASTER_LOG_POS和master状态里的Positon_保持一致

  • 开启主从同步,输入命令

start slave;

  • 查看主从同步状态,输入命令

show slave status\G;
mysql主从配置 - 图2
Slave_IO_Running和Slave_SQL_Running的状态都为YES才表示同步成功!!!!
若有错误,可在下方查看报错信息
mysql主从配置 - 图3
根据错误信息,自行百度!
自行创建库与表进行验证即可。
备注:注意不要往从库中写数据,如果从库写入数据,master_log_pos是不会变化的,主库的信息没有发生变化,当主库又变化和从库一样的操作时就有可能会产生冲突,因此,只能在主库中写数据,从库只能读数据,当然主库也可以读数据。
在从库中建立只读用户,避免往从库中写数据。

//遇到的问题================================

1.提示:server_id重复
解决办法: show variables like ‘server_id’;
set global server_id=2;
2.常用命令
start slave;
show slave status\G;
stop slave
flush privileges;

  1. 登陆master主库,创建一个用于让从数据库连接的用户,输入命令(自定义用户warm,密码为warm123456)<br /> CREATE USER 'slaveuser'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

给用户授权,输入命令
GRANT REPLICATION SLAVE ON . TO ‘slaveuser’@’%’;

3.提示: Last_IO_Error: Master command COM_REGISTER_SLAVE failed: Access denied for user ‘slaveuser’@’%’ (using password: YES) (Errno: 1045)
解决办法:没有权限 GRANT REPLICATION SLAVE ON . TO ‘slaveuser’@’%’
4.如果2次执行change master ,提示Mysql主从复制slave启动报Slave failed to initialize relay log info structure from the repository,
解决:https://blog.csdn.net/q283614346/article/details/101945018 用到了重置slave :reset slave;
5.问题:you need (at least one of) the SYSTEM_USER privilege(s) for this operation
解决办法:grant system_user on . to ‘root’;