- 博客(171)
- 收藏
- 关注
原创 go routine 并发和同步
sync.WaitGroup 是 Go 语言中的一个并发原语,用于等待一组协程(goroutine)完成。在使用多个协程时,WaitGroup 可以帮助你确保所有协程都执行完毕后再继续执行主程序。sync.Cond 是 Go 语言中的一个同步原语,用于在 goroutine 之间协调执行顺序。sync.Mutex 是 Go 语言中的一种互斥锁,用于在多协程环境中保护共享资源,防止数据竞争。errgroup 是 Go 语言标准库中的一个包,提供了一种方便的方式来管理一组并发任务,并收集它们中的第一个错误。
2025-03-03 17:02:02
542
原创 MySQL 主从复制原理
MySQL 的主从复制是一种常见的数据复制机制,用于在多个 MySQL 数据库服务器之间同步数据。主从复制的基本原理是将一个主服务器(Master)上的数据更改复制到一个或多个从服务器(Slave)上。
2025-02-19 18:23:36
853
原创 基于规则的优化(内含子查询优化二三事)
MySQL本质上是一个软件,设计MySQL的大佬并不能要求使用这个软件的人个个都是数据库高高手,就像我写这本书的时候并不能要求各位在学之前就会了里边儿的知识。也就是说我们无法避免某些同学写一些执行起来十分耗费性能的语句。即使是这样,设计MySQL的大佬还是依据一些规则,竭尽全力的把这个很糟糕的语句转换成某种可以比较高效执行的形式,这个过程也可以被称作查询重写(就是人家觉得你写的语句不好,自己再重写一遍)。本章详细介绍一下一些比较重要的重写规则。
2024-12-01 16:20:08
684
原创 兵马未动,粮草先行-InnoDB统计数据是如何收集的
我们前面介绍查询成本的时候经常用到一些统计数据,比如通过SHOW TABLE STATUS可以看到关于表的统计数据,通过SHOW INDEX可以看到关于索引的统计数据,那么这些统计数据是怎么来的呢?它们是以什么方式收集的呢?本章将聚焦于InnoDB存储引擎的统计数据收集策略。设计MySQL的大佬们给我们提供了系统变量innodb_stats_persistent来控制到底采用哪种方式去存储统计数据。
2024-11-09 18:39:12
865
原创 grpc 快速入门
gRPC 是一个现代的远程过程调用(RPC)框架,由 Google 开发。它使用 HTTP/2 作为传输协议,并采用 Protocol Buffers(protobuf)作为接口描述语言(IDL)。gRPC 提供高效的通信、语言无关性和跨平台支持,非常适合构建分布式系统。
2024-10-31 14:14:55
462
原创 谁便宜就选谁---基于成本的优化,good sql
我们之前老说MySQL执行一个查询可以有不同的执行方案,它会选择其中成本最低,或者说代价最低的那种方案去真正的执行查询。对于InnoDB存储引擎来说,页是磁盘和内存之间交互的基本单位,设计MySQL的大佬规定读取一个页面花费的成本默认是1.0,读取以及检测一条记录是否符合搜索条件的成本默认是0.2。1.0、0.2这些数字称之为成本常数,这两个成本常数我们最常用到,其余的成本常数我们后边再说。
2024-09-01 12:31:11
944
原创 InnoDB 表空间2---系统表空间
了解完了独立表空间的基本结构,系统表空间的结构也就好理解多了,系统表空间的结构和独立表空间基本类似,只不过由于整个MySQL进程只有一个系统表空间,在系统表空间中会额外记录一些有关整个系统信息的页,所以会比独立表空间多出一些记录这些信息的页。因为这个系统表空间最牛逼,相当于是表空间之首,所以它的表空间 ID(Space ID)是0。
2024-06-30 16:52:49
952
原创 InnoDB 表空间1---独立表空间
表空间是一个抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于每个独立表空间来说,对应着文件系统中一个名为表名.ibd的实际文件。大家可以把表空间想象成被切分为许许多多个页的池子,当我们想为某个表插入一条记录的时候,就从池子中捞出一个对应的页来把数据写进去。
2024-06-30 15:46:58
803
原创 Java builder 和 new 创建对象时默认值处理方式不一样
【代码】Java builder 和 new 创建对象时默认值处理方式不一样。
2024-06-07 18:53:12
229
1
原创 InnoDB B+树索引
在一个页中的查找在很多页中查找大部分情况下我们表中存放的记录都是非常多的,需要好多的数据页来存储这些记录。在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,在每一个页中根据我们刚刚介绍过的查找方式去查找指定的记录。因为要遍历所有的数据页,所以这种方式显然是超级耗时的,如果一个表有一亿条记录,使用这种方式去查找记录那要等到猴年马月才能等到查找结果。
2024-03-17 13:15:42
821
原创 InnoDB数据页结构---页目录 PageDirectory
InnoDB为了不同的目的而设计了许多种不同类型的页,比如存放表空间头部信息的页,存放Insert Buffer信息的页,存放INODE信息的页,存放undo日志信息的页等等等等。本文聚焦的是那些存放我们表中记录的那种类型的页,官方称这种存放记录的页为索引(INDEX)页,鉴于我们还没有了解过索引是个什么东西,而这些表中的记录就是我们日常口中所称的数据,所以目前还是叫这种吧。
2024-03-12 20:27:12
1153
原创 InnoDB记录结构
InnoDB是一个将表中的数据存储到磁盘上的存储引擎,所以即使关机后重启我们的数据还是存在的。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内存中的内容刷新到磁盘上。而我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级,所以当我们想从表中获取某些记录时,InnoDB存储引擎需要一条一条的把记录从磁盘上读出来么?
2024-03-12 13:58:09
446
原创 MySQL BufferPool精讲
我们知道,对于使用InnoDB作为存储引擎的表来说,不管是用于存储用户数据的索引(包括聚簇索引和二级索引),还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只不过是InnoDB对文件系统上一个或几个实际文件的抽象,也就是说我们的数据说到底还是存储在磁盘上的。但是各位也都知道,磁盘的速度慢的跟乌龟一样,怎么能配得上“快如风,疾如电”的CPU呢?所以InnoDB存储引擎在处理客户端的请求时,当需要访问某个页的数据时,就会把完整的页的数据全部加载到内存中,。
2024-01-07 16:25:25
1150
原创 MySQL MVCC精讲
以此类推,如果之后事务id为200的记录也提交了,再此在使用READ COMMITTED隔离级别的事务中查询表hero中number值为1的记录时,得到的结果就是’诸葛亮’了,具体流程我们就不分析了。随着系统的运行,在确定系统中包含最早产生的那个ReadView的事务不会再访问某些update undo日志以及被打了删除标记的记录后,有一个后台运行的purge线程会把它们真正的删除掉。隔离级别的事务来说,由于可以读到未提交事务修改过的记录,所以直接读取记录的最新版本就好了;
2023-12-26 14:34:54
1163
原创 MySQL undo日志精讲3-从回滚段中申请 Undo 页面链表
如果该属性的值为 TRXUNDO ACTIVE,则意味着有一个活跃的事务正在向这个 Undo 页面链表中写入 undo 日志,然后再在 Undo Segment Header 中找到 TRX UNDO LAST LOG 属性,通过该属性可以找到本Undo 页面链表最后一个 Undo Log Header 的位置。我们现在知道一个事务在执行过程中最多可以分配4个 Undo 页面链表,在同一时刻不同事务拥有的 Undo 页面链表是不一样的,所以在同一时刻系统里其实可以有许许多多个 Undo 页面链表存在。
2023-12-24 12:08:23
1128
原创 MySQL undo日志精讲2-undo日志写入
设计InnoDB的大佬认为同一个事务向一个Undo页面链表中写入的undo日志算是一个组,比方说我们上面介绍的trx 1由于会分配3个Undo页面链表,也就会写入3个组的undo日志;但是我们前面又强调过,同一个Undo页面要么只存储TRX_UNDO_INSERT大类的undo日志,要么只存储TRX_UNDO_UPDATE大类的undo日志,反正不能混着存,所以在一个事务执行过程中就可能需要2个Undo页面的链表,一个称之为insert undo链表,另一个称之为update undo链表;
2023-12-22 13:41:30
1006
原创 MySQL undo日志精讲1-undo日志类型
我们说过事务需要保证原子性,也就是事务中的操作要么全部完成,要么什么也不做。这两种情况都会导致事务执行到一半就结束,但是事务执行过程中可能已经修改了很多东西,为了保证事务的原子性,我们需要把东西改回原先的样子,这个过程就称之为回滚(英文名:rollback),这样就可以造成一个假象:这个事务看起来什么都没做,所以符合原子性要求。从上面的描述中我们已经能隐约感觉到,每当我们要对一条记录做改动时(这里的改动可以指INSERT、DELETE、UPDATE),都需要留一手 —— 把回滚时所需的东西都给记下来。
2023-12-17 12:46:13
464
原创 NFR 数字权益开发流程
NFR 在技术开发领域通常指的是“非功能性需求”(Non-Functional Requirements),这些是描述系统属性如安全性、性能、可用性、兼容性等方面的需求。
2023-12-11 11:33:29
802
1
原创 MySQL redo 日志精讲
有一个很不幸的事实就是我们的redo日志文件组容量是有限的,我们不得不选择循环使用redo日志文件组中的文件,但是这会造成最后写的redo日志与最开始写的redo日志追尾,这时应该想到:redo日志只是为了系统奔溃后恢复脏页用的,如果对应的脏页已经刷新到了磁盘,也就是说即使现在系统奔溃,那么在重启后也用不着使用redo日志恢复该页面了,所以该redo日志也就没有存在的必要了,那么它占用的磁盘空间就可以被后续的redo日志所重用。自系统开始运行,就不断的在修改页面,也就意味着会不断的生成redo日志。
2023-11-05 16:24:43
260
1
原创 MySQL Server层的 max_connections 和引擎层的 innodb_thread_concurrency
max_connections 和 innodb_thread_concurrency
2023-09-16 18:52:00
417
原创 MySQL的 timze_zone 和 SpringBoot 的 serverTimezone 的设置
serverTimeZone的作用就是指定web服务器和mysql服务器的会话期间的mysql服务器时区,就是临时指定mysql服务器的时区。同理 golang 也有类似配置。// 在给创建时间赋值时,会把服务器所在时区的时间转换为 UTC 时间保存;// 而在获取数据时会把数据库里的创建时间当成 UTC 时区的,然后转换为 bean.DbEngine.TZLocation 时区的时间。
2023-06-15 14:43:17
2461
3
原创 制作 MySQL 镜像的 dockerfile以及 ENTRYPOINT 和 CMD 的区别
【代码】制作 MySQL 镜像的 dockerfile以及 ENTRYPOINT 和 CMD 的区别。
2023-03-29 18:57:13
180
转载 GPG 使用指南:包括对称加密和非对称加密
加密与签名在传输信息时,会面临两个典型的问题:这两个问题不难理解。例如发送的邮件可能会被监听,诈骗分子可以冒充你老板。不一定是在网络上,在任何非面对面交流的情况下,都可能存在这两个问题。例如打仗时,情报可能被敌方监听窃取,收到的命令可能是被敌人冒充的。对于第一个问题,可以通过加密来解决。就像战争电影中,双方会加密自己的情报和破解对方的情报。那么如何进行加密呢?最容易想到的方法就是双方约定一套规则(加密算法),发送方将原始信息(明文)按照这套规则转换(加密)成别人看不懂的信息(密文)。其他人不知道这套规则,
2023-01-30 14:33:45
1258
转载 @RestControllerAdvice注解;有点架构的感觉了
@RestControllerAdvice注解在做前后端分离的项目时,后端业务通常会使用多个微服务,我们希望在每一个微服务的调用接口返回给前端的结果都是统一的数据结构,如:在上面的结构中,有请求是否成功标识-successful,其值为boolean类型;有服务处理结果编码-code,其值为String,可以封装自定义编码,也可以使用HttpStatus;有服务处理结果文本信息message;还有业务返回数据-data,其值类型为Object,即可以返回String、List、对象信息等等。定义统一的返回
2022-12-07 12:13:59
776
原创 mysql SQL 集锦:join_and 和 多次join同一张表的处理 和 group_concat 和 find_in_set
2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉,on后的条件用来生成左右表关联的临时表,where后的条件对临时表中的记录进行过滤。1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
2022-11-02 18:16:30
2292
原创 Python 装饰器精讲
于是调用 businessA() 将执行新函数,即在 my_decorator()函数中返回的wrapper()函数。wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。所以,原来的 businessA()函数仍然存在,只是现在同名的 businessA 变量指向了新的函数,如果函数的参数定义是(*args, **kw),表示该函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。
2022-10-13 17:21:12
325
转载 浅谈select-epoll
综上:一次普通网络IO操作需要4次状态切换以及4次数据拷贝。以上只是操作系统底层流程,至于具体代码(欢迎去看linux源码)。我们编写的应用程序在进行IO的操作时,系统调用read() 和 write()。今天的话题还是得从最开始的IO开始。内核缓冲区和进程缓冲区(用户态缓冲区)。1.阻塞性IO(BIO,NIO).用户态和内核态切换。
2022-09-26 11:44:03
242
转载 select和epoll
之所以能够同时处理多个客户端的请求,原因是可以查询哪个客户端准备好了,对于准备好的客户端(例如客户端已经发了信息过来,本服务器用read读取数据的时候不会阻塞;另外,客户端已经关闭了连接,那么本服务read的时候,返回0,也不会阻塞),则和它进行通信,而未准备好的,就暂时先不理会。select是对加进去的所有fd进行轮询,返回之后也要对整个fd进行一次轮询,才能找到准备好的fd。epoll采用事件触发的方式,当某个fd准备好后会触发事件,这样减少了内核的轮询。现今用的多的是epoll。
2022-09-26 11:39:01
212
原创 4-Linux 进程组的精确理解和 Daemon进程
为了验证 if you log into a machine, your shell starts a session from: https://blog.youkuaiyun.com/cpxsxn/article/details/107371177。为了验证 os.setsid();executor.py 主体就是一个真正的 daemon 进程。shell 进程: http://c.biancheng.net/view/739.html。为了验证:父子进程是一个进程组,但是子进程不是进程组组长。
2022-09-23 12:07:29
518
转载 TCP粘包问题以及解决方法
这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。可以将真实数据,做成一个固定长度的报头,客户端发送给服务端,服务端可以接受报头,然后对报头进行解包,获取真实数据的长度,进行接收即可。TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
2022-09-19 15:26:27
3834
原创 ES 基本操作
term 查询:用来查找指定字段中包含给定单词的文档,term 查询不被解析,只有查询词和文档中的词精确匹配才会被搜索到,应用场景为查询人名、地名等需要精准匹配的需求。match 查询:用于搜索单个字段,首先会针对查询语句进行解析(经过 analyzer),主要是对查询语句进行分词,分词后查询语句的任何一个词项被匹配,文档就会被搜到,a.分词后所有词项都要出现在该字段中(相当于 and 操作)。如果想查询匹配所有关键词的文档,可以用 and 操作符连接。b.字段中的词项顺序要一致。
2022-09-18 10:22:20
554
转载 解决Django的request.POST获取不到内容的问题
在服务器端我用request.POST期望能获取到,但是我发现获取到的是一个空的,用reqyest.body是能获取到原始的请求内容key2=value2&key1=value1的。
2022-09-11 10:16:07
1799
转载 python setup.py 打包发布
平常我们习惯了使用pip来安装一些第三方模块,这个安装过程之所以简单,是因为模块开发者为我们默默地为我们做了所有繁杂的工作,而这个过程就是打包。打包,就是将你的源代码进一步封装,并且将所有的项目部署工作都事先安排好,这样使用者拿到后即装即用,不用再操心如何部署的问题(如果你不想对照着一堆部署文档手工操作的话)。不管你是在工作中,还是业余准备自己写一个可以上传到PyPI的项目,你都要学会如何打包你的项目。Python发展了这么些年了,项目打包工具也已经很成熟了。他们都有哪些呢?............
2022-07-31 13:15:09
1136
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人