Other

MySQL三大日志、 MVCC、锁、分库分表、主从复制、优化

MySQL三大日志(binlog、redolog、undolog) 1、redo log(重做日志) 物理日志 (1)InnoDB存储引擎独有的,使MySQL崩溃后能恢复数据,保证数据的持久性和完整性 (2)一般情况下事务提交就会进行刷盘操作。 =刷盘策略:innodb_flush_log_at_trx_commit 0:每次事务提交时不进行刷盘操作 1:每次事务提交时都会进行刷盘操作(默认) 2:每次事务提交时都只会把redo log buffer内容写入文件系统缓存page cache (3)记录某个数据页上的修改操作 (4)事务执行过程中 不断写入 2、bin log(归档日志) 逻辑日志(二进制文件) (1)记录语句的原始逻辑,所有涉及更新数据的逻辑操作,顺序写 (2)属于MySQL Server层,保证数据库集群架构的数据一致性 (3)作用于 数据库数据备份、主备、主主、主从、集群 (4)事务提交时才写入 3、undo log(回滚日志) (1)异常发生时,对已经执行的操作进行回滚,保证事务的原子性 (2)回滚时,恢复机制是通过undo log实现的 (3)所有事务的操作会先记录到undo log,再执行相关操作 (4)undo log先于疏忽持久化到磁盘上,数据库宕机后再启动,数据库能通过查询回滚日志来回滚之前未完成的事务。 4、事务是基于redo log(持久化、原子性)和undo log(原子性、一致性)实现的 MVCC 多版本控制 1、一致性非锁定读 (1)实现:加版本号或时间戳,查询时比对版本号 (2)读取快照数据,读取记录时其它事务加锁排他锁时,也是可以直接读取的 2、锁定读 (1)语句 select ...... lock in share mode 对数据加读锁,其它事务也可以加读锁(共享锁),不能加写锁(排他锁) select ...... for update\insert\delete 对数据加写锁 (2)锁定读,读取的数据是最新版本的 3、多版本控制是对非锁定读的实现 MVCC (1)通过保存数据在某个时间点的快照来实现的。 (2)实现原理: innodb每行数据都有一个隐藏的回滚指针,用于指向该行修改前的最后一个历史版本(快照)存放在undo log中 (3)好处:读不加锁、读写不冲突,保证了事务的隔离性 (4)MVCC: 只在read committed 和repeatable read 中

shell-进阶1

[root@centos8 ~]# lscpu Architecture: x86_64 #架构 CPU op-mode(s): 32-bit, 64-bit #指令集 Byte Order: Little Endian CPU(s): 8 #核数 On-line CPU(s) list: 0-7 Thread(s) per core: 1 #每个core 有几个线程 Core(s) per socket: 4 #每个槽位有4个core Socket(s): 2 #服务器面板上有2个cpu 槽位 NUMA node(s): 2 #nodes的数量 反引号不能嵌套,$()可以嵌套使用 root@ubuntu2004:~# echo `date +%F`.txt 2022-04-15.txt root@ubuntu2004:~# ll `echo `date +%F`.txt` .txt: command not found ls: cannot access 'date': No such file or directory ls: cannot access '+%F': No such file or directory root@ubuntu2004:~# echo $(date +%F).

MYSQL --存储引擎的对比

