1.MySQL实战45讲.md

分享海报

01 | 基础架构在: 一条SQL查询语句是如何执行的?

MYSQL执行过程

02 | 日志系统:一条SQL更新语句是如何执行的?

  1. redo log 是InnoDB 引擎特有的;binlog 是MySQL server层使用的,所有存储引擎都可以使用。
  2. redo log 是物理日志,记录了是“某个记录做了什么修改” ,binlog是逻辑日志,记录的是sql语句。
  3. redo log 是循环写的,空间固定会用完,binlog是append的,文件写到一定大小会重新新起一个文件再写。

03 | 事务隔离:为什么你改了我还看不见?

SQL标准的事务隔离级别包括:

  • 读未提交(read uncommitted)
  • 读提交(read committed)
  • 可重复读(repeatable read)
  • 串行化(serializable)

读未提交是指,一个事务还没提交时,它做的变更可以被其他事务看到。
读已提交是指,一个事务提交之后,它做的变更可以被其他事务看到。
可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
串行化,顾名思义是对于同一行记录,“写”会加写锁,“读”会加读锁。当出现读写锁冲突的时候,后一个事务需要等前一个事务提交才能执行。

长事务怎么处理

  • 应用端:set autocommit=0,减少读事务, set max_execution_time 设置语句执行最长时间。
  • 数据库端:
    • 监控information_schema.innodb_trx 表,报警或kill;
    • pt-kill这个工具。
    • 输出general_log,提前分析日志发现问题
    • 设置innodb_undo_tablespaces 设置为2。

04 | 深入浅出索引(上)

在MySQL中,MyISAM采用的是非聚簇索引的,InnoDB存储引擎是采用聚簇索引的。

聚簇结构的特点:

  • 根据主键查询条目时,不用回行(数据就在主键节点下)
  • 如果碰到不规则数据插入时,造成频繁的页分裂

非主键索引需要回表,尽量用主键查询
InnoDB的页大小默认是16K,多个大字段的确会引起更多的页分页,较小的varchar字段,16K一页就能放上千条,差别自然不会太大。

05 | 深入浅出索引(下)

覆盖索引

  • 索引覆盖了查询需求
  • 减少树的搜索次数,常用的性能优化手段

最左前缀原则

  • 第一个原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
  • 第二个原则是,考虑空间的因素,比如name,age,可以(name,age)建个索引,age建个索引。name占用的空间要远大于age。

索引下推

联合索引,满足条件就不需要多回表一次。
select name,age from table where name = '张三' and age =10
上面语句建立了联合索引(name,age)

06 | 全局锁和表锁 :给表加个字段怎么有这么多阻碍?


2.Linux性能优化实战.md


3.趣谈Linux操作系统.md

15 | 调度(上):如何制定项目管理流程

优先级:

实时:0~99

普通: 100~139

实时调度策略:SCHED_FIFO,SCHED_RR,SCHED_DEADLINE

普通调度策略: SCHED_NORMAL,SCHED_BATCH,SCHED_IDLE,SCHED_OTHER

sched_class:

stop_sched_class, dl_sched_class, rt_sched_class, fair_sched_class, idle_sched_class

完全公平调度算法

CFS : Completely Fair Scheduling

虚拟运行时间:

虚拟运行时间 vruntime += 实际运行时间 delta_exec * NICE_0_LOAD / 权重

架构图

实战

查看当前进程的调度策略

用chrt命令可以方便的修改进程的调度策略和优先级

chrt -p pid

16 | 调度(中):主动调度是如何发生的?

计算机主要处理计算、网络、存储三个方面。计算主要是 CPU 和内存的合作;网络和存储则多是和外部设备的合作;在操作外部设备的时候,往往需要让出 CPU,就像上面两段代码一样,选择调用 schedule() 函数。

进程上下文切换上下文切换主要干两件事情,

一是切换进程空间,也即虚拟内存;

二是切换寄存器和 CPU 上下文。

1、32位,ESP(Extended Stack Pointer)为扩展栈指针寄存器,是指针寄存器的一种,用于存放函数栈顶指针。 与之对应的是EBP(Extended Base Pointer),扩展基址指针寄存器,也被称为帧指针寄存器,用于存放函数栈底指针。

2、64位,RSP 是堆栈指针寄存器,通常会指向栈顶位置,堆栈的 pop 和push 操作就是通过改变 %rsp 的值即移动堆栈指针的位置来实现的

寄存器详解

在 x86 体系结构中,提供了一种以硬件的方式进行进程切换的模式,对于每个进程,x86 希望在内存里面维护一个 TSS(Task State Segment,任务状态段)结构。这里面有所有的寄存器。另外,还有一个特殊的寄存器 TR(Task Register,任务寄存器),指向某个进程的 TSS。更改 TR 的值,将会触发硬件保存 CPU 所有寄存器的值到当前进程的 TSS 中,然后从新进程的 TSS 中读出所有寄存器值,加载到 CPU 对应的寄存器中。

