- 博客(15)
- 收藏
- 关注
原创 MySQL联查该如何优化?
此外还有一种Hash-Join优化思路(Mysql没有官方支持该方案),将驱动表的数据行加载到内存中,构建hash,然后查询被驱动表的记录行,每读取到一行就通过hash进行匹配驱动表,这种方案比临时表的方案更快。先将Join_Buffer中的记录行排序,然后批量匹配,匹配到的数据作为结果集一部分,然后清空缓存,继续读取T1的记录行。3)T2的数据不会放入JoinBuffer中,只是挨个扫描T2的记录行(当然,扫描过的数据页会被加载到内存中),每扫描一行跟Join Buffer中的记录匹配一次。
2024-12-31 11:24:52
404
原创 Redis如何保证高可用?
replication backlog是一个环形队列,它是各个从库共享的,只要有一个从库与主库还处在连接中,那么replication backlog就继续存在。然后,主库会将replication buffer中的指令发送给从库,从库执行replication buffer中的操作指令,从而实现主从数据一致。当该节点收到多数节点认为主库已下线的回复之后,会立刻向其他哨兵节点发送希望自身作为leader的命令,当该节点收到多数同意答复后,该节点就成为了leader。在从库上进行读操作,来分摊主库的读压力。
2024-12-19 14:26:37
825
原创 Redis如何保证数据不丢失?
整体思路是当AOF超过配置阈值时,将Redis内存中的数据复制一份出来,由后台子进程将Redis中的数据依次拷贝成写入操作,然后将新的写入操作记录到新的AOF文件中。当瘦身操作完成之后,会将AOF重写日志的记录写入到新的AOF文件中,然后用新的AOF文件替换旧的AOF文件,最终实现瘦身的目的。上次备份到Redis崩溃重启间的数据是会丢失的,这对业务也是难以接受的。AOF中的记录需要持久化到AOF磁盘文件中,否则Redis发生崩溃重启,那么在内存中的AOF记录是无法恢复的,也就无法用来恢复Redis的数据。
2024-12-03 17:08:56
625
原创 关于二叉树的一些总结
如果从0开始,已知索引x,其左子节点的索引为2*x+1,右子节点的索引为2*x+2,其父节点的索引为(x-1)/2。因为每个节点在数组中的位置都是固定的,因此当用数组保存非完全二叉树的时候,会有很多的空闲位置,造成空间的浪费。在查找插入位置的过程中,如果碰到一个节点的值,与要插入数据的值相同,我们就将这个要插入的数据放到这个节点的右子树,也就是说,把这个新插入的数据当作大于这个节点的值来处理。在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值。
2024-11-30 11:52:42
920
原创 单线程Redis为什么这么快?
服务端中,基本的网络IO需要经过监听客户端请求(bind/listen),和客户端建立连接(accept),从 socket 中读取请求(recv),解析客户端发送请求(parse),最终由业务系统处理解析过后的内容。socket() 方法会返回主动套接字,然后调用 listen() 方法,将主动套接字转化为监听套接字,此时,可以监听来自客户端的连接请求。Redis 的单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。
2024-11-24 10:49:55
320
原创 关于散列表的一些总结
合理设置装载因子的阈值,超过阈值的话,分配一个更大的散列表,然后逐步复制(将复制操作分散到各个操作中),均摊时间复杂度即为f(1)。数据删除的时候,将对应的元素标记为删除,不能直接删除。而二次探测探测的步长变成了原来的“二次方”,也就是说,它探测的下标序列就是 hash(key)+0,hash(key)+1^2,hash(key)+2^2……2)基于链表的散列冲突处理方法比较适合存储大对象、大数据量的散列表,而且,比起开放寻址法,它更加灵活,支持更多的优化策略,比如用红黑树、跳表代替链表。
2024-11-16 14:18:04
443
原创 关于MySQL存储空间的一些总结
具体优化逻辑是在复制表数据的同时,如果将原表的写操作记录日志,等待复制数据完成之后,将日志中的操作应用到新的表中,最后在进行替换操作。此处需要注意的是,重建表的alter操作需要先获取到MDL的写锁,然后再复制数据的时候写锁退化为读锁,此举是为了防止再重建表期间有其他的DDL操作。通过重建表操作,可以将数据页被标记为删除的空间释放出来,从而提高页空间的利用率。综上,对表数据的增删改之后,数据页会产生很多的空间被标记为删除,如果只是单纯的delete只是标记删除,并不会真正的去释放存储空间。
2024-11-13 17:49:02
278
原创 关于MySQL锁的一些总结
事务堵塞时,主动检测释当前事务的加入释放会导致死锁,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。行锁是针对数据表中行记录的锁,比如事务 A 更新了一行,而这时候事务 B 也要更新同一行,则必须等事务 A 的操作完成后才能进行更新。MySqlDump使用-single-transaction,但是当全库数据量太大,导致备份时间过长,使得可重复读事务太长,占用资源,有可能会导致MySql服务重启。行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。
2024-10-27 19:47:15
284
原创 关于MySQL索引的一些总结
因此最佳实践方式是使用自增长数字字段作为主键索引,数据写入的时候天然追加,无需修改数据页,这样还有一个好用,数据字段占用空间较小,作为非主键索引的值时能够减少空间占用。举例来说,如果一张表建立a和b两个字段的联合索引,然后查询条件是like a和b,则根据索引下推可以在搜索a的时候同时比对b,不需要回到主键索引中比较。有序数组:以有序数据来组织索引,通过二分法查找,复杂度为logn,效率非常高,适用于查询查询。设计索引字段时,覆盖业务所需的查询字段,使得该联合索引包含业务所需求的字段,无需回表,提高效率。
2024-10-27 01:11:35
242
原创 关于MySQL事务的一些总结
由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的undolog都必须保留,这就会导致大量占用存储空间。MySql中的数据有多个版本,每个版本都有一个row trx_id,该row trx_id就是写入该数据的事务ID,并且该版本数据还存在对应的undolog,通过对应的undolog即可获得上一个版本的数据。它是事务启动的时候向Innodb事务系统申请的,并且是顺序递增的。1 如果落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;
2024-10-21 23:08:24
722
原创 装箱拆箱到底做了什么?
通过上述的操作,我们找到Person的Obj实例在内存中的位置,最后观察其结构,发现首位置为空,第二部分为Person方法表指针,剩下的就是字符串指针以及int值10。然后通过指令k观察main方法的函数栈,因为在上述代码中,所有的Person值(包括值类型、引用类型)的Name值都是张三,所以可以通过字符串张三的指针值去查找两个值类型在函数栈上的位置。可以发现栈上有2处结构体,下面对应是第一个Person,它的Age字段赋值被为11,正好对应十六进制的0b,上面的0c对应十六进制的12。
2024-09-14 22:26:30
1073
原创 PortableThreadPool浅析
创建必要的线程池线程之后,通过GateThread.EnsureRunning确保线程池启动一个GateThread,该线程负责其他线程池线程的管理工作,比如任务委托数量超过最小线程数后,在必要的情况下慢速创建新的线程池线程,直到最大线程数。:避免线程池委托任务饥饿的机制,启动一个GateThread监控线程池委托任务的堆积情况,在不超过最大线程池数量的情况下,缓速创建新的线程池线程。:net6以后用从c#开发的线程池,线程池承载类,负责线程池工作线程的管理工作。
2024-09-11 15:07:41
932
原创 类实例在内存中到底长什么样?
其次再对该内存上的第一个指针位上的数据执行 dumpmt ,在clr中类型变量保存了指向实例的第二部分的指针,此处即可看到该实例是Product的一个类实例。1) 一个指针位大小的对象头,该部分处于该实例在内存中的最前端,用于实现lock机制,并且还可以作为实例hash值的缓存。接下来再看下实例的第一部分数据,因为此处并没有执行lock操作或者hash,所以此处内存并没有任何数据。在CLR中,可以通过new创建对应类的实例。然后观察该地址上的数据,dp:按照指针的格式显示指定地址上的数据,
2024-09-10 18:08:34
285
原创 Windbg下查询已知对象被哪些代码使用的思路
5可以将步骤3所得的结果与步骤1中的结果进行差值排查,原因:步骤2所得的都是一些引用了对象A的其他类型对象,而操作对象A时会将对象A的一个指针所在内存地址值存放于调用栈空间或者存在寄存器中,步骤3与步骤2的一些差值很有可能就是这些指针,这些临时指针的地址值会被硬编码在汇编代码中,所以步骤4可以找到这些硬编码所在的内存位置(汇编指令地址),最后执行!如果当前的dump抓得不好,对象的地址也有可能在某个时间被存放与寄存器中,但是抓取dump时寄存器的值被替换,那这种情况下,这种方式就没啥用。
2024-09-07 23:08:34
275
1
原创 Windbg下对NT堆异常内存的排查
在 Windows 平台上有一个非常底层的内存分配函数 VirtualAlloc,它会一次性分配 64k 整数倍的内存段,内部对象按4k的内存页对齐,如果让程序直接接触 VirtualAlloc,很容易造成内存的浪费以及分配效能的降低,为了提高性能和内存使用效率, Windows 给进程提供了一个堆管理器对对象分配进行细粒度化管理,32位程序的颗粒度位8Byete,64位程序则为16Byte。HEAP 开头有一块大小为 0x4a8 的 HEAP_ENTRY 堆块,用来存放 _HEAP 结构的元数据信息。
2024-09-07 22:58:26
664
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人