一条SQL查询语句是如何执行的 MySQL学习笔记 一

大体来说MySQL可以分为Server层和存储引擎层两部分。 Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。 存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。现在最常用的存储引擎是InnoDB,从MySQL5.5.5版本开始成为了默认存储引擎。

……

Continue reading

Redis String

一、数据结构基础

  1. sds在C字符数组的基础上增加了长度和空间元数据,使基于字符串长度的追加、复制、比较等操作可以直接读取元数据,提升效率。。
  2. SDS总共设计了五种类型,分别为sdshdr5、sdshdr8、sdshdr16、sdshdr32和sdshdr64。他们的主要区别是数据结构中字符数组现有len和分配空间长度alloc的不同,sdshdr5没有被使用,后四种len数据类型分别为uint8_t、uint16_t、uint32_t、uint64_t。
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
  1. SDS设计不同的结构头是为了灵活保存不同大小的字符串,从而有效节省空间。结构头占用内存空间不一样,保存小字符串时结构头占用小可以节约内存。
  2. 结构体定义中__attribute__ ((__packed__))的作用是告诉编译器不要使用字节对齐方式,而是采用紧凑型额方式分配内存(默认情况编译器会按照8字节对齐的方式分配内存)。
  3. 为了避免频繁内存重新分配,当SDS扩容时,如果所需内存小于1M时扩容翻倍,当大于等于1M时扩大1M。
  4. SDS保存数据的末尾设置为空字符,并且总会为buf数组分配空间时多分配一个字节来容纳这个空字符,使保存文本数据的SDS可以重用一部分<string.h>库定义的函数。
  5. SDS采用惰性空间的释放策略。

二、C字符串与SDS比较

……

Continue reading

Redis Hash

  1. Redis中的dict数据结构采用链式哈希方式存储。负载因子大于等于1时触发哈希扩容检测,当存在RDB子进程或者AOF子进程时关闭哈希扩容(避免父进程大量写时复制),不过即使没开启hash扩容在负载因子大于dict_force_resize_ratio时也会执行哈希扩容,扩容大小为当前容量的2倍。
  2. 当往Redis中写入新的键值对或者是修改键值对时,Redis都会判断是否需要rehash,函数调用链为:dictAdd/dictReplace/dictAddOrFind -> dictAddRaw -> _dictKeyIndex -> _dictExpandIfNeeded。
  3. Redis哈希扩容时使用渐进式rehash,即每次只进行n个bucket的rehash处理,避免大量的键需要从原来的位置拷贝到新位置时主线程无法执行其他请求而阻塞;rehash时当出现10*n个都为空bucket时会结束本次处理,防止阻塞太长时间。
  4. Redis中有五处函数调用_dictRehashStep进而调用dictRehash函数来执行rehash,调用链为:ictAddRow/dictGenericDelete/dictFind/dictGetRandomKey/dictGetSomeKeys -> _dictRehashStep -> dictRehash。
  5. 全局哈希表除了主动函数调用(增删改查)执行rehash外还有定时rehash,主线程会默认每间隔100ms执行一次迁移操作。单次以100bucket作为单位迁移数据,如果超过1ms就结束当前迁移。
  6. 在rehash期间,查询hash表找不到结果时还会在新哈希表查询一次。
……

Continue reading

Redis核心技术与实战 学习笔记 一

Redis的特性是“快”。一方面是因为它是内存数据库,所有操作都在内存上完成,内存的访问速度本身就很快。另一方面归功于它的数据结构。键值对是按一定的数据结构来组织的,操作键值对最终就是对数据结构进行增删改查操作,所以高效的数据结构是Redis快速处理的基础。

……

Continue reading