进程调度第一定律

寄存器详解

实战

mpstat、vmstat、pidstat 和 /proc/interrupts可以查看进程的上下文切换。

上下文切换: pidstat -p 9992 -w -I 1 10

查看内存和cpu: vmstat -S M

寄存器详解

17 | 调度(下):抢占式调度是如何发生的?

调度过程

18 | 进程的创建:如何发起一个新项目?

fork 系统调用的过程咱们就解析完了。它包含两个重要的事件,一个是将 task_struct 结构复制一份并且初始化,另一个是试图唤醒新创建的子进程。

19 | 线程的创建:如何执行一个新子项目?

创建进程的话,调用的系统调用是 fork,在 copy_process 函数里面,会将五大结构 files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都复制一遍,从此父进程和子进程各用各的数据结构。而创建线程的话,调用的是系统调用 clone,在 copy_process 函数里面, 五大结构仅仅是引用计数加一,也即线程共享进程的数据结构。

实战

pstree -apl pid看进程树

pstack pid 看栈

20 | 内存管理(上):为客户保密,规划进程内存空间布局

内存管理系统至少应该做三件事情:

第一,虚拟内存空间的管理,每个进程看到的是独立的、互不干扰的虚拟地址空间;

第二,物理内存的管理,物理内存地址只有内存管理模块能够使用;

第三,内存映射,需要将虚拟内存和物理内存映射、关联起来。

实战

1、查看内存映射

pmap 25992

cat /proc/25992/maps

21 | 内存管理(下):为客户保密,项目组独享会议室封闭开发

分段可以配置权限
分页占用内存小, 而且可以换入换出

如果在系统中使用了huge page,则内存页的数量会减少,从而需要更少的页表(page table),节约了页表所占用的内存数量,并且所需的地址转换也减少了,TLB缓存失效的次数就减少了,从而提高了内存访问的性能。

如果在客户机中运行的应用程序(典型的应用为oracle数据库)具备使用huge page的能力,那么就可以在客户机中使用huge page带来性能的提升。

总的来说,对于内存访问密集型的应用,在KVM客户机中使用huge page是可以较明显地提高客户机性能的,不过,它也有一个缺点,使用huge page的内存不能被换出(swap out),也不能使用ballooning方式自动增长。

22 | 进程空间管理:项目组还可以自行布置会议室

linux内部结构
slab 分配器
什么是物理/虚拟/共享内存——Linux内存管理小结一

23 | 物理内存管理(上):会议室管理员如何分配会议室?

如果有多个 CPU,那就有多个节点。每个节点用 struct pglist_data 表示,放在一个数组里面。

每个节点分为多个区域,每个区域用 struct zone 表示,也放在一个数组里面。每个区域分为多个页。

为了方便分配,空闲页放在 struct free_area 里面,使用伙伴系统进行管理和分配,每一页用 struct page 表示。

24 | 物理内存管理(下):会议室管理员如何分配会议室?

对于物理内存来讲,从下层到上层的关系及分配模式如下:

物理内存分 NUMA 节点,分别进行管理;

每个 NUMA 节点分成多个内存区域;

每个内存区域分成多个物理页面;

伙伴系统将多个连续的页面作为一个大的内存块分配给上层;

kswapd 负责物理页面的换入换出;

Slub Allocator 将从伙伴系统申请的大内存块切成小块,分配给其他系统。

config swap

cat /proc/sys/vm/swappiness

60
该值默认值是60.

swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,

swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。

如何查看swap分区

swapon -s
cat /proc/swaps
free
vmstat
以上4类命令都可以查看swap分区的大小和使用情况


 如何修改swappiness参数?

--临时性修改:

[root@rhce ~]# sysctl vm.swappiness=10

vm.swappiness = 10

[root@rhce ~]# cat /proc/sys/vm/swappiness
10
这里我们的修改已经生效,但是如果我们重启了系统,又会变成60.

--永久修改:
在/etc/sysctl.conf 文件里添加如下参数:
vm.swappiness=10
或者:
[root@rhce ~]# echo 'vm.swappiness=10' >>/etc/sysctl.conf

保存,重启,就生效了。

25 | 用户态内存映射:如何找到正确的会议室?

用户态的内存映射机制包含以下几个部分。

用户态内存映射函数 mmap,包括用它来做匿名映射和文件映射。

用户态的页表结构,存储位置在 mm_struct 中。

在用户态访问没有映射的内存会引发缺页异常,分配物理页表、补齐页表。如果是匿名映射则分配物理内存;如果是 swap,则将 swap 文件读入;如果是文件映射,则将文件读入。

brk是什么

mmap


Copyright © 2018 INSTALL.REN