来源:Onegoleya 简栈文化

  什么是mysql的主从复制?

  MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。

  Mysql复制原理

  原理:

  (1)Master服务器将数据的改变记录二进制Binlog日志,当Master上的数据发生改变时,则将其改变写入二进制日志中;

  (2)Slave服务器会在一定时间间隔内对Master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求Master二进制事件

  (3)同时主节点为每个I/O线程启动一个Dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

  Undo log与Redo log原理分析

  Undo log原理

  Undo log是把所有没有COMMIT的事务回滚到事务开始前的状态,系统崩溃时,可能有些事务还没有COMMIT,在系统恢复时,这些没有COMMIT的事务就需要借助Undo log来进行回滚。

  使用Undo log时要求:

  1、记录修改日志时(Redo log),(T,x,v)中v为x修改前的值,这样才能借助这条日志来回滚;

  2、事务提交后,必须在事务的所有修改(包括记录的修改日志)都持久化后才能写COMMIT T日志;这样才能保证,宕机恢复时,已经COMMIT的事务的所有修改都已经持久化,不需要回滚。

  使用Undo log时事务执行顺序

  1、记录START T

  2、记录需要修改的记录的旧值(要求持久化)

  3、根据事务的需要更新数据库(要求持久化)

  4、记录COMMIT T  

  使用Undo log进行宕机回滚

  1、扫描日志,找出所有已经START,还没有COMMIT的事务。

  2、针对所有未COMMIT的日志,根据Redo log来进行回滚。

  如果数据库访问很多,日志量也会很大,宕机恢复时,回滚的工作量也就很大,为了加快回滚,可以通过Checkpoint机制来加速回滚。

  从后往前,扫描Undo log

  1、如果先遇到checkpoint_start, 则将checkpoint_start之后的所有未提交的事务进行回滚;

  2、如果先遇到checkpoint_end, 则将前一个checkpoint_start之后所有未提交的事务进行回滚;(在checkpoint的过程中,可能有很多新的事务START或者COMMIT)。
使用Undo log,在写COMMIT日志时,要求Redo log以及事务的所有修改都必须已经持久化,这种做法通常很影响性能。

  与Undo log类似,在使用时对持久化以及事务操作顺序的要求都比较高,可以将两者结合起来使用,在恢复时,对于已经COMMIT的事务使用Redo log进行重做,对于没有COMMIT的事务,使用Undo log进行回滚。Redo/Undo log结合起来使用时,要求同时记录操作修改前和修改后的值,如(T,x,v,w),v为x修改前的值,w为x修改后的值,具体操作顺序为:

  1. 记录START T

  2. 记录修改日志(T,x,v,w)(要求持久化,其中v用于undo,w用于redo)

  3. 更新数据库

  4. 记录 COMMIT T

  实战操作

  上一篇已经对于Binlog设置做了一些初步的实践:http://www.cyblogs.com/mysql-binlogshe-zhi/,还是在本地利用Docker的方式启动了2个容器。

➜ ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
662e8531eb70 centos: "/bin/bash" hours ago Up hours 0.0.0.0:->/tcp docker-mysql-slave
c738746e9623 centos: "/bin/bash" hours ago Up hours 0.0.0.0:->/tcp docker-mysql-master

  一个是docker-mysql-master作为主节点,docker-mysql-slave作为从节点,最后实现一个主从同步的功能。

  Master节点

  设置slave_account账户

 [root@c738746e9623 bin]# ./mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is
Server version: 5.6.-log MySQL Community Server (GPL)
mysql> grant replication slave on *.* to 'slave_account'@'%' identified by '';
Query OK, rows affected (0.01 sec)
mysql> flush privileges;
Query OK, rows affected (0.01 sec)

  Master节点的my.cnf