主要介绍三种 InnoDB 、MyISAM 、Memory 一、InnoDB 介绍: InnoDB是一种兼顾高可靠性和高性能的通用存储引擎,在MySQL5.5之后默认的存储引擎 特点: DML操作遵循ACID模型,支持事务 行级锁,提高并发访问性能 支持外键FOREIGN KEY约束,保证数据的完整性和正确性 文件 xxx.ibd: xxx代表的是表名,innoDB引擎每张表都会对应一个这样的表空间文件,存储该表的表结构、数据和索引。该文件是基于二进制存储的,不能直接基于记事本打开,我们可以使用mysql提供的一个指令 ibd2sdi ,通过该指令就可以从ibd文件中提取sdi信息,而sdi数据字典信息中就包含该表的表结构。 逻辑存储结构 表空间 : InnoDB存储引擎逻辑结构的最高层,ibd文件其实就是表空间文件,在表空间中可以包含多个Segment段。 段 : 表空间是由各个段组成的, 常见的段有数据段、索引段、回滚段等。InnoDB中对于段的管理,都是引擎自身完成,不需要人为对其控制,一个段中包含多个区。 区 : 区是表空间的单元结构,每个区的大小为1M。 默认情况下, InnoDB存储引擎页大小为16K, 即一个区中一共有64个连续的页。 页 : 页是组成区的最小单元,页也是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。为了保证页的连续性,InnoDB 存储引擎每次从磁盘申请 4-5 个区。 行 : InnoDB 存储引擎是面向行的,也就是说数据是按行进行存放的,在每一行中除了定义表时所指定的字段以外,还包含两个隐藏字段(后面会详细介绍)。 二、MyISAM 介绍 MyISAM是MySQL早期的默认存储引擎。 特点: 不支持事务,不支持外键 支持表锁,不支持行级锁 访问速度快 文件 xxx.sdi:存储表结构信息 xxx.MYD: 存储数据 xxx.MYI: 存储索引 三、Memory 介绍 Memory引擎的表数据是存储在内存中的,由于受到硬件问题或断电问题的影响,只能将这些表作为临时表或缓存使用 特点 内存存放 hash索引(默认) 文件

3.Linux目录结构

        /bin:存放经常使用的命令。 /sbin:系统管理员使用的系统管理程序。 /home:存放普通用户的主目录。 /root:系统管理员的主目录 /lib:系统开机所需要的动态连接共享库。 /lost+found:系统非法关机时,会存放一些文件。  /etc:存放配置文件和子目录。 /usr:存放应用程序和文件。 /boot:存放Linux启动的核心文件。包括链接文件及镜像文件。 /proc:虚拟的目录。 /srv:存放服务启动后所需的数据 /tmp:存放临时文件。  /dev:硬件用文件形式存储 /media:自动识别设备 /mnt:让用户临时挂载别的文件系统 /opt:安装软件放置的目录  

redis/nginx/memcached等网络编程模型

