SQL基础数据结构

内存池MEM_ROOT

  • 目的: malloc函数申请的内存使用完要使用free函数释放, 但向MEM_ROOT申请的内存,只需要在设为空闲块或释放时需要使用free,这样管理简单不要跟踪每个已分配的内存。
    具有相同生命周期的变量向同一个MEM_ROOT实例申请内存,生命周期结束后就释放内存。
  • 内存池:mariadb使用MEM_ROOT动态管理内存分配,MEM_ROOT向内存申请大块连续内存,程序再向MEN_ROOT请求所需内存。
  1. 优点: 减少malloc的调用,减少内存碎片产生。
  • 内存碎片问题:
    原因:程序请求内存大小和内存释放的时间不同,导致大块连续内存空间被划分为小块不连续内存空间,分为内部碎片和外部碎片。
  1. 内部碎片
    分配器分配的内存空间比请求大(因为对齐和用于free的调用),程序内部未使用的碎片内存–内存碎片。
  2. 外部碎片
    指还没分配的,但太小无法满足程序的大块连续内存申请的空闲内存。

Linux内核使用伙伴系统和slab对象缓存来减少内存碎片的发生

伙伴系统

  1. 伙伴系统算法解决外部碎片问题。
    内核将空闲连续页框分为11组,对应11个空闲链表,分别包含1、2、4、8、16、32、64、128、256、512、1024个连续页框, 第N个页框的起始物理地址是N2^12 (N页大小4K)。
    算法:
    *. 请求N个连续页框的空闲块时,在N对应的的链表中查找,有就直接分配;
    . 没有就在N2对应链表中查找;
    . 如果还没找到,就在N4表中查找,如果找到N4连续页框就被分为N+N+N2,剩下的空闲块加入对应的链表。
    *. 内核会将大小一致,物理地址连续的空闲块合并,再加入空闲链表.
    glibc的内存管理器ptmalloc也采用伙伴系统算法管理内存

MEM_ROOT定义

进程内通常是内部碎片的问题
缓解策略:总是向内存申请4、8、16整数倍的大块内存,减少非对齐内存的申请

  1. USED_MEM结构:从内存分配器分配的一个内存块
    next:下一个内存块,实现链表
    left:剩余内存块
    size:当前内存块大小

  2. MEN_ROOT使用这种策略管理内存:MEN_ROOT向内存分配器申请大块对齐的内存,程序向MEN_ROOT申请小块的内存
    MEM_ROOT结构:管理所有已分配的内存块
    free链表:包含足够大的内存空间的内存块
    used链表:很小剩余空间,或全部用满的内存块
    pre_alloc:初始化时与分配的内存块
    min_malloc:阀值,内存块低于它时,改内存块移到used链表
    block_size:内存块大小是block_size的整数倍
    block_num:用于计算新分配内存块的大小
    first_block_usage:计数器,内存块多次不能满足请求时,出于效率考虑,将其加入used内存块链表
    err_handler:错误处理函数
    MEM_ROOT的使用
    MEN_ROOT men_root;
    init_alloc_root(&mem_root, 2096, 0); //初始化MEM_ROOT
    char p1 = (char)alloc_root(&mem_root, 128); // 分配内存
    free_root(&mem_root, 0); //释放内存,如果使用MY_MARK_BLOCKS_FREE仅仅标记为空闲(加入free链表),不返回给内存管理器

高性能武器–缓存

意义:减少慢速操作的执行次数,提高性能

CPU L1/L2 cache

    cpu运行越来越快,内存的速度提升却很慢
    CPU cache 是位于在CPU和主存之间的能提高读写的内存(存在CPU中)
    二级缓存位于一级缓存和主存之间,容量比一级缓存大,速度比一级缓存慢比内存快

页高速缓存

访问内存一次20 -100ns,范围磁盘一次10ms左右。
Linux内核使用page cache页面(4K)缓存机制加快对磁盘文件的读写, 页面缓冲区是内存中用于缓存磁盘文件数据的一块区域。
对于磁盘文件的读请求,内核直接在页高速缓存区查找;如果没有,从磁盘读取相应的页,同时读取紧随其后的少数页,并放入页高速缓冲区中。
对于磁盘文件的写请求,内核直接修改页高速缓冲区中对应的页,修改为脏页,内核再定期回写到磁盘中。

分布式内存缓存—memcached

    经常被用来缓存数据库查询结果,减少慢速的数据库访问操作和计算操作,提高性能。

IO_CACHE定义

枚举类型cache_type,指定IO_CACHE的类型,如READ_CACHE等
    enum cache_type
    {
        TYPE_NOT_SET=0,
        READ_CACHE,
        WRITE_CACHE,
        SEQ_READ_APPEND,
        READ_FIFO,
        READ_NET,
        WRITE_NET
    };

IO_CACHE是MariaDB中定义的I/O缓存结构,许多磁盘文件的操作都是通过IO_CACHE进行的,还作为网络IO 的缓冲区

IO_CACHE的使用
  1. 读缓存READ_CACHE
    IO_CACHE可以作为磁盘文件的应用层面的读缓存,减少磁盘文件的读操作。
    算法:先读取缓存中是否包含请求的数据,如果没有就从磁盘读取包含请求数据的一大块数据到缓存中;根据数据的局部性原理(两次相邻请求的数据位于前一次请求的数据附近)提高磁盘文件的读效率。
  2. 写缓存WRITE_CACHE
    算法:减少写磁盘文件的次数
  3. IO_CACHE作为顺序读取追加缓存SEQ_READ_APPEND
    顺序读:只能从前往后读取
    追加写:只能从文件末尾追加数据。
    与写缓存功能差不多,一方面将缓存中数据刷入文件中,一方面释放已分配的内存,
    分配两倍cachesize大小的内存,前半部分作为顺序读缓冲区,后半部分作为追加写缓冲区,
    从IO_CACHE中读取数据的顺序:1、seq_read_buffer—->2、文件—–>3、append_buffer(需要加锁)。

线程上下文—-THD

线程描述符,包含一个线程的上下文信息
一个THD实例对应一个线程,如果使用线程池技术,一个连接对应一个THD实例
THD实例还可以对应MariaDB中其它系统线程

TABLE_SHARE

定义了数据库表的基本信息
一个TABLE_SHARE实例对应于数据库中的一个表
查询语句时,打开表,这时创建一个TABLE实例,如果对应的TABLE_SHARE不存在(第一次使用这个表或FLUSH tables),
那么需要从.frm文件中读取表的信息,然后创建对应的TABLE_SHARE实例
一个数据库表对应一个TABLE_SHARE实例,一个实例可以对应(被共享)多个TABLE实例

TABLE

定义了数据库表的描述符
打开语句中的表就会创建一个TABLE实例





转载于:https://www.cnblogs.com/auyeungcarl/p/6913105.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值