[root@c738746e9623 bin]# cat /etc/my.cnf
[client]
default-character-set=utf8 [mysql]
default-character-set=utf8 [mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port =
socket = /tmp/mysql.sock server-id =
log-bin=mysql-bin binlog-ignore-db = mysql
binlog-ignore-db = information_schema sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

  查看master节点状态

 mysql> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin. | | | mysql,information_schema | |
+------------------+----------+--------------+--------------------------+-------------------+
row in set (0.00 sec)

  Slave节点

  Slave节点my.cnf

 [root@662e8531eb70 mysql]#cat /etc/my.cnf
[client]
default-character-set=utf8 [mysql]
default-character-set=utf8 [mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port =
socket = /tmp/mysql.sock server-id = sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

  配置与主节点同步的配置

mysql> change master to master_host='172.17.0.2',master_user='slave_account',master_password='',master_log_file='mysql-bin.000002',master_log_pos=;
Query OK, rows affected, warnings (0.06 sec)

  启动同步

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

  查看一个主从同步的状态

 mysql> show slave status\G;
*************************** . row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.17.0.2
Master_User: slave_account
Master_Port:
Connect_Retry:
Master_Log_File: mysql-bin.
Read_Master_Log_Pos:
Relay_Log_File: 662e8531eb70-relay-bin.
Relay_Log_Pos:
Relay_Master_Log_File: mysql-bin.
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:
Last_Error:
Skip_Counter:
Exec_Master_Log_Pos:
Relay_Log_Space:
Until_Condition: None
Until_Log_File:
Until_Log_Pos:
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master:
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno:
Last_IO_Error:
Last_SQL_Errno:
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id:
Master_UUID: 7323857e-254b-11ea-9b62-0242ac110002
Master_Info_File: /usr/local/mysql/data/master.info
SQL_Delay:
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count:
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position:
row in set (0.00 sec)

  Master节点写数据

mysql> CREATE TABLE `person_01` (
-> `id` int() DEFAULT NULL,
-> `first_name` varchar() DEFAULT NULL,
-> `age` int() DEFAULT NULL,
-> `gender` char() DEFAULT NULL
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8
-> ;
Query OK, rows affected (0.03 sec)
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| person |
| person_01 |
+----------------+
rows in set (0.01 sec) mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Bob', , 'M');
Query OK, row affected (0.01 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Jane', , 'F');
Query OK, row affected (0.01 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Jack', , 'M');
Query OK, row affected (0.00 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Bill', , 'M');
Query OK, row affected (0.00 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Nick', , 'M');
Query OK, row affected (0.00 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Kathy', , 'F');
Query OK, row affected (0.01 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Steve', , 'M');
Query OK, row affected (0.00 sec)
mysql> INSERT INTO test.person_01 (id, first_name, age, gender) VALUES (, 'Anne', , 'F');
Query OK, row affected (0.00 sec) mysql> select * from person_01;
+------+------------+------+--------+
| id | first_name | age | gender |
+------+------------+------+--------+
| | Bob | | M |
| | Jane | | F |
| | Jack | | M |
| | Bill | | M |
| | Nick | | M |
| | Kathy | | F |
| | Steve | | M |
| | Anne | | F |
+------+------------+------+--------+
rows in set (0.01 sec)
mysql> exit
Bye
[root@c738746e9623 bin]# 主节点

  Slave节点查数据

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| person_01 |
+----------------+
row in set (0.00 sec) mysql> select * from person_01;
+------+------------+------+--------+
| id | first_name | age | gender |
+------+------------+------+--------+
| | Bob | | M |
| | Jane | | F |
| | Jack | | M |
| | Bill | | M |
| | Nick | | M |
| | Kathy | | F |
| | Steve | | M |
| | Anne | | F |
+------+------------+------+--------+
rows in set (0.00 sec)
mysql> exit
Bye
[root@662e8531eb70 mysql]# 从节点

  这样子就做好了最简单的主从同步。主从同步只是最基础的高可用架构。

参考地址

https://blog.csdn.net/xuanxuan_good/article/details/54427154
https://zhuanlan.zhihu.com/p/96212530

MySQL主从同步-原理&实践篇的更多相关文章

  1. MySQL主从同步原理 部署【转】

    一.主从的作用:1.可以当做一种备份方式2.用来实现读写分离,缓解一个数据库的压力二.MySQL主从备份原理master 上提供binlog ,slave 通过 I/O线程从 master拿取 bin ...

  2. mysql 主从 同步原理及配置

    一.在mssql 里头实现同步镜像,只能主库用而镜像库不能同时用,而mysql 主从同步可以实现 数据库的读写分离,主库负责 update insert delete ,从库负责select 这样一来 ...

  3. mysql主从同步原理及错误解决

    mysql主从同步的原理: 1.在master上开启bin-log日志功能,记录更新.插入.删除的语句. 2.必须开启三个线程,主上开启io线程,从上开启io线程和sql线程. 3.从上io线程去连接 ...

  4. Mysql 主从同步原理简析

    在开始讲述原理的情况下,我们先来做个知识汇总,究竟什么是主从,为什么要搞主从,可以怎么实现主从,mysql主从同步的原理1.什么是主从其实主从这个概念非常简单主机就是我们平常主要用来读写的服务,我们称 ...

  5. 架构师必备:MySQL主从同步原理和应用

    日常工作中,MySQL数据库是必不可少的存储,其中读写分离基本是标配,而这背后需要MySQL开启主从同步,形成一主一从.或一主多从的架构,掌握主从同步的原理和知道如何实际应用,是一个架构师的必备技能. ...

  6. 高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏

    1. MySQL主从同步实现方式 MySQL主从同步是基于Bin Log实现的,而Bin Log记录的是原始SQL语句. Bin Log共有三种日志格式,可以binlog_format配置参数指定. ...

  7. MySQL主从同步原理

    mysql主从复制用途 实时灾备,用于故障切换 读写分离,提供查询服务 备份,避免影响业务 主从部署必要条件 主库开启binlo日志(设置log-bin参数) 主从server-id不同 从库可以连同 ...

  8. Mysql主从同步原理简介

    1.定义:当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库. 2.好处: 1)水平扩展数据库的负载能力. 2)容错,高可用.Failover(失败切换)/High Av ...

  9. mysql 主从同步原理

    Replication 线程 Mysql的 Replication 是一个异步的复制过程,从一个 Mysql instace(我们称之为 Master)复制到另一个 Mysql instance(我们 ...

随机推荐

  1. Idea 中 使用 devtools 热部署 spring-boot 应用 无需重新启动

    描述: 在我们使用spring-boot开发时,如果在开发者调试项目,边修改边调试运行,如果每次修改 java文件或者配置文件后都需要重新启动程序,如果程序启动比较慢的化,每次修改一点东西都要重新启动 ...

  2. java IO流 (七) 对象流的使用

    1.对象流: ObjectInputStream 和 ObjectOutputStream2.作用:ObjectOutputStream:内存中的对象--->存储中的文件.通过网络传输出去:序列 ...

  3. 机器学习实战基础(十五):sklearn中的数据预处理和特征工程(八)特征选择 之 Filter过滤法(二) 相关性过滤

    相关性过滤 方差挑选完毕之后,我们就要考虑下一个问题:相关性了. 我们希望选出与标签相关且有意义的特征,因为这样的特征能够为我们提供大量信息.如果特征与标签无关,那只会白白浪费我们的计算内存,可能还会 ...

  4. 机器学习实战基础(九):sklearn中的数据预处理和特征工程(二) 数据预处理 Preprocessing & Impute 之 数据无量纲化

    1 数据无量纲化 在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求,这种需求统称为将数据“无量纲化”.譬如梯度和矩阵为核心的算法中,譬如逻辑回 ...

  5. 爬虫07 /scrapy图片爬取、中间件、selenium在scrapy中的应用、CrawlSpider、分布式、增量式

    爬虫07 /scrapy图片爬取.中间件.selenium在scrapy中的应用.CrawlSpider.分布式.增量式 目录 爬虫07 /scrapy图片爬取.中间件.selenium在scrapy ...

  6. Django框架04 /模板相关、别名/反向解析/路由分发

    Django框架04 /模板相关.别名/反向解析/路由分发 目录 Django框架04 /模板相关.别名/反向解析/路由分发 1. 语法 2. 变量/万能的点 3 . 过滤器 4. 标签Tags 5. ...

  7. 原来不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞!

    GitHub 15.8k Star 的Java工程师成神之路,不来了解一下吗! GitHub 15.8k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 15.8k Star ...

  8. (5)webpack中url-loader的使用

    为什么要使用url-loader 在前面已经介绍了css文件可以使用第三方loader去加载. 在一个项目中,也不仅仅只有html,js和css文件,还有图片文件,字体文件等等.当我们给一个css样式 ...

  9. 用前端姿势玩docker【一】Docker通俗理解常用功能汇总与操作埋坑

    前言 首先一句话表达个人对docker的理解:与传统虚拟技术基于硬件及物理资源的虚拟化相比,Docker更加轻量化,docker为基于操作系统或内核级别的虚拟化,并且提供了从各种机制与操作以满足从开发 ...

  10. python 复制以及更改列表操作

    题目:设置一个老用户列表和一个新用户列表,检查老用户列表中是否与新注册的用户名字有重复(不区分大小写),老用户列表不能被破坏 usernames = ['admin','Tom','john','ja ...