Loading

mariadb的日志,存储引擎,GTID原理小计

 

1,日志刷新保存

事务日志:事务日志的写入类型为“追加”,其操做为“顺序IO”,通常被称为:预写式日志 write ahead logging

事务日志文件: ib_logfile0, ib_logfile1

innodb事务日志包括redo log和undo log。redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作

事务日志与二进制日志区别:

  • 区别一
♦ 二进制日志不依赖存储引擎
♦ 事务日志依赖存储引擎

• 区别二
♦ 二进制不覆盖之前的日志
♦ 事务日志覆盖之前的日志

• 区别三
♦ 二进制日志是完整的事务
♦ 事务日志有不完全的事务

redo日志与undo日志的主要区别:

* undo:在恢复时取消未完成事务的影响,忽略已提交的事务

   redo: 忽略未完成事务。重做已提交的事务

* undo: 先将修改后的数据写入到磁盘------写<commit  t >  到磁盘  (这里不太懂,修改后的数据指哪里的,undo日志记录事务未提交前修改数据语句前的数据,如果undo日志已经缓存或已经持久化,人为回滚操作,数据恢复,这样看来,修改后的数据应该已经在缓存里)

   redo: 先写<commit  t >  到磁盘----将修改后的数据写入到磁盘

*undo:恢复时需要的是旧值,redo重做时需要的是新值

 

日志写入磁盘

 inno db_flush_log_at_trx_commit 默认为1,这个变量与日志写入时机有关

1默认情况下,日志缓冲区将写入日志文件,并在每次事务后执行刷新到磁盘。这是完全遵守ACID特性
0提交时没有任何操作; 而是每秒执行一次日志缓冲区写入和刷新。 这样可以提供更好的性能,但服务器崩溃可以清除最后一秒的事务
2每次提交后都会写入日志缓冲区,但每秒都会进行一次刷新。 性能比0略好一些,但操作系统或停电可能导致最后一秒的交易丢失
3模拟MariaDB 5.5组提交(每组提交3个同步),此项MariaDB 10.0支持

 

 2,数据引擎

MyISAM引擎特点:

  • 不支持事务
  • 表级锁定
  • 读写相互阻塞,写入不能读,读时不能写
  • 只缓存索引
  • 不支持外键约束
  • 不支持聚簇索引
  • 读取数据较快,占用资源较少
  • 不支持MVCC(多版本并发控制机制)高并发
  • 崩溃恢复性较差
  • MySQL5.5.5前默认的数据库引擎

      适用的场景:

  • 只读(或者写较少)、表较小(可以接受长时间进行修复操作)
  • 引擎的文件
  • tbl_name.frm 表格式定义
  • tbl_name.MYD 数据文件
  • tbl_name.MYI 索引文件

InnoDB引擎特点:

  • 行级锁
  • 支持事务,适合处理大量短期事务
  • 读写阻塞与事务隔离级别相关
  • 可缓存数据和索引
  • 支持聚簇索引
  • 崩溃恢复性更好
  • 支持MVCC高并发
  • 从MySQL5.5后支持全文索引
  • 从MySQL5.5.5开始为默认的数据库引擎

可已创建表时指定数据引擎,或在配置文件中指定默认存储引擎

[mysqld]
default_storage_engine= InnoDB
或:

 CREATE TABLE tb_name(... ) ENGINE=InnoDB;
 ALTER TABLE tb_name ENGINE=InnoDB;

查询缓存原理:

缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预
处理查询语句请求,先去查询缓存,判断是否存在可用的记录集。

判断标准:与缓存的SQL语句,是否完全一样,区分大小写

优缺点:

不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能。

查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低其效率;
查询缓存的使用,会增加检查和清理Query Cache中记录集的开销。

 

3,索引: 索引(Index)是帮助MySQL高效获取数据的数据结构

常见的查询算法:

