the notebook of eyu

2016-06-28
青海湖骑行

青海湖骑行

记得大学生就打算去青海湖骑行,只是经济上不允许,最终也没成行,这次也只是一次偶然的机会向几个朋友提起,然后大家的想法不谋而合,一次说走就走的旅行。

4天骑完全程,共360公理,经历过冰雹,大雨,强风,暴晒,一日四季,无数个上坡,下坡,不得不说,青海是我唯一一个来了,而没有后悔的地方。

Read More

2016-06-28
mysql count(*)原理

mysql count(*)原理

mysql count(*)原理

1
2
3
4
5
6
create table t1(
c1 varchar(30) not null,
c2 varchar(20) not null,
c3 varchar(40) not null,
c4 varchar(10) not null
) engine=innodb;
Read More

2016-06-21
数据库自增列

数据库自增列

简介

自增列的主要目的是自动生成行的唯一ID,对于不同的数据库或是存储引擎,还有一些特别的意义。

大部分数据库的使用者会使用自增列做为聚簇索引,以innodb为例,在内存中数据存放到B+Tree的一个页子结点上,数据按照主键顺序存放,每次插入数据时,会根据主键插入适当的位置。如果使用自增ID,数据插入相当于顺序插入,不会移动现有数据的位置;如果不使用自增ID,则有可能为了插入数据而移动数据,如果内存页已经回写的磁盘,则需要从磁盘上读回来,同时,频繁的移动和分页,会带来大量的碎片。

自增ID,一般使用一个整数来表示,而其它的一些方案,如UUID等一般会使用一个长字符串来表示(一般为16字节),存储空间和网络都会有一些浪费。

现在业务中接触到的很多客户,可能是习惯或是方便,一般不指定与某个有实际意义的字段为主键,而是使用自增列,其它维度查询列建索引,如果存储系统接口不支持的话,它们就会用UUID来代替,不会考虑与之相关的一些问题。

本文主要是了解一下自增列的实现原理

Read More

2016-04-11
golang的map的元素遍历为什么是随机的

golang的map的元素遍历为什么是随机的

golang的map的元素遍历是随机的?为什么这样做?怎么做的?

为什么这样做

大部分的编程语言,对于固定的数据集合,map的元素遍历是顺序,但是golang为什么要搞成随机的呢?

golang的设计哲学是:没有过于灵活地允许马马虎虎的代码,Go强迫你从一开始就把事情弄得直接一点。Go程序员参考里面说如果他们的程序可以编译(而且代码符合Go的风格),那么代码有很大的可能可以像预期的那样工作,这种模模糊糊却不错的感觉也有Go严谨性的贡献。没有诡异的类型bug,丢失分号等等错误。

尤其是,在Andrew的参考文章中,他指出这是Go的设计者们所作出的改变。他们不再允许人们依赖于那些破破烂烂的假设。我最痛恨的一点就是那些破烂的,到处是bug的功能(这发生在交付的产品中,或者是编程语言,等等很多地方),通过权衡,接受,从而变成了一个特性,另外尝试修复这些”特性”真的是很恶心。

怎么实现

如果每输出一个元素都随机的话,一是性能问题,而且还要标记某个元数是否访问到。所以很可能是随机生成一个访问点然后,先将当前桶便历完,然后顺序扫描下一个桶(猜测的,没有看源码,不一定正确),看下面程序的运行结果:

Read More

2016-03-10
大学毕业后的第三次室友聚会

大学毕业后的第三次室友聚会

大学毕业后的第三次室友聚会

Read More

2015-11-30
linux系统性能监控与优化--cpu

linux系统性能监控与优化--cpu

cpu scheduler负责调度两种资源:线程和中断, 按优先级从高到低:

  • 中断:设备告诉内核它们已经处理完成:如网卡发送完成了一个packet或是硬盘完成了一个io请求。
  • 内核进程:
  • 用户进程:

context switches:上下文切换

大多数的处理器在同一时刻只能运行一个进程,在多核处理器中,linux内核将每一个core当作一个独立的处理器。

一个内核可以同时运行50~50000个进程。如果只有一个cpu,内核必须负责高度和平衡这些进程。

