MVCC(Multi-Version Concurrency Control,多版本并发控制)
基本概念
当前读(Current Read):最新版本,不能修改当前记录(一般就是加锁的那种 lock in share mode如金融交易、库存扣减。),通过共享锁(LOCK IN SHARE MODE
)或排他锁(FOR UPDATE
)阻塞其他事务的写操作
快照读(Snapshot Read):select 语句(读取事务开始时的数据快照(历史版本),无需加锁
基于MVCC机制,通过undo log
版本链和Read View
选择可见版本,不阻塞其他事务的读写,高并发性能好。允许延迟一致(如报表查询)
实现方式(隐藏字段+undo log+readview)
三个隐式字段
trx_id: 记录 修改数据事务 对应的 事务id roll_ptr:undo log 回滚 指向这条记录的上一个版本 row_id: 没有主键,自动生成 叫隐藏主键
uodolog回滚日志
记录版本链条(roll_ptr) 头部是最新的旧记录 , 尾部是最早的旧记录(往前面加)
readView(读视图)
快照读 记录 当前 未提交 事务的id(m_ids/min_trx_id/max_trx_id /creator_trx_id)
总结:MVCC通过版本链、Undo Log和Read View的协作,实现了高效的并发控制,
主从复制(实现原理,搭建方式)
简单概述
将主数据库(master)的DDL/DML 语句通过 binlog(二进制日志) 传到 从数据库(slave)
三个方面主从复制的必要性
- 主库宕机,从库替换
- 读写分离,减低主库的访问压力
- 在从库备份,优化主库性能
主从复制的实现 原理三个步骤
- 主库 增删改 操作记录到 binlog (变成二进制数据)
- 从库--通过 IOThread 读取(二进制数据),写入Relaylog (中继日志)
- 从库 --通过 SQLthread 重做(relaylog) ,变成自己的数据存储
总而言之:主库-输出二进制(binlog)-从库 I/O线程输入 中继日志 relaylog 再线程转化为自己的数据!!!!!!!
搭建
###################准备两台服务器,设计阶段关闭防火墙
systemctl stop firewalld;
#关闭开机自启动
systemctl disable firewalld;
##如果是服务阶段 开放指定端口
firewall-cmd--zone=publc--add-port=3306/tcp-permannet
firewall-cmd-reload
###################主库 配置 集群唯一
server-id=1;
#只读1 读写0
read-only=0;
#f赋予'hhh'@'%'主从复制的权限 replication (复制的意思)
grant replication slave on *.* to 'hhh'@'%';
#查看 二进制日志坐标
show master status;
#################以下在从库操作########
######修改位置 /etc/my.cnf
#从库 配置 集群唯一 和主库不一样就行
server-id=2;
#只读1 读写0
read-only=1;
#连接 登入 mysql 在从库执行 连接 手机 连WiFi 一样
change replication source to source_host='192.168.200.200' ,source_user='hhh',
source_password='root' ,source_log_file='binlog.000004',source_log_pos=663;
#启动 同步操作
start replica;
分库分表(垂直拆分/水平拆分/实现技术)
问题:数据量大,单数据库:IO瓶颈 ,CPU瓶颈
中心思想:将数据分散存储,将单一数据库 /表 的数据量减小 。
垂直拆分
- 垂直分表 ---分字段(姓名/身份证号/地址 对应 分成三个数据库存储 )
- 垂直分库---分表(订单表/员工表/用户表 对应 分成三个数据库存储)
水平拆分
- 水平分库---分表 (订单表/员工表/用户表 其中一个数据库拥有三张表的部分信息)
- 水平分表---分字段(姓名/身份证/地址 其中一个数据库 拥有 三个字段的部分信息 )
实现技术:
shardingJDBC:基于AOP 原理 ,对sql 进行拦截 ,解析,改写,路由处理,自行编码实现,只支持Java语言,性能高
Mycat:数据库分库分表 中间件 ,无需编码,多语言,性能不如前者(就是帮mysql的APP) 三个服务器==分片服务器
读写分离(一主一从读写分离,双主双从读写分离)
介绍:基于主从复制 (基于二进制binlog),读操作与写操作分离,主库写,从库读,减轻单台数据库压力(通过Mycat支持:writeHost/readHost)
日志(错误,二进制,慢查询,查询)
错误日志(log_error)
作用:排查问题,定位问题 文件地址:var/lib/mysqld.log
二进制日志(bin log)
作用: 灾难数据恢复, 主从复制,默认row格式开启 记录了DDL/DML(处了select,show)
慢查询日志(slow log)
记录执行效率低,慢速度的sql
查询日志(query log)
记录了所有操作语句,默认不开启,文件太大
InnoDB结构
逻辑存储结构
包含关系:表空间tablespace》段 segment》区 extent》page页》row行
表空间:mysql.idb 文件 (记录,索引,)
段:数据段(叶子节点),索引段(非叶子节点) ,回滚段 区: 区大小1M
页: 16k 行:数据 trx_id (每次事务进行修改 ,会给对应事务id 隐藏列)
Roll_pointer (修改记录,把旧版本存入undolog ,指针找到旧版本 隐藏列 )
内存架构
Buffer Pool: DML增删改查 先操作 缓冲池子 里的数据,减少磁盘I/O (页为单位)
Adpative Hash Index: 要是哈希索引可以提高查询速度 自动建立哈希
重要!!!!Change Buffer: 在DML 如果Buffer Pool 没有缓存数据,不要直接访问磁盘,先存到Change Buffer等数据被读取,再合并 buffer pool 批量处理 (针对非唯一二级索引,日志、账单系统,写入后延迟查询的场景收益最大)总之就是存在一起处理
Log Buffer:日志缓冲区,保存 redolog undolog (16MB)定期刷入磁盘(大小,时机)