网络编程四点 说到网络编程,就要把下面四个方面处理好。 第一是网络连接,来自客户端的连接,监听accept有收到EPOLLIN事件,或者当前服务器连接上游服务器,进行connect时返回-1,errno为EINPROGRESS,此时再收到EPOLLOUT事件就代表连接上了,因为三次握手最后是需要回复ack给上游服务器。 第二个方面是网络断开,当客户端断开时,服务端read返回0,或者收到EPOLLRDHUP事件,如果服务端要支持半关闭状态,就关闭读端shutdown(SHUT_RD),如果不需要支持,直接close即可,大部分都是直接close,一般close前也会进行类似释放资源的操作,如果这步操作比较耗时,可以异步处理,否则导致服务端出现大量的close_wait状态。如果是服务端主动断开连接时,通过shutdown(SHUT_WR)发送FIN包给客户端,此时再调用write会返回-1,errno为EPIPE,代表写通道已经关闭。这里要注意close和shutdown的区别,close时如果fd的引用不为0,是不会真正的释放资源的,比如fd1=dup(fd2),close(fd2)不会对fd1造成影响,而shutdown则跳过了前面的引用计数检查,直接对网络进行操作,多线程多进程下用close比较好。断开连接时,如果发现接收缓冲区还有数据,直接丢弃,并回复RST包,如果是发送缓冲区还有数据,则会取消nagle进行发送,末尾加上FIN包,如果开启了SO_LINGER,则会在linger_time内等待FIN包的ack,这样保证发送缓冲区的数据被对端接收到。 第三个是消息到达,如果read大于0,接收数据正常,处理对应的业务逻辑即可,如果read等于0,说明对端发送了FIN包,如果read小于0,此时要根据errno进行下一步的判断处理,如果是EWOULDBLOCK或者EAGAIN,说明接收缓冲区还没有数据,直接重试即可,如果是EINTR,说明被信号中断了,因为信号中断的优先级比系统调用高,此时也是重试read即可,如果是ETIMEDOUT,说明探活超时了,每个socket都有一个tcp_keepalive_timer,当超过tcp_keepalive_time没有进行数据交换时,开始发送探活包,如果探测失败,间隔tcp_keepalive_intvl时间发送下一次探活包,最多连续发送tcp_keepalive_probes次,如果都失败了,则关闭连接,返回ETIMEDOUT错误。这些探活都是在传输层进行的,如果应用层的进程有死锁或者阻塞,它是检测不到的,这种情况需要在应用层自行加入心跳包机制来进行检测。一般客户端与数据库之间,反向代理与服务器直接直接用探活机制就行,但数据库之间主从复制以及客户端与服务器之间需要加入心跳机制,以防进程有阻塞。 第四个是消息发送,write大于0,消息放入了发送缓冲区,write小于0,同样要分errno的情况处理,如果错误码为EWOULDBLOCK,说明发送缓冲区还装不下你要发送的数据,需要重试,如果是EINTR,说明write系统调用被信号中断了,同样进行重试处理,如果是EPIPE,说明写通道已经关闭了。 udp读写 这里的读写数据部分和udp有个不同的地方,udp不能发送比MSS还大的数据,超过则发送不出去,最大MSS为MTU-20-8=1500-28=1472,20为ip包的头部,8为udp报文的头部,有的数据还会加入pppoe字段区分不同的运营商,所以MSS最大使用1400比较保险。另外udp接收时,需要接收比MSS大的数据量,否则没接完的数据会丢失。而tcp由于是流式协议,数据不一定是整体到达的,比如3000字节的数据,先到100字节,到了就可以进行recv,可以分多次recv,所以tcp有粘包问题。 常见网络io模型 网络io模型主要分这么几种,阻塞io,非阻塞io,信号驱动io,io多路复用,异步io,其中阻塞io和非阻塞io指的是内核数据准备阶段要不要阻塞等待,如果内核数据准备好了,将数据从内核拷贝至用户空间还是阻塞的,所以它们都为同步io,信号驱动io是内核数据准备好后,通过信号中断的方式来告诉用户空间,比如SIGIO,但也是需要用户主动调用系统调用函数将数据从内核空间拷贝至用户空间的,异步io就不需要用户态去调用系统调用函数将数据从内核态拷贝至用户态了,它是内核自己去把准备好的数据拷贝到用户态,然后通知用户态。目前使用最多的是io多路复用,有select/poll/epoll这些系统调用,可以监听多个io的状态,有事件时系统调用返回,再调用同步io去读取数据即可,当然我们也可以while循环调用同步io轮询看数据有没有准备好,但这样使得cpu一直空转,消耗高。 redis网络模型 目前大部分高性能网络中间件都是采用io多路复用加事件处理的机制,也就是reactor模型,redis是单reactor模型,只有一个epoll对象,主线程就是一个循环,不断的处理epoll事件,首先处理accept事件,将接入的连接绑定读事件处理函数后加入epoll中,等epoll检测到连接有读事件到来时,触发读事件处理函数,但这个函数并没有真正的去读数据,而是将该有读事件到来的连接放入clients_pending_read任务队列中,主线程循环到下一次epoll_wait前,再将这些任务队列中的连接分配给各个io线程本地的任务队列io_threads_list处理,在io线程里,不断对io_threads_pending[i]原子变量进行判断,看有没有值,有就代表主线程给派了任务,然后根据io_threads_op任务类型对任务进行读或写处理,先说读处理部分,主要读取客户端数据并进行解析命令处理,将命令读到该连接对应的querybuf中,主线程忙轮询,等待所有io线程解析命令完成,再主线程开始执行命令,因为这些都是内存操作,所以单线程就可以,如果用多线程的话还有锁的问题,执行完命令后将相应结果写入连接对应的buf数组中,如果放不下就放入reply链表中,然后再将各个连接的响应客户端的任务放入clients_pending_write任务队列中,主线程再分配给各个io线程进行写处理,将数据响应给客户端,主线程此时也是忙轮询,等待所有io线程完成,如果最后发现还有数据没发送完,就注册epollout写事件sendReplyToClient,等客户端可写时再把数据发送完。可以看出网络io相关的操作使用了多线程处理,但是命令执行等纯内存操作都是单线程完成的,全程只有一个eventLoop即相当于epollfd,这种就是单reactor模型,每个io线程都有自己的任务队列io_threads_list,所以也没有多线程竞争的问题。 nginx网络模型 nginx采用的是单reactor多进程模型,因为每个连接都是处理的无状态数据,故可以通过多进程实现,多进程之间共享epollfd,在内核2.6以前,accept还存在惊群问题,即如果有连接到来,多个进程的epoll_wait都能监测到,这样多个进程都处理了该相同的连接,这是有问题的,所以nginx采用了文件锁的方式,在ngx_process_events_and_timers函数中可以看出,哪个进程先获得了这把锁ngx-accept_mutex,就开始监听EPOLLIN事件,并进行epoll_wait接收对应的事件,接收到的事件先不处理,先放入一个队列中,如果是accept事件,就放入accept对应的ngx_posted_accept_events队列中,其它事件放入另外一个ngx_posted_events队列,然后再处理accept队列的事件回调函数,到这里才能释放文件锁,再去处理非accept队列里面的事件回调函数handler。可以看出nginx其实也是只有一个epollfd,只是被多个进程共享了,这样多个进程可以并行处理事件。 memcached网络模型 memcached是基于libevent来实现网络模型的,它是多线程多reactor模型,相比前面两种,它是有多个reactot模型的,也就是说有多个epoll进行事件循环,它也是将网络接入和网络读写io单独分离的方式,主线程主要处理网络的接入,主要看server_sockets函数,有accept事件后会调用event_handler回调函数,该事件是通过调用conn_new函数注册在主线程的event_base类型变量main_base上,所以主线程陷入事件循环后会监听accept事件。该event_handler回调函数里面做的事情就是调用drive_machine,看这个名字就知道是个状态机处理,所以accept事件来时就处理conn_listening下的事情,主要是进行accept得到客户端的sfd,然后通过round_robin算法选择一个工作线程,将该fd信息打包成CQ_ITEM放在工作线程的连接事件队列ev_queue中,最后通过pipe通知那个工作队列有连接事件过来了,其实就是往pipe中发一个c字符,工作线程此时处理事件回调thread_libevent_process,该回调主要是从连接事件队列ev_queue中取出主线程传过来的那个item,再调用conn_new处理该item,conn_new之前主线程也是调用的这个,主要是用来绑定fd的读写事件到event_base上去,工作线程则绑定到该线程对应的那个event_base上,这个event_base对应一个epoll,所以memcached是有多个epoll,因为每个工作线程都有自己的event_base,绑定完后,后续的读写事件回调也是event_handler函数,里面再调用drive_machine函数,只是连接的状态变成了conn_read和conn_write,这就是状态机的好处,代码逻辑很清晰。总的来说,主线程处理accept,工作线程处理后续的通信read和write,思路很清晰。 以上是对网络模型原理的一些介绍,并结合实际开源代码进行剖析,建议自己多看源码,结合别人的思路看我,很快就能梳理清楚,也对网络模型有了更加深刻的理解。 本文作者: nephen 本文链接: https://www.nephen.cn/posts/ef7ede25/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!