每个线程将会分配一个时间片,直到这个线程的时间片用完,或是被更高优先级的线程抢占,它才会被重新放回cpu队列。切换线程的过程就是context switch。

每进行一次context switch,就要花费一些资源来将处理CPU寄存器和加入cpu队列。context switch越高,则内核调度的工作负担越大。

Read More

2015-11-13
pstack原理和应用

pstack原理和应用

排查性能问题时,经常使用patack打印所有线程的函数调用堆栈。

pstack实际上是一个脚本(/usr/bin/pstack),是通过GDB的thread apply all bt来实现了。

脚本的关键代码:

1
2
3
4
5
6
7
8
backtrace="thread apply all bt"   //GDB 通过thread apply all bt打印所有线程的调用堆栈

$GDB –quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 | // /proc/$1/exe对应实际运行的二进制代码
set width 0
set height 0
set pagination no
$backtrace //thread apply all bt
EOF

线上运行的程序一般是不带符号信息的,此时如果想打印堆栈,可以重新编译一个带符号信息的版本,将/proc/$1/exe替换成带符号版本的路径,就可以正常打印堆栈了。

Read More

2015-10-21
golang goroutine id的相关问题

golang goroutine id的相关问题

goroutine id主要有两个用途:

  • 打日志,方便排查问题
  • 因为golang是不支持Thread Local Storage,所以也可以使用goroutine id来实现Goroutine Local Storage
Read More

2015-09-18
golang自动生成版本信息

golang自动生成版本信息

需求

golang程序在build时自动生成版本信息,使用 ./helloworld –version可以查看版本和build时间

实现原理

使用链接选项-X设置一个二进制文件中可以访问的变量

实例1

1
2
3
4
5
6
7
8
package main
import "fmt"

var Version = "No Version Provided"

func main() {
fmt.Println("HelloWorld Version is:", Version)
}
1
2
3
go run -ldflags "-X main.Version 1.5" helloworld.go

HelloWorld Version is: 1.5

实例2

1
2
3
4
5
6
7
8
9
10
package main
import "fmt"

var buildstamp = "no timestamp set"
var githash = "no githash set"

func main() {
fmt.Println("HelloWorld buildstamp is:", buildstamp)
fmt.Println("HelloWorld buildgithash is:", githash)
}
1
2
3
4
5
6
go build -ldflags "-X main.buildstamp `date '+%Y-%m-%d_%I:%M:%S'` -X main.githash `git rev-parse HEAD`" helloworld.go

./helloworld

HelloWorld buildstamp is: 2015-09-08_05:58:49
HelloWorld buildgithash is: 1adb00d88d832687eb4148a3871829fb73021c29

参考资料

golang-auto-build-versioning

Read More

2015-06-07
oceanbase整理--工具

oceanbase整理--工具

去年,领导一直催让我整理一个排查性能问题和查BUG的文档,我一直拖着,因为很很想到一套体系把所有问题串连起来,而且大部分排查也是出于经验。

前一段时间翻译过一骗很好的性能排查与优化的文章:

  • 性能排查与优化综述
  • CPU性能排查与优化
  • 内存性能排查与优化
  • IO性能排查与优化

最近又读了一篇关于linux常用工具的文章linux-performance-monitoring-tools,感觉不错,结合自己的经历,描述一下,可能不全面,以后再补充。

SA

oceanbase一些重要应用上会部署sar后台运行,主要是为了分析一天的网络和磁盘性能数据,方便性能问题提成查。曾经一个合并问题,导致网络流量过大的问题,就是通过sar来辅助排查的。不过sar使用的时候,会写大量记录,所以最好选择一个单独的盘来用,不要影响正常的业务磁盘。

sar是sysstat包的一部分,sar可以做两件事情

  • 监控系统实时性能(CPU,内存,I/O)
  • 在后台收集数据,分析历史数据来查找性能瓶颈

sar详细功能说明

  • 收集cpu利用率
  • 单个cpu统计
  • 内存使用率
  • swap使用率
  • 系统的全部IO活动
  • 单个设备的IO活动
  • 上下文切换
  • 运行队列和load
  • 网络状态

sar使用实例

1
2
3
4
5
sar -b 1 3

-b: 报告io状态
1: 每一秒执行一次
3: 总共汇报3次
Read More