7.7 分布式事务
7.7.1 mysql分布式事务
innodb支持XA事务,通过XA事务支持分布式事务的实现
分布式事务:多个独立事务资源参与到一个全局的事务
事务资源:通常指关系型数据库系统,也指其他类型资源
全局事务要求所有参与的事务要么一起提交要么都回滚
使用分布式事务时innodb的事务隔离级别需要是serializable
XA事务允许不同数据库之前的分布式事务,只要参与全局事务的每个节点都支持XA事务
分布式事务在银行转账中比较常见
XA事务由一个或多个资源管理器、一个事务管理器以及一个应用程序组成
-
资源管理器:提供访问事务资源的方法,通常一个数据就是一个资源管理器
-
事务管理器:协调参与全局事务的各个事务,需要和参与全局事务的所有资源管理器通信
-
应用程序:定义事务的边界,指定全局事务中的操作
在mysql数据库分布式事务中,资源管理器就是mysql数据库,事务管理器是连接mysql服务器的客户端
分布式事务使用两段式提交
- 第一阶段:所有参与全局事务的节点都开始准备,告诉事务管理器他们准备好提交
- 第二阶段:事务管理器告诉资源管理器执行回顾那还是提交,如果任何一个节点不能提交,则所有节点都要回滚
分布式事务需要多一次prepare操作,等所有节点的同意信息收到后再执行commit还是rollback
XA {START | BEGIN} xid {JOIN | RESUME}
XA END xid [SUSPEND [FOR MIGRATE]]
XA PREPARE xid
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
XA RECOVER
7.2.2 内部XA事务
内部XA事务:存在存储引擎和插件之间,或存在存储引擎和存储引擎之间
最常见的内部XA事务:binlog与innodb之间,提供复制的需要
事务提交时,先写binlog,再写redo日志,对这两个操作需要是原子的,需要同时写入,如果binlog先写,而在写入redo时发生宕机,则slave则可能会接收到master传过去的binlog并执行,最终导致主从不一致
如果在(3)之前宕机了,则会发生主从不一致
当事务提交时,innodb先做一个prepare操作,将xid写入,再写入binlog,如果在提交前宕机了,则在重启后会检查准备的uxid事务是否提交,若没有则再进行一次提交
7.8 不好的事务习惯
7.8.1 在循环中提交
innodb默认自动提交,不需要手动commit
即使正确语法,但存在问题,假设插入 1 0000 条数据,插入 5 000 后宕机了,此时很难处理
把一整个循环放进事务中,失败了可以直接回滚
7.8.2 不建议使用自动提交
7.8.3 不建议使用自动回滚,设置某些返回信息
7.9 长事务
执行时间比较长的事务
问题:发生问题时重新开始的代价过大
解决:转化为小批量的事务来处理,发生错误时只需要回滚一部分数据
第 8 章 备份和恢复
8.1 备份与恢复概述
备份方法分类:
- hot backup 热备
运行中直接备份,对正在运行的操作没有影响,online backup在线备份
- cold backup 冷备
在数据库停止时备份,一般只复制相关的物理文件,最为简单
- warm backup 温备
运行中备份,但对正在运行的操作有影响,需加一个全局读锁来保证备份数据的一致性
备份后文件的内容:
- 逻辑备份
导出的文件是可读的,一般是文本文件,为sql语句或者表内实际数组组成
可以观察导出文件内容,使用于数据库升级、迁移等工作
- 裸文件备份
复制物理文件,恢复时间短
备份内容:
- 完全备份
完整备份
- 增量备份
在上一个完整备份上对更改数据备份
- 日志备份
对binlog日志进行备份
通过对一个完全备份进行binlog的重做来完成数据库的point-in-time的恢复工作
mysql复制(replication)原理就是异步实时地将binlog重做并传送到slave数据库
增量备份:记录当前每页最后的检查点的lsn,如果大于之前完全备份的lsn,则备份该页,否则不用备份
备份时需要检查数据库的一致性,要求在备份的时候数据在这一点上是一致的
对设置隔离级别为read repeatable的innodb,其支持mvvc,实现一致备份简单:用户先开启一个事务,然后导出一组相关的表,然后提交
8.2 冷备
备份数据库的frm文件、共享表空间文件、独立表空间文件(*.ibd)、redo日志文件(定期备份配置文件my.cnf)
优点:
-
备份简单,复制相关文件
-
易于在不同操作系统,不同版本mysql恢复
-
速度快
缺点:
- 比逻辑文件大,表空间存放其他数据,如undo段,插入缓冲信息
- 跨平台也只是相比而言简单
8.3 逻辑备份
8.3.1 mysqldump
通常用来完成转存(dump)数据库的备份和不同数据库之间的移植
mysqldump [argument] >file_name
备份所有数据库:
mysqldump --all-databases >dump.sql
备份指定数据库:
mysqldump --databases db1 db2 db3 >dump.sql
对架构备份:
mysqldump --single-transaction test >test_backup.sql
mysqldump --help
查看所有参数
8.3.2 SELECT ... INTO OUTFILE
逻辑备份,导出一张表
fields[terminated by ‘string‘]表示每个列的分隔符
[[optionally] enclosed by ‘char‘]表示对于字符串的包含符
[escaped by ‘char‘]表示转义符
[starting by ‘string‘]每行开始符号
[terminated by ‘string‘]表示每行结束的符号
如果没有指定选项,则默认使用:
file_name表示导出的文件,文件所在路径权限需要是mysql: mysql的
8.3.3 逻辑备份的恢复
通过sql文件恢复
mysql -uroot -p <test_backup.sql
如果到处是包含了创建数据库sql语句,提前删除数据库
也可以通过source 路径
来恢复
8.3.4 LOAD ADTA INFILE
语法:
导入格式与SELECT ... INTO OUTFILE一样
8.3.5 mysqlimport
是LOAD ADTA INFILE的命令接口,语法大概相同
8.4 二进制日志备份与恢复
默认不启用,在配置文件中配置
log-bin=mysql-bin
sync_binlog = 1
innodb_support_xa=1
恢复binlog:mysqlbinlog
mysqlbinlog [options] log_file0 | log_file| ...
--start-position 和 --stop-position从binlog中指定恢复
--start-time 和 --stop-time 时间点
8.5 热备
8.5.1 ibbackup
原理:
- 记录备份开始时redo日志检查点的lsn
- 复制共享表空间文件及独立表空间文件
- 记录复制表空间后redo日志检查点的lsn
- 复制在备份时产生的redo日志
优点:
- 在线备份,不会阻塞其他语句
- 备份实质是复制数据库文件和redo日志文件
- 支持备份压缩
- 跨平台
恢复:
- 恢复表空间文件
- 使用redo日志文件
8.5.3 XtraBackup实现增量备份
原理:
- 完成一个完全备份,记录下此时检查点的lsn
- 在进行增量备份时,比较表空间中每个页的lsn是否大于上次备份的lsn,是则备份该页,同时记录当前检查点的lsn
8.6 快照备份
通过文件系统支持的快照功能对数据库进行备份,前提是所有数据库文件放在同一文件分区中,然后对该分区进行快照操作
8.7 复制
8.7.1 复制的工作原理
replication的原理分3步骤
- 主服务器Master把数据记录到binlog中
- 从服务器slave吧binlog复制带自己的中继日志中relay log
- 从服务器重做中继日志中的记录,更改到自己的数据库上,实现数据最终一致性
基本实时进行着(异步实时)
从服务器有 2 个线程,一个是I/O线程,负责读取主服务器的binlog,并保存为relay log
一个是sql线程,复制执行relay log
性能低已淘汰
show master status\G
show slave status\G
8.7.2 快照 + 复制的备份架构
复制的功能
- 数据分布
- 读取的负载平衡
建立多个服务器,将读取平均地分布到这些从服务器中,减少主服务器压力
- 数据库备份:还是不能完全代替备份
- 高可用性和故障转移
当误操作时可从 slave从服务器是快照上进行恢复
第 9 章 性能调优
- 选择合适的CPU
- 内存的重要性
- 硬盘对数据库性能的影响
- 合理地设置RAID
- 操作系统选择
- 不同文件系统对数据库的影响
- 选择合适的基准测试工具
9.1 选择合适的CPU
OLTP:在线事务处理
- 银行交易
- 数据库容量小
- 操作并发量大
- 处理时间短
- 查询简单,走索引
- IO密集型
OLAP:在线事务分析
- 复杂sql查询
- CPU密集型
修改参数innodb_read_io_threads、innodb_write_io_threads来增大IO线程
mysql> show variables like ‘innodb_read_io_threads‘;
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| innodb_read_io_threads | 4 |
+------------------------+-------+
1 row in set, 1 warning (0.12 sec)
mysql> show variables like ‘innodb_write_io_threads‘;
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| innodb_write_io_threads | 4 |
+-------------------------+-------+
1 row in set, 1 warning (0.00 sec)
9.2 内存的重要性
查看缓冲池参数:
mysql> show global status like ‘innodb%read%‘\G
*************************** 1. row ***************************
Variable_name: Innodb_buffer_pool_read_ahead_rnd
Value: 0
*************************** 2. row ***************************
Variable_name: Innodb_buffer_pool_read_ahead
Value: 0
*************************** 3. row ***************************
Variable_name: Innodb_buffer_pool_read_ahead_evicted
Value: 0
*************************** 4. row ***************************
Variable_name: Innodb_buffer_pool_read_requests
Value: 15175
*************************** 5. row ***************************
Variable_name: Innodb_buffer_pool_reads
Value: 1033
*************************** 6. row ***************************
Variable_name: Innodb_data_pending_reads
Value: 0
*************************** 7. row ***************************
Variable_name: Innodb_data_read
Value: 16995328
*************************** 8. row ***************************
Variable_name: Innodb_data_reads
Value: 1056
*************************** 9. row ***************************
Variable_name: Innodb_pages_read
Value: 1033
*************************** 10. row ***************************
Variable_name: Innodb_rows_read
Value: 0
*************************** 11. row ***************************
Variable_name: Innodb_system_rows_read
Value: 4782
*************************** 12. row ***************************
Variable_name: Innodb_sampled_pages_read
Value: 0
12 rows in set (0.24 sec)
9.4.2 RAID Write Back功能
RAID控制器将写入的数据放入自身缓存,再安排到后面执行,提供电池备份,操作系统或数据库关机时可以继续工作