使用PowerShell下载文件

更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月12日。 使用Invoke-WebRequest指令下载文件 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri https://xxx.zip -OutFile F:/xx.zip Unblock-File $des 第一条指令是避免出现协议版本问题。第二条指令用于下载文件。第三条指令用于解锁文件。 老版本的PowerShell使用以下指令下载文件 $WebClient = New-Object System.Net.WebClient $WebClient.DownloadFile(https://www.panda666.com/file,F:\panda.zip); 本质是使用.NET框架的WebClient类型实例进行下载文件。

使用PowerShell压缩和解压ZIP包

更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月13日。 解压ZIP包 使用PowerShell的Expand-Archive命令。PowerShell官方文档地址。 命令格式: Expand-Archive -Path -DestinationPath -Confirm 解压压缩包 Expand-Archive -Path .\panda.Zip -DestinationPath F:\dd -Confirm 压缩ZIP包 使用PowerShell的Compress-Archive命令。PowerShell官方文档地址。 命令格式: Compress-Archive -Path -DestinationPath -Confirm 实例:压缩多个文件 $compress = @{ Path = C:\Reference\Draftdoc.docx, C:\Reference\Images\*.vsd CompressionLevel = Fastest DestinationPath = C:\Archives\Draft.Zip } Compress-Archive @compress 实例:压缩文件 Compress-Archive -Path ‪E:\test.txt -DestinationPath F:\panda.zip -Confirm 实例:压缩目录 Compress-Archive -Path E:\新建文件夹\ -DestinationPath F:\panda.zip -Confirm 实例:压缩目录(不包含根目录) Compress-Archive -Path E:\新建文件夹\* -DestinationPath F:\pan.zip -Confirm 实例:压缩目录(只包含根目录的文件)

