MYSQL mysqldump备份实验

0. meta data lock实现(mysql 5.5后引入的)

http://blog.leokim.cn/2017/05/25/mysql-metadata-lockmdl/

1.分析muysqldump流程

2. 利用mysqldump做备份建一个从库(online不停业务)
3. 理解binary log在备份中的作用
4. 利用全备+binary log恢复到某个时间点
==========
5. 利用innobackupex 做备份及恢复 3307, 3306
6. 利用innobackupext做增备及恢复 3307, 3306
7. 利用innobackupex加binary log恢复到某个时间点

8. 表空间传输5.6, 5.5

扩展知识:

9. 关于mysql 5.5以下mysqlbinlog(第三方版本)的闪回
10. mysql binary logs格式浅析

DDL没办法在事务里保护

blob.png

/usr/local/mysql/bin/mysqldump -S /tmp/mysql_3306.sock –master-data=2 –single-transaction leokim >leokim_1_full.sql

GTID下可以不要"–master-data=2"这个参数

more leokim_1_full.sql

blob.png

blob.png

 人生就这么悲剧了,数据没了,这个时候就需要恢复

需要注意在dump的时候如果是gtid会有一个SET @@GLOBAL.GTID.PURGED 会直接报错

blob.png

mysql -S /tmp/mysql_3306.sock leo_bak<leokim_1_full.sql

 

blob.png

利用全备恢复 但是少了我们全备后添加的memcache

blob.png

在全备文件里找到master_log_pos = 858

所以我们在binlog里找到858这个位置 恢复从这个位置开始 到truncate之间的数据就可以了

blob.png

blob.png

mysqlbinlog -v --base64-output=decode-rows --start-position=858 --stop-position=1149  mybinlog.000001 > 1_bak.sql
use leokim
rename table leo to leo_bak;
rename table leo_bak.leo to leo;
select * from leo;

blob.png

mysqlbinlog --start-position=858 --stop-position=1062  mybinlog.000001 | mysql -S /tmp/mysql_3306.sock

现在看mongodb就恢复出来了

blob.png

如果开启了gtid 要reset master之后再做才行,gtid会认为自己已经做过了就不会恢复

所以恢复要找个别的地方恢复 然后再恢复到主库上 不能在主库上reset master

在测试库里回复完了单独做一次mysqldump 然后到出来放到生产库里恢复

gtid开启的话 要加上-f强制执行

或者加上–set -gtid-purged=OFF

有GTID的环境里做恢复特别要小心

binlog恢复一定要按顺序恢复不能跳着恢复

 

 

SQL四种语言:DDL,DML,DCL,TCL

1.DDL(Data Definition Language)数据库定义语言statements are used to define the database structure or schema.

DDL是SQL语言的四大功能之一。
用于定义数据库的三级结构,包括外模式、概念模式、内模式及其相互之间的映像,定义数据的完整性、安全控制等约束
DDL不需要commit.
CREATE
ALTER
DROP
TRUNCATE
COMMENT
RENAME

2.DML(Data Manipulation Language)数据操纵语言statements are used for managing data within schema objects.

由DBMS提供,用于让用户或程序员使用,实现对数据库中数据的操作。
DML分成交互型DML和嵌入型DML两类。
依据语言的级别,DML又可分成过程性DML和非过程性DML两种。
需要commit.
SELECT
INSERT
UPDATE
DELETE
MERGE
CALL
EXPLAIN PLAN
LOCK TABLE

3.DCL(Data Control Language)数据库控制语言  授权,角色控制等
GRANT 授权
REVOKE 取消授权

4.TCL(Transaction Control Language)事务控制语言
SAVEPOINT 设置保存点
ROLLBACK  回滚
SET TRANSACTION

SQL主要分成四部分:
(1)数据定义。(SQL DDL)用于定义SQL模式、基本表、视图和索引的创建和撤消操作。
(2)数据操纵。(SQL DML)数据操纵分成数据查询和数据更新两类。数据更新又分成插入、删除、和修改三种操作。
(3)数据控制。包括对基本表和视图的授权,完整性规则的描述,事务控制等内容。
(4)嵌入式SQL的使用规定。涉及到SQL语句嵌入在宿主语言程序中使用的规则。

MYSQL 备份

blob.png

blob.png

blob.png

