SQL标准的事务隔离级别包括:
读未提交是指,一个事务还没提交时,它做的变更可以被其他事务看到。
读已提交是指,一个事务提交之后,它做的变更可以被其他事务看到。
可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
串行化,顾名思义是对于同一行记录,“写”会加写锁,“读”会加读锁。当出现读写锁冲突的时候,后一个事务需要等前一个事务提交才能执行。
长事务怎么处理
在MySQL中,MyISAM采用的是非聚簇索引的,InnoDB存储引擎是采用聚簇索引的。
聚簇结构的特点:
非主键索引需要回表,尽量用主键查询
InnoDB的页大小默认是16K,多个大字段的确会引起更多的页分页,较小的varchar字段,16K一页就能放上千条,差别自然不会太大。
覆盖索引
最左前缀原则
索引下推
联合索引,满足条件就不需要多回表一次。
select name,age from table where name = '张三' and age =10
上面语句建立了联合索引(name,age)
优先级:
实时: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
计算机主要处理计算、网络、存储三个方面。计算主要是 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
fork 系统调用的过程咱们就解析完了。它包含两个重要的事件,一个是将 task_struct 结构复制一份并且初始化,另一个是试图唤醒新创建的子进程。
创建进程的话,调用的系统调用是 fork,在 copy_process 函数里面,会将五大结构 files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都复制一遍,从此父进程和子进程各用各的数据结构。而创建线程的话,调用的是系统调用 clone,在 copy_process 函数里面, 五大结构仅仅是引用计数加一,也即线程共享进程的数据结构。
实战
pstree -apl pid看进程树
pstack pid 看栈
内存管理系统至少应该做三件事情:
第一,虚拟内存空间的管理,每个进程看到的是独立的、互不干扰的虚拟地址空间;
第二,物理内存的管理,物理内存地址只有内存管理模块能够使用;
第三,内存映射,需要将虚拟内存和物理内存映射、关联起来。
实战
1、查看内存映射
pmap 25992
cat /proc/25992/maps
分段可以配置权限
分页占用内存小, 而且可以换入换出
如果在系统中使用了huge page,则内存页的数量会减少,从而需要更少的页表(page table),节约了页表所占用的内存数量,并且所需的地址转换也减少了,TLB缓存失效的次数就减少了,从而提高了内存访问的性能。
如果在客户机中运行的应用程序(典型的应用为oracle数据库)具备使用huge page的能力,那么就可以在客户机中使用huge page带来性能的提升。
总的来说,对于内存访问密集型的应用,在KVM客户机中使用huge page是可以较明显地提高客户机性能的,不过,它也有一个缺点,使用huge page的内存不能被换出(swap out),也不能使用ballooning方式自动增长。
linux内部结构
slab 分配器
什么是物理/虚拟/共享内存——Linux内存管理小结一
如果有多个 CPU,那就有多个节点。每个节点用 struct pglist_data 表示,放在一个数组里面。
每个节点分为多个区域,每个区域用 struct zone 表示,也放在一个数组里面。每个区域分为多个页。
为了方便分配,空闲页放在 struct free_area 里面,使用伙伴系统进行管理和分配,每一页用 struct page 表示。
对于物理内存来讲,从下层到上层的关系及分配模式如下:
物理内存分 NUMA 节点,分别进行管理;
每个 NUMA 节点分成多个内存区域;
每个内存区域分成多个物理页面;
伙伴系统将多个连续的页面作为一个大的内存块分配给上层;
kswapd 负责物理页面的换入换出;
Slub Allocator 将从伙伴系统申请的大内存块切成小块,分配给其他系统。
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
保存,重启,就生效了。
用户态的内存映射机制包含以下几个部分。
用户态内存映射函数 mmap,包括用它来做匿名映射和文件映射。
用户态的页表结构,存储位置在 mm_struct 中。
在用户态访问没有映射的内存会引发缺页异常,分配物理页表、补齐页表。如果是匿名映射则分配物理内存;如果是 swap,则将 swap 文件读入;如果是文件映射,则将文件读入。