1,顺序查找 数据结构:有序或无序队列  复杂度:O(n) 
2,二分查找: 数据结构:有序数组  复杂度:O(logn) 
3,二叉树查找:
二叉排序树的特点是:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
搜索原理:
1. 若b是空树,则搜索失败,否则:
2. 若x等于b的根节点的数据域之值,则查找成功;否则:
3. 若x小于b的根节点的数据域之值,则搜索左子树;否则:
4. 查找右子树
数据结构:二叉排序树 
时间复杂度: O(log2N)
4,哈希散列法(哈希表)
首先根据key值和哈希函数创建一个哈希表(散列表),然后根据键值,通过散列函数,定位数据元素位置。
数据结构:哈希表 
时间复杂度:几乎是O(1),取决于产生冲突的多少
5,分块查询法:
分块查找又称索引顺序查找,它是顺序查找的一种改进方法。其算法思想是将n个数据元素”按块有序”划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须”按块有序”;即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,依次类推

## 平衡二叉树 

是基于二分法的策略提高数据的查找速度的二叉树的数据结构。

特点:

平衡二叉树是采用二分法思维把数据按规则组装成一个树形结构的数据,用这个树形结构的数据减少无关数据的检索,大大的提升了数据检索的速度;平衡二叉树的数据结构组装过程有以下规则:
(1)非叶子节点只能允许最多两个子节点存在。
(2)每一个非叶子节点数据分布规则为左边的子节点小当前节点的值,右边的子节点大于当前节点的值(这里值是基于自己的算法规则而定的,比如hash值);

##平衡多路搜索树(B-tree)

B树和平衡二叉树稍有不同的是B树属于多叉树,又名平衡多路查找树(查找路径不只两个),数据库索引技术里大量使用者B树和B+树的数据结构

规则:

(1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;
(2)子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);
(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);
(4)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子;

## B+tree

MySQL就普遍使用B+Tree实现其索引结构

规则:

(1)B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
(2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;
(3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
(4)非叶子节点的子节点数=关键字数

特点:

1、B+树的层级更少:相较于B树B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;
2、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;
3、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
4、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。
B树相对于B+树的优点是,如果经常访问的数据离根节点很近,而B树非叶子节点本身存有关键字其数据的地址,所以这种数据检索的时候会要比B+树快。

 

mysql 索引实现:

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。

 

 

innodb 索引实现

InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这种结构被称为聚簇索引。

 

 

 

 聚簇索引和非聚簇索引的区别的:
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。

 4,GTID

Gtid的全称为global transaction identifier,根据原始机器及事务操做序列生成一个独一的全局事务标识。

概念:

1、全局事务标识:global transaction identifiers。
2、GTID是一个事务一一对应,并且全局唯一ID。
3、一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
4、GTID用来代替传统复制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
5、MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。
6、在传统的slave端,binlog是不用开启的,但是在GTID中slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)
GTID的组成
1.GTID = source_id:transaction_id
2.source_id,用于鉴别原服务器,即mysql服务器唯一的的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID。
3.transaction_id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务。
GTID的优势
1、更简单的实现failover,不用以前那样在需要找log_file和log_pos。
2、更简单的搭建主从复制。
3、比传统的复制更加安全。
4、GTID是连续的没有空洞的,保证数据的一致性,零丢失。

工作原理:
1、当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
2、binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
5、如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,
在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描
GTID的限制
1.不支持非事务引擎
2.不支持create table … select 语句复制(主库直接报错)
原理:( 会生成两个sql,一个是DDL创建表SQL,一个是insert into 插入数据的sql。由于DDL会导致自动提交,所以这个sql至少需要两个GTID,但是GTID模式下,只能给这个sql生成一个GTID )
3.不允许一个SQL同时更新一个事务引擎表和非事务引擎表
4.在一个复制组中,必须要求统一开启GTID或者是关闭GTID
5.开启GTID需要重启(5.7除外)
6.开启GTID后,就不再使用原来的传统复制方式
7.对于create temporary table 和 drop temporary table语句不支持
8.不支持sql_slave_skip_counter

 

附:

知识点极多,碎片化学习成本高,只是限于短时记忆,应该系统的学习知识,以上有许多点没有联系起来。

感谢互联网及分享知识的人。

 

posted @ 2019-05-12 11:43  Lust4Life  阅读(332)  评论(0)    收藏  举报