blob.png

blob.png

·  不完全备份(上面少写了)

冷备:把机器关掉 copy数据库文件

热备(hot backup):在数据是运行中,进行的备份

增倍:在上一次备份的基础上做一个增加的备份,今天相对于昨天的变更备份

不完全备份:只备份一张表两张表

blob.png

ntsqldump单进程不太完美

mydumper多进程 sql层备份

xtrabackup基本上大家都在用

在有slave的情景下为什么还要有备份?

人为误操作 在主库上truncate table 从库上也会执行truncate table

mysql 5.6引入delay replication

可以指定从库和主库延迟多长时间 比如说一小时 一小时内主库上有误操作可以不同步到从库上

sql_thread 执行同步 不应用就行了

blob.png

只备份一个表的话只有select权限就可以 如果要一致性就要有lock tables权限

涉及到存储过程和视图就要把show view 和 trigger权限都给上 要不然会报错权限不足

blob.png

造成问题:

  1. 热数据冲掉

  2. 冷数据加载 备份时间长

blob.png

–trigger=false(2个减号)

-t –no-create-info(Don't write table createion info. 不要创建schema) 

-d  不要数据只要表结构

-R存储过程

-n 不要创建库

-E  event 

-f 重置备份

建议每个分开备份 

特别对于数据文件单独放

如果数据库不超过100G 并且内存又很大 可以使用

如果已经100G 内存只有16G 就不要考虑使用mysqldump了

考虑的场景是内存和数据差不多的场景采取用 如果超过3倍以上就不要考虑了 

因为用起来太慢了

blob.png

会有一个问题 如果这个表没有id字段会报错

所以加上where条件的话 要明确这个条件和表是有内容的

mysqldump -t –where="id<10" db1 tb1

这样可以简单的从一个表里拿到一部分去做测试方便拿到子集

DDL不受事务管理 保护不了一致性

一致性快照:拿到一个数据在某一时间一致性的数据 t1时间的备份拿到t1时间的镜像

–set-gtid-purged 会带着gtid的值 表明多少gtid之前的不要了 这样一个标识

默认dump出来的代码:insert into tb1 values(),();

-c参数之后变成:insert into tb1(c1,c2,c3) values(c1,c2,c3);

会变成一个完整的格式,支持对原来表结构进行修改

-h:host

-u :用户

-P:端口号

-p:密码

blob.png

blob.png

不同版本的mysqldump变化很频繁

–replace -> replace into

blob.png

后面再演示

利用mysqldump备份有什么问题?

要注意:

1. 数据的内存的比例

2.mysqldump备份很慢,热数据冲掉冷数据加载时间过程备份时间过长

3.建议只备份数据量小的

4.Innodb表 –single-transanction可以不锁表

5.mysqldump还是单进程的(mydumper多线程并行sql层备份  https://launchpad.net/mydumper)

blob.png

还是基于sql层的备份

blob.png

blob.png

blob.png

mysql本身官方的东西太弱了

很多优秀的东西都是开源的

工具:percona-tools

备份:xtrabackup

监控:zabbix


blob.png

Xtrabackup 是类似于官方的企业备份工具 完全开源

Hot Onloine backup tool for MYSQL

图里的Memory是Innodb Buffer Pool

数据更新时 

1.把数据文件拉到内存更新 

2.把日志写到redo log

3.更新完了再把数据回写到data file里

在一个完整的事务环境保护下作了redo undo相应措施

redo 是为防止在update更新时没有完全提交 崩掉了 可以通过redo 来恢复到数据文件里

image.png

这个16K 是代表page size 可以自己定义

从data file里拿到内存的是page size的大小 这个就是操作最小单位
比如说以下示例:

    select * from user where user_id=100;

    除了会把user_id=100的page全读取到buffer pool里

    还会预读后面的内容 每次取满page size大小

    最小单位基于page size 5.6可以调整

    这个时候就体现出key value缓存的好处

    key value缓存就是一条记录缓存不是基于page的缓存

    没有预读直接获取准确值

    innodb_buffer_pool_size 是基于page的缓存

    每次操作读回来的大小是page size效率上会比key value缓存慢

blob.png

innodb crash recovery

如果更新中挂掉了 可以通过redo log恢复

100G 库 5.5引入innodb fast crash recovery 2,3分钟恢复

5.1之前要很久(1个多小时) 可以在errorlog里可以看到进度

blob.png

在内存里备份的时候先形成xtrabackup log

把数据库的任何变成以redo log的形式写入到xtrabackup log文件里

在这里面把数据文件全部copy走

任何变更都在这个文件里有了

相当于在内存挂掉之后用redo log恢复一下做一次crash recovery恢复

很快把数据文件恢复出来

Xtrabackup其实就时利用innodb的crash recovery原理

blob.png

blob.png

数据恢复是经过内存在内存里合并写入到数据文件里

对一个业务很繁忙的系统备份出来xtrabackup log很大 不要再高峰时间备份

fast recovery 的逻辑

  1. 依赖于redo log(redolog会记录哪个page变更,之后能得到一个page no)

  2. 拿到page no把数据(原始页)从备份的数据里读到内存里

  3. 拿到内存之后修改合并

  4. 持久化到数据文件

blob.png

blob.png

XtraBackup 2.4.1 GA版本发布,终于支持了MySQL 5.7的物理备份

tokudb不支持 可能会按非事务引擎来备份


blob.png

innodb/xtradb可以hot backup

myisam非事务引擎都是要加锁的

blob.png

innobackupex 是调用xtrabackup

中间2个会影响效率不建议使用

xtrabackup不会copy *.frm (表结构文件)

blob.png

ibdata里有什么数据?

1、system tablespace(系统表空间)
ibdata files包含:(共享表空间文件)
(1)、internal data dictionary:数据字典
(2)、insert buffer:插入buffer
(3)、rollback segments:回滚表空间
(3)、undo pages:回滚页
(4)、Double write buffer:写入缓冲区

(5)、undo tablespace 

参照叶的课程

mysql 5.6 引入了一个特性: undo tablespace可以独立配置

blob.png

  1. 先形成xtabackup log文件记录内存里的变更

  2. copy innodb数据文件 .ibd , ibdata1

  3. 设置读锁为了一致性

  4. copy表空间,表结构等文件

  5. 拿到binlog位置

  6. 释放锁

  7. 停掉copy 结束

全事务引擎的–no-lock

blob.png

在做这个的时候是调用xtrabackup来copy的

blob.png

/etc/my.cnf /etc/mysql/my.cnf

/usr/local/mysql/etc/my.cnf

如果不是标准安装需要制定配置文件

指定备份目录

innobackupex –defaults-file=/path/my.cnf /backup/to/path/

依赖变量:

datadir 

socket

如果当前用户连不到mysql里需要提供用户密码

–user=

–password=

–host=

–port=

–apply-log

备份完之后会形成backup-my.cnf

blob.png

数据库刚开始备份时形成xtrabackup_info

xrtabackup_binlog_info: 获得binlog位置show master status的输出

–apply-log之后会形成

xtabackup_slave_info

xtrabackup_binlog_post_innodb

一般情况下xrtabackup_binlog_info应该和xtrabackup_binlog_post_innodb 是相等的

如果不相等以xtrabackup_binlog_post_innodb 为准

xtrabackup_logfile是最早形成的

backup-my.cny有数据库的redu log大小定义

blob.png
    blob.png

blob.png

这里没有gtid比较不爽 不知道现在有没有(https://sanwen8.cn/p/22b9Mii.html)

blob.png

这是测试环境里没有写入 to_lsn和last_lsn是一样的

如果在live里写入会很多 to_lsn和last_lsn会差很大

lsn是log sql no在系统show  engine innodb status\G里面输出

blob.png

其实就是字节大小

blob.png

blob.png

ibdata1:100M:autoextend

被同事改成了1G 

已经完成初始化后,再改,然后重启能不能启动?为什么?

实际的datafile 大于1G可以起来小于1G起不来

ibdata1:10M:autoextend

改小可以起来

因为:定义的值要<=实际的文件 关键在autoextend 只要比定义值小就起不来 大就没问题

innodb_log_file_in_group :log个数

innodb_log_file_size :log大小

这2个参数关系到重新做apply log(好像是这个听的不是太清楚)的时候需要把这2个初始化出来

blob.png

innodb_log_file_size

5.5要重新导入导出重建数据库

5.6可以修改重启就可以了

untitled.bmp

blob.png

指定上一次备份的文件在哪

blob.png

拿到之后主要是找xtabackup_info 找上一次备份的last_lsn找到后把大于这个lsn的data page全部copy一遍,copy到下图位置

blob.png

得到lsn后也可以有偷懒的做法 在做增量备份之前可以指定last_lsn在哪,在这个地方直接指定一个lsn就可一直接备份增量也不用指定上个备份目录在哪,这个做法就是大于这个lsn的page全把他copy一份

这样就是简单的做了一个增量

blob.png

blob.png

恢复:

full_1

incr_1

incr_2

如果incr_1 增量坏了

那就悲剧了

blob.png

data-page, index-page

更紧凑备份:只要data-page不要index-page

恢复的时候要重建index-page

blob.png

innodb_file_per_table:独立表空间

blob.png

include-tables-file=/path/tblist.txt //指定备份哪些表

–database //指定备份哪个库

blob.png

恢复的时候要多一个-export,会多一个tb.exp

紧凑备份

好处是减少备份集,备份小一点

blob.png

紧凑备份恢复的时候要索引重建

blob.png

恢复的时间会比平常时间多好几倍时间 因为索引要重建

========================================================

blob.png

blob.png

export之后除了之前的tb_a.frm, tb_ibd

会生成一个tb_a.cfg

然后把这个文件scp到远程空间上 或者scp到需要导入的那台机器上

导入的机器上需要创建一个同样的表结构

需要把当前表空间干掉blob.png

干掉之后如果没有表空间导进来的话就完蛋了

tb_a.ibd 表空间删掉了

把表空间import进来: alter table tb_a  import tablespace;

这个特性是MySQL 5.6引入的

blob.png

blob.png

基本每天一个全被+每天备份相应的binlog

比如:

早上4点做全备

4点前的binlog也要copy一下

通过天全备+今天的binlog 备份

可以还原到昨天的备份到今天任何一个时间点的备份

还原到今天某个时间点需要什么东西呢?

昨天凌晨4点的全量到今天凌晨4点的全量是什么呢? 是今天今天4点的binlog

重要的放到HDFS上

blob.png

MYSQL SQL编程

blob.png

mysql属于有这些功能但不是强项和分区一样不是特别推荐用

dba不是来写存储过程的 dba主要是是保证性能高可用

更高层面是架构

blob.png

存储过程:一组sql语句在客户端存储待client调用

把这些全封装在数据库里增加了数据库的开销

也可以对一组业务逻辑进行封装

游戏 通过更新存储过程 积分加倍或者不加倍

类型:

1.定义一组sql语句返还结果

2.UDF用户自定义函数 user defined function 函数返回一些标量(不能修改的值)

blob.png

mysql一个sql只能使用一个cpu

sql有没有编译缓存计划? 没有

一组sql在mysql server端运行只在一个核上运行同时没有编译缓存计划那么节省的是什么??

节省是client端向server端传输的网络io 但这个io通常不是我们的瓶颈

唯一我觉得的优点是可以把业务逻辑封装到数据库上

在数据库上通过sql达到业务逻辑的变更

感觉灵活一些

所以建议不要用存储过程 cpu会跑到很高

数据库删除也会删除相应存储过程

blob.png

存储过程是在表里寸的 而且这个表是mysaim的 很操蛋

mysql调存储过程满慢因为缓存不住 其实缓存住 直接在内存拿就好了 这是设计缺陷 后期版本可能会改善 5.7可能会有大的改善

blob.png

delimiter下面定义一个batch sql

create procedure 存储过程名字 括号里可存参数

调用后返回相应3个结果

blob.png

区别是存储函数有一个return 要把结果return回来

blob.png

declare申明的变量是存储过程中的local变量 只在存储过程中有(in可有可无)

declare上面少了个begin

blob.png

使用session变量容易造成结果是乱的慎用出结果特别难查

历史遗留产物

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

调试过程中可以这样看看是哪一步出错了

blob.png blob.png

blob.png

declare “关键词”cursor for "SQL语句"

重点

blob.png

5.6 一个触发器的名字指定定义一个触发器 

5.7这点做了改善 一个触发器可以定义多个

blob.png

高并发环境不允许使用触发器

核心业务里面禁掉不允许

高写入的情况下很耗资源毕竟是多了一些多的操作

blob.png

我们现在考虑都是支持事物的表 

blob.png

blob.png

blob.png

blob.png

级联外键所导致的更改

从库上触发器有可能不起作用

event再从库上也会被disable掉

blob.png

5.1以后才在mysql 引入

应用过程中各种操蛋

打开之后可以通过show processlist;看到多了一个进程

再高可用里切来切去容易造成event丢失

尽可能不用 用定时任务来取代

blob.png

坑:主从库切换之后 从库上的event是不会运行的

提升为主库也不会运行

需要把slave side去掉 然后out 一下inable

blob.png

blob.png

blob.png

MySQL分区

blob.png

SQL优化的核心:

减少I/0

把随机IO转成顺序IO

分区唯一的场景:用来记日志

blob.png

mysql hash分区 要求分区表达式必须是整数

range, list, hash

blob.png

show variables like "%partition%";

mysql 5.1 开始支持分区

blob.png

SELECT * FROM `PLUGINS` WHERE PLUGIN_NAME LIKE '%partition%'\G

mysql的分区比oracle差距很大 很弱

好处是从官方手册里直接翻译过来的,老师说不要用分区哈哈哈哈

特别不重要的地方才用分区,比如说日志

blob.png

delete from tb where add_date<'';

数据量太大删除不掉

用分区drop很方便

alter table tb drop partition p1;

blob.png

5.6种可以自动判断不用显示声明

innodb必须有主键

主键又必须在你的分区表达式里

blob.png

blob.png

range(year(add_datetime))

range columns(date(add_datetime))

partition p0 values less than ('2017-01-01'),

blob.png

blob.png

blob.png

list就是一个集合(有限的集合)

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

子分区名字不能重复

blob.png

blob.png

blob.png

blob.png

blob.png

group_concat长度有限制 可以修改

show global variables like "%group%";

blob.png

入果只命中一个效率最高

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png 

blob.png

blob.png

blob.png

blob.png

blob.png

mysql partition没有全局索引,所以索引都在自己的ipdate里放

一个分区一个索引没有完整性

blob.png

blob.png

mysql分区没有全局索引

分区能不能达到行级锁呢?

如果要有行级锁需要针对主键或者针对唯一索引

那么这个主键或者唯一索引就有一个条件必须在分区表达式里面

range 必须by primary key 或者 unique key

如果条件能去where的主键或者unique key那么能做行级锁

如果不能基本上是去锁到一个很大的区间

分区表包括mysql的表在select期间是不能去修改表的结构的

在执行代码的过程中是锁定的

锁定表的结构

这个是由存储引擎来处理不允许更改表结构

因为这个锁是存储引擎自己来处理的 所以每个存储引擎处理的方式也不同

myisam就是全局的锁等待

innodb通过不断重试去拿锁

每个分区都是一个存储引擎的实例 他们都有自己的ibdata

blob.png

其实对锁的粒度还是挺粗的 动不动就是一个range 锁

blob.png

不能对临时表进行分区 上面ppt日志写错了

blob.png

大部分都是时间函数,Mysql就是提倡对时间类的数据进行分期的

可用,但不可以委以重任

blob.png

不要再更改sql model

MYSQL基于复制业界的一些新技术

blob.png

blob.png

blob.png

master挂了

现在要提升slave为master 要做一些同步对比

以下要熟记,是最基础的

第一: 要确认自已是同步完成的 

master_log_file == relay_master_log_file 和read_master_log_pos =exec_master_log_pos

第二: 要确认slave1和slave2是相等的

slave1.master_log_file == slave2.master_log_file || slave1.master_log_pos == slave2.master_log_pos

第三: 让slave2 change 到slave1上

slave1(在即将成为master的slave上): 上执行一个show master status;

如果是GTID的直接change过去就OK了

show processlist查看master上的slave(和此文无关)

slave2: 执行一下show slave status;

slave2 : stop slave; change master ; start slave; show slave status;

reset slave; 清掉本地的relay log , 把同步调整到起始位置

blob.png

字典表

比如说 地理信息

blob.png

blob.png

多机房同步

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

选择proxy:

这个proxy有没有维护了,自已能不能维护

MYSQL复制管理技巧

blob.png

如果主库挂掉了

A->B A->C

A挂了只有BC了

要检查B/C是否同步完成并且检查谁更靠前

比较是否同步完成

这个时候的状态是io_thread:NO

if(master_log_file == reley_mast_log_file) and (read_master_log_post == exec_master_log_pos)

只有当这2个条件成立 我们才认为是同步完成的

b.Master_Log_File , c.Master_Log_File比较谁更大 就是同步的更完全

如果Master_Log_File都一样,那么比较 Exec_Master_Log_Pos

GTID会自动补上来 上面是传统模式

主从数据一致性怎么去校验(怎么确认主从是同步的?)

运行一段时间之后有一些不规范的操作搞成同步不一致问题

大的库分段检测 分析数据变换情况

pt-table-checksum

利用语句级复制,在主从库上对表分段进行校验,如果值不一样,说明就不同步了

pt-table-sync

利用语句复制,所有的修复都是在主库上完成的

https://www.percona.com/   Percona toolkit 

blob.png

下载最新版本

blob.png

用yum安装 方便管理 把yum源弄进来

pt 大多是基于perl编写的

有部分的shell

同一组内的数据必须同一个端口

每组的端口号是全局唯一的

总结:

row 格式的binlog复制,有些情况下会比statement的快

原因是:sql_thread应用日志时,在有主建的情况,会利用主键更新数据

reset master 清掉Executed_Gtid_Set

gtid_purged 配置在slave上

slave只会读取gtid_purged这个GUID之后的数据之前的就不要了

MYSQL同步中参数

MySQL 5.6.22的参数,总共432个

change maseter to 

show global variables;

以下所有参数都是mysqld里的

复制中的一些重点参数(最基础的)

log-bin(binlog路径)
server-id
(服务标识)
log-bin-index
binlog_format(binlog格式)
binlog_cache_size
max_binlog_size
sync_binlog
expire_logs_days
log_bin_trust_function_creators

server-uuid  以后有可能代替server-id(标识)

gtid从库没有配置service id也是也是可以的 但是主库一定要配置

Master的参数:

============================================

server-id
  唯一区别ID,同一个集群内不可重复
  可动态修改

binlog_format
  binlog日志格式:statement、row、mixed三种
  可动态修改 建议修改session的不修改全局的 推荐用row

binlog_cache_size
  binlog写入buffer
  可动态修改

max_binlog_size
  限制单个binlog大小
  可动态修改 通常配置1M

max_binlog_size
  限制单个binlog大小
  可动态修改 一般建议设置成200M/500M 根据日志产生量 默认是1G

  5min左右刷一个或者10min左右刷一个

  binlog刷新过程数据是提交不了的 所以让binlog刷新慢一点 写数据不会被卡住

sync_binlog = n
  多少个SQL之后,调用fdatasync()函数刷新binlog到disk

  默认是0,在调优中很重要

  多少个sql刷一次binlog的cache,同步到磁盘

  比如说现在写成0就是由系统来刷新binlog cache

  系统觉得binlog大了就去刷新

  对一些交易型的,账单或者扣钱的东西 建议设置成1

  让没个sql都刷新一下binlog 让binlog更安全一点

  当然设置成1了 性能也是最差的,设置成0的时候性能是最好的

  这个是对性能影响很严重的参数

  tokodb不开binlog写入可以达到5,6w

  开启之后写入只能达到2W的写入

expire_logs_days =n
  n天后自动删除binlog
  可动态修改 默认指定为7

  如果不开启就会造成binlog把磁盘占满了

  应用卡住了 也不知道怎么回事

log_bin_trust_function_creators

  默认是0 要用的话改成1就行了

  允许在存储过程调用的时候用到,如果没有涉及存储过程是用不到

log_warnings

  参数级别 默认是2  默认是0

  error log看到Abort connection拒绝连接请求

  如果不想看到这些就把值设置成1

binlog_error_action 

binlog_error_action=ABORT_SERVER

当空间满了写不进去了 会在应用层直接报错 不会直接卡在那里

5.6之前只能再error log里看到

binlog_row_image=[full|minimal|noblog]

也是5.6的

日志格式为row的时候日志里会记录修改之前的和修改之后的记录所以日志很大

利用这个参数之后只保留写后的记录

update tb set c2=xxx where id=xxx;

[minimal]

update tb 
set 
@2=xxx,
where 
@1=xxx,
@2=xxx;

没有变更到的就不记录了

Binlog_rows_query_log_events=[1|0]

默认关闭,(日志格式是row 的时候)开启参数之后会生成query event

会记录用户原始sql

gtid_mode=on

开启的时候必须设置这些参数

log-bin ,

log-slave-updates(从库上也会记录binlog 可以用来备份或者机连备份) ,  

enforce-gtid-consistency(一致性,控制哪些语句能安全的记录到binlog里)

Executed_Gtid_set 执行过的gtid集合

set gtid_next="uuid:NO."; 指定下一个事物是哪个事物

set global gtid_purged='uuid:NO.';

进行同步的时候忽略这个事件之前的,告诉主库包括NO.之前的事物都不要给我了

reset master;

才能清空,清空之后才能设置

Gtid_executed

从库上到底执行过哪些gtid操作

uuid:1-100:300-10000:20001-NNNNN

发现有空洞

有可能做了互为主从造成了空洞

如果是传统的A->B的应该是不会有空洞的

uuid:1-NNNNN

或者是set global gtid_purged开始的 到 NNNNN

show master status\G  

show slave status\G

一样

这个参数也需要reset master

slave的参数

============================================

server-id 

推荐配置service-id可能从库以后要挂从库或者转为主库

relay-log

从本地拿到的binlog会存到relay-log里

relay-log-index

read-only 对非super 用户起作用

set global read-only = 0|1

slave其他参数

log-slow-slave-statements
log_slave_updates
max_relay_log_size
relay-log-info-file
relay_log_purge
relay_log_recovery 
replicate-same-server-id 
skip-slave-start
slave_load_tmpdir
slave_transaction_retries

slave_parallel_workers

log-slow-slave-statements

sql_thread 执行sql超过long_query_time 会记到慢日志中

默认没开启

max_relay_log_size

设置一下relay-log的大小

slave和master不会形成长连接 每次链接就会生成一个relay log

relay-log-info-file =relay.info

relay crash recover

[root@node21 data]# cat relay-log.info 
7
./mysql-relay-bin.000008
4
mybinlog.000005
191
0
0
1
1

执行到005 位置是191

从库忽然挂掉 又起来了同步接不上

要把这个参数打开之后会从binlog005 191这个位置向主库重新请求

在gtid里做了一个变相实现

5.6.21叫 simplified_binlog_gtid_recovery 

5.6.23改名了叫binlog_gtid_recovery_simpliefied

可以从gtid里拿到已经同步到哪个gtid了只要这个gtid之后的数据就行了

5.6.21只前gtid重启之后没有这个重新请求的过程中没有crash recover处理机制

是在5.6.21之后引入进来的

而且这个参数默认是没有开启的

这个功能很好 之前从库挂掉都要去修复

replicate-same-server-id

默认没开启 自己复制自己的server id基本上不用 

skip-slave-start

建议在配置文件里要有

slave启动之后不要默认开启同步

slave_load_tmpdir

指向到tmpdir下 一般不用设置

slave_transaction_retries

sql语句在执行中上层mysql如果发生堵住的情况把某个数据区间锁住了

sql thread就会等待锁的释放 机会有一个重试的过程

当重试超过次数之后 就会报错

start slave sql_thread;

5.6引入  并行复制 库级别的复制

slave_parallel_workers 最大1024

默认是关闭的

如果sql_thread断了但是io_thread还是yes

同步断掉之后本地的relay_log 会记录很多 造成磁盘被写满

所以引入了relay_log_space_limit 限定relay log占用磁盘大小

超过了之后io_thread  会等待relay-log释放空间

relay log执行完会被删掉

SHOW SLAVE HOSTS

slave上需要配置这3个参数

report_password
report_port
report_user

实际生产中很少去配 库都是动态切换的 配置上意义不大

sync_master_info
sync_relay_info

5.5之后 可以吧master info 和 relay info存到数据库里

5.6.17之前这2个参数如果配置成1或者过小会有内存溢出错误

保持默认不变就行了

sync_relay_log   =  sync_binlog

========================================

复制过滤规则

1. 库级别的

2. 表级别

支持: 精确和通配符?

正向逻辑和反向逻辑

分binlog 和sql_thread两个部分

一部分可以控制记录binlog的时候记录什么

另一部分可以在sql thread里面控制执行什么

master 部分

只记录某个db的binlog

replicate-do-db = "leokim"

create database jl;

就不会记录

use jl;

insert into leokim.tb(col1) values(1);

语句格式下是记录不上去的

在行格式是能让记录的

replication-ignore-db="mysql"忽略mysql库

想忽略某个表

replicate-ignore-table=leokim.quota

复制中改库

a_db -> b_db

在slave上才能配置

replicate-rewrite-db='a_db->b_db';

把某个库映射到另一个库上

从库上的

binlog

replicate-wild-do-table
replicate-wild-ignore-table

replicate-wild-do-table="leokim.ds_%";(不是这个前缀的就不计)

mysql同步复制里有个坑

slave_net_timeout

从库和主库多少时间断开才会说连不上主库 — 默认3600S

忽然闪断2min 数据不同步 io_thread 和 sql_thread 都是ok

推荐配置成10

slave_net_timeout=10

slave_skip_errors

slive中复制,忽略那些错误

常见的:

1062 主建冲突

1032 找不到记录

一般建议不允许忽略任何错误

除非从库来不及修又要用

就先skip掉晚上用工具修复

sql_slave_skip_counter
忽略多少个复制事件,遇到个别错误(主键冲突、记录不存在等)时,可以忽略这些事件,继续复制进程
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n;
START SLAVE;
SHOW SLAVE STATUS\G
一般一次只忽略一个事件,除非很肯定,否则不要设置大于1

简单总结:

推荐gtid 管理方便不用找偏移量位置

 

server-id 推荐ip最后一位

传统配置:

#replication 
log-bin=/path/mysql_xxxx/logs/mysql-bin
server-id=[ip]port
log-bin-index=mysql-bin.index
binlog_format=row
binlog_cache_size=1M
max_binlog_size=200M
sync_binlog=0
expire_logs_days=7
log_bin_trust_function_creators=1
#master binlog filter

#slave
relay-log=relay-bin
relay-log-recovery=1

log-slow-slave-statements
log_slave_updates
slave_net_timeout=10
master-retry-count= 86400

MYSQL GTID复制实验

blob.png

blob.png

blob.png

blob.png

我在主库清除了所有binlog然后在leo表里删除了几条记录又重新插入了一些

blob.png

从库操作

change master to master_host='192.168.61.131',master_user='repl',master_password='repl4slave', master_auto_position=1;

blob.png

blob.png

blob.png

可以看到1-3的都copy过来了

示例情况

我在从库插入了一条记录 

在主也插入同样记录的时候,从库同步就会报错

这个时候处理方式是 把从库上的该条重复记录删掉

然后执行

start slave sql_thread;

就继续同步过来了

同样现在从库删除一条记录

然后再去主库删除同样的记录

尽然没有报错 哈哈

update也不会报错 

主库上没有id为2的记录 从库上有id为2的记录

主库上执行delete id 2 从库上的会被干掉

binlog要换成row格式

对于gtid必须要用row格式要么会有很多错误都不爆

上面那些delete update应该出错的就会出现 slave就会起不起来了

跳过错误

set gtid_next=b9c8ef95-27ea-11e7-9c7b-000c29a8f010:10

stop slave;

begin;commit;

blob.png

跳过错误

同步就继续了数据就同步过来了

blob.png

MYSQL传统复制实验

blob.png

blob.png

blob.png

初始化master和slave数据

删除所有数据

blob.png

创建从库账号

blob.pngblob.png

前面的都是初始化的log可以不要

从库也是相同配置

change master to master_host='192.168.61.131',master_user='repl', master_password='repl4slave', master_log_file='mybinlog.000001', master_log_pos=120;

blob.png

blob.png

warning就是不提倡在命令行里直接写密码 哈哈

blob.png

blob.png

这里有个报错 说是因为server id要用不一样的 我去修改一下

blob.png

还是有error

妈蛋···绑定master的mybinerlog写成mybilog了·····

后来试了一下还是有报错

blob.png

最后发现是定义master的时候把密码写错了

blob.png

成功了。

主库上创建leokim的库

blob.png

从库上也生成了leokim这个库

blob.png

主库上创建表

blob.png

从库上也能看到表和数据

blob.png

blob.png

blob.png

blob.png

blob.png