使用PowerShell校验文件MD5

更新记录 2022年4月16日:本文迁移自Panda666原博客,原发布时间:2021年7月14日。 方法1:使用Get-FileHash命令 (Get-FileHash .\SQLServer.iso -Algorithm MD5).Hash‪ 这个命令就像其描述的那样获得文件的哈希值,都不需要去记忆,直接理解了就可以拼写出来,太方便了。这个命令支持多种算法,比如:SHA1、SHA256、SHA384、SHA512、MD5关于命令的更多信息可以看微软PowerShell官方文档。 方法2:使用certutil命令 certutil -hashfile .\SQLServer2019.iso MD5 第一眼看到这命令,怎么都没想到怎么会和计算哈希想到一块。官方文档的说明是:【Certutil.exe 是命令行程序,作为证书服务的一部分进行安装。 你可以使用 certutil.exe 来转储和显示证书颁发机构 (CA) 配置信息、配置证书服务、备份和还原 CA 组件以及验证证书、密钥对和证书链】。但我实验了一下确实可以计算问的MD5值,作为上一种方法的备选方案吧,优先肯定还是考虑上一种方法,毕竟可读性又好,而且还是面向对象的。

9.Redis数据库部署和操作

Redis 介绍 NoSQL类型数据库之一,内存运行,效率极高,支持分布式,理论上可以无限拓展数据库,支持各种语言的API,可安装在各种平台 关系型数据库:MySQL、SQLServer、Oracle 非关系型数据库:NoSQL、Redis(key-value) 特点: c/s通信模式(Client and Server) 单进程单线程(list、set、hash……) 支持很多数据类型 高并发读写 支持lua脚本 支持数据持久化(内存数据保存在硬盘) 支持数据备份 读写极快(每秒11w次读,8w1k次写) 原子性操作,要么成功要么失败,即要么全做要么全不做,不会像MySQL做到一半报个错 部署与操作 部署 在phpstudy的软件管理中下载Redis服务端和客户端,在客户端中添加服务端Host,即127.0.0.1,默认6379端口 在phpstudy的Extensions中打开Redis服务端,可以看到其中的命令文件,在其中使用cmd进行操作 # 连接数据库 本机:redis-cli -h 127.0.0.1 远程:redis-cli -h [远程数据库的地址] -p 6379 # 选择哪个数据库 select [数字] # 退出 quit 如果要让别人远程连接,除了防火墙端口放行,还要绑定IP 数据库操作 key-value:键值对,键不能重复 # 清空所有数据(基本设置值) flushall # 添加键值对 set name1 yingge1 # 获得数据 get name1 # 设置5s后失效的键值对 set name2 yingge2 EX 5 setex name2 5 yingge2 # 获得生命周期 ttl name2 # 同时设置多个键值对 mset key1 value11 key2 value22 # 同时获得多个键值对 mget key1 key2 # 在name1(键)的值后面增加zj11(拼接效果) append name1 zj11 键命令 keys [正则表达式]