God's in his heaven.
All's right with the world.

0%

与MySQL等开源数据库不同的是,PostgreSQL(PG)并不使用O_DIRECT来写data文件和log文件,而是依赖于OS缓存,并且强调在设置shared buffer在大小时不能过大,否则会造成过于频繁的swap而导致IO性能下降。这与MySQL等数据库的buffer pool size越大性能越好的指导原则是相反的。并且PG依赖于OS缓存的这一特性也给提供PostgreSQL云服务造成了很多问题。例如云服务要求multiple tenants资源隔离,也就是说跑在同一个VM上的多个PG servers相互之间不能互相影响,但共用OS缓存显然会造成资源竞争。不知道Docker是否可以进行OS缓存的资源隔离,但现阶段还还依赖于Service Fabric架构的Azure PG显然得自己解决这个问题,也因此造成了架构设计上不得不考虑OS缓存的隔离。

The Internals of PostgreSQL: Chapter 2 Process and Memory Architecture这篇文章看来,与MySQL使用多线程或线程池和架构不同的是,PG使用的是多进程架构。多进程模型在Windows平台上会造成很大的性能问题,这暂且不提。但多进程之间是共用的shared buffer。既然如此,那就应该不是寄希望于OS缓存来便于多进程之间共享shared buffer吧。

阅读全文 »

本文作者吴卓浩,前Google中国用户体验团队负责人。微信公众号、知乎号:uxbang

2016年中秋节,被阿里的月饼门刷屏了。知乎上有人发起了讨论,“如果这样的事发生在Google会怎样”——如果也和阿里一样,我看着柜子里的差不多50件Google T-shirt,一头汗。

月饼事件的热闹,在于各种人都能从各种角度做各种分析评论。但是无论真相如何,上半场已经结束,希望那几位兄弟们吸取教训、但不要被吓怕,接下来的发展一定会有自己的精彩;而下半场才刚刚开始,对这几位兄弟来说是,对阿里,对整个行业,甚至对更大的体系,都是。

不论对于一个普通员工,还是对于一个公司的老大,公司 VS 个人,文化 VS 制度,永远是无法回避的问题,而且是没有标准解答的问题。比如,为了提高工作效率:

在一个初创公司中经常是没有标准流程的效率更高,而在一个大公司中是有标准流程效率更高;

在一个内容创作型的公司中,追随热点、快速响应的效率更高,而在一个产品研发型的公司中,做好计划、理清流程的效率更高;

在一个业务稳定成熟的公司中,以KPI推动工作效率更高,而在一个业务快速创新的公司中,以OKR推动工作效率更高;

阅读全文 »

简介

经常听到有人说磁盘很慢、网络很卡,这都是站在人类的感知维度去表述的,比如拷贝一个文件到硬盘需要几分钟到几十分钟,够我去吃个饭啦;而从网络下载一部电影,有时候需要几个小时,我都可以睡一觉了。

最为我们熟知的关于计算机不同组件速度差异的图表,是下面这种金字塔形式:越往上速度越快,容量越小,而价格越高。这张图只是给了我们一个直观地感觉,并没有对各个速度和性能做出量化的说明和解释。而实际上,不同层级之间的差异要比这张图大的多。这篇文章就让你站在 CPU 的角度看这个世界,说说到底它们有多慢。

希望你看到看完这篇文章能明白两件事情:磁盘和网络真的很慢,性能优化是个复杂的系统性的活。

注:所有的数据都是来自这个地址。所有的数据会因为机器配置不同,或者硬件的更新而有出入,但是不影响我们直觉的感受。如果对这些数据比较感兴趣,这个网址给出了不同年份一些指标的数值。

阅读全文 »

结合What is the relationship between the docker host OS and the container base image OS?How can Docker run distros with different kernels?和[Why docker has ability to run different linux distribution?(https://stackoverflow.com/questions/25444099/why-docker-has-ability-to-run-different-linux-distribution)这几篇文章看来,Docker实例和Host OS之间通讯的唯一桥梁就是Host OS的内核。挡在Fedora上跑一个Ubuntu 16.04的Docker实例时,Docker实例用的内核仍然是Fedora的内核,而不是Ubuntu 16.04所对应的的内核,因此有可能和原生的Ubuntu 16.04有一些内核上的区别。


本文地址:http://xnerv.wang/why-docker-has-ability-to-run-different-linux-distribution/

本文主要是对MinGW和Cygwin相关的一些名词的研究和推测,以求澄清一些似乎而非的概念,并记录当前已经弄清楚的一些问题,以及还需要进一步调研的一些细节。

关于MinGW和Cygwin的关系

网上大部分博文复制粘贴的文章都是讨论MinGW和Cygwin的区别和优劣。而我主要是分析两者的联系,以及一些需要同时用到MinGW和Cygwin的交叉编译场景。

MinGW的维基百科上看,Cygwin是提供一个模拟的POSIX层(cygwin1.dll)。我推测Cygwin也提供了一系列基于Cygwin的编译工具,在降需要移植的Linux代码在Cygwin上重新编译后,可以获得可以在Windows上直接运行的exe,而这个exe调用的还是POSIX风格的API,只不过这些API由cygwin1.dll提供模拟实现。而MinGW也提供了一系列编译工具,但MinGW-GCC是在编译时将代码中的POSIX API调用直接修改为对应的Windows API调用,从而不需要一个额外的dll转换层。需要额外提到的是,gcc的这种在编译时直接修改调用的API的行为不仅不少见,而且非常常见,在64位Linux上编译C++程序时,例如调用open这个函数,实际上在gcc编译后,调用的是libc中的open64函数,这个可以通过objdump导出外部依赖符号表来确认。另外就是,MinGW并不提供某些难以用Windows API实现的POSIX API,例如fork(),mmap()和ioctl()。

阅读全文 »

Seafile是国内少有的做的还不错的开源产品之一。相信很多朋友都经历过几年前的各大云盘厂商大战然后纷纷衰落的这个过程。金山快盘应该是我用过的个人觉得最好的一款云盘了,和Windows GUI的集成也非常完美。可惜现如今各大云盘不是停止运营了就是今非昔比了。因此与其每天提心吊胆地担心自己宝贵的“资源”是不是会被某度网盘封杀,作为码农的我们何不自己动手来搭建一个私有云盘。Seafile的UI是基于Qt,考虑到可移植性和跨平台兼容性,虽然不能像金山快盘那样拥有一些Windows上的特效,例如在托盘上查看当前在上传/下载哪些文件,以及上传/下载的进度。但优势是多平台,在Linux、安卓,iOS上都有相应的客户端。

Seafile官网只提供了Linux版本客户端的编译方法,并没有提供Windows版本的步骤。搜索了官方论坛,虽然有不少人提问问过,但是官方并没有给出回答。只能说国内的开源的文档还需要进一步完善,遮遮掩掩不算是真正的开源。搭建seafile windows客户端的交叉编译环境这篇文章给出了一种基于MinGW在Fedora上交叉编译Windows版本Seafile的方法。我曾尝试过在Ubuntu 18.04上重复这个步骤,但是因为一些packages的原因没能成功。不同的Linux发行版之间的package有一些区别。我也曾尝试过在Windows上的MinGW上交叉编译,但有一些packages死活找不到在Windows MinGW上对应的版本,而且编译时也有一些错误(Windows上的MinGW好像是跑在Cygwin上面的,也就是说Cygwin上的packages可能不全或者跟Fedora上有一些不同)。最终由于时间关系,我放弃了去弄清楚其中的原因,而是采用在Ubuntu上用docker安装Fedora镜像这种类似作弊的方法来重现这篇文章中的步骤。

阅读全文 »

协议格式

IPv4

IPv4头
IP首部中的校验和只覆盖IP的首部,不覆盖IP数据报中的任何数据。
IP层会丢弃传输中损坏的数据报,但是不产生错误消息,由上层去检测和重传。但是如果发生了分片,IP层应该能保证原子性。
在IP层下面的每一种数据链路层都有自己的帧格式,其中包括帧格式中的数据字段的最大长度,即最大传送单元 MTU (Maximum Transfer Unit)。当一个数据报封装成链路层的帧时,此数据报的总长度(即首部加上数据部分)最好不能超过下面的数据链路层的MTU值,否则要分片。
增加首部的可变部分是为了增加IP数据报的功能,但这同时也使得IP数据报的首部长度成为可变的。这就增加了每一个路由器处理数据报的开销,实际上这些选项很少被使用。新的IP版本IPv6就将IP数据报的首部长度做成固定的。
IP包中只有首部检验和,由TCP和UDP报文各自包含自身的数据校验和。

阅读全文 »

volatile

  • volatile使得代码每次在读写volatile变量时都需要从内存读写,而不能使用寄存器中缓存的值。并且也禁止编译器对volatible做编译优化。volatile本身并不是用于线程同步,也不保证原子读写(例如volatile a++这种需要几个指令才能完成的操作)。volatile主要用于access to memory mapped devices和variables in signal handlers and between setjmp and longjmp。C++标准禁止编译器reorder同一个线程内的volatile变量的读写,但不同线程则没有限制。non-volatile变量则有可能发生reorder(Stay away from Volatile in threaded code?)。
  • 而根据为什么volatile++不是原子性的?中的说法,volatile的读操作后会插入LoadLoad和LoadStore屏障,避免volatile读操作与后面的普通读写发生reorder。而volatile的写操作前会插入StoreLoad和StoreStore屏障,避免volatile写操作与后面的普通读写发生reorder(我不太确定这种说法的正确性,毕竟在wikipediavolatile (computer programming)中并没有提到volatile会插入内存屏障,或者只有Java等语言才会这样做?)。
  • 内存屏障中有提到

    C与C++语言中,volatile关键字意图允许内存映射的I/O操作。这要求编译器对此的数据读写按照程序中的先后顺序执行,不能对volatile内存的读写重排序。因此关键字volatile并不保证是一个内存屏障。[4]
    对于Visual Studio 2003,编译器保证对volatile的操作是有序的,但是不能保证处理器的乱序执行。因此,可以使用InterlockedCompareExchange或InterlockedExchange函数。
    对于Visual Studio 2005及以后版本,编译器对volatile变量的读操作使用acquire semantics,对写操作使用release semantics。

阅读全文 »

前言

MySQL5.5版本开始引入了MDL锁用来保护元数据信息,让MySQL能够在并发环境下多DDL、DML同时操作下保持元数据的一致性。本文用MySQL5.7源码分析了常用SQL语句的MDL加锁实现。

MDL锁粒度

MDL_key由namespace、db_name、name组成。

namespace包含:

  • GLOBAL。用于global read lock,例如FLUSH TABLES WITH READ LOCK。

  • TABLESPACE/SCHEMA。用于保护tablespace/schema。

  • FUNCTION/PROCEDURE/TRIGGER/EVENT。用于保护function/procedure/trigger/event。

  • COMMIT。主要用于global read lock后,阻塞事务提交。(在DML的commit阶段也会获取COMMIT锁)

  • USER_LEVEL_LOCK。用于user level lock函数的实现,GET_LOCK(str,timeout), RELEASE_LOCK(str)。

  • LOCKING_SERVICE。用于locking service的实现。

阅读全文 »

MDL(Meta Data LocK)的作用

在MySQL5.1及之前的版本中,如果有未提交的事务trx,当执行DROP/RENAME/ALTER TABLE RENAME操作时,不会被其他事务阻塞住。这会导致如下问题(MySQL bug#989)

master: 未提交的事务,但SQL已经完成(binlog也准备好了),表schema发生更改,在commit的时候不会被察觉到.

slave: 在binlog里是以事务提交顺序记录的,DDL隐式提交,因此在备库先执行DDL,后执行事务trx,由于trx作用的表已经发生了改变,因此trx会执行失败。 在DDL时的主库DML压力越大,这个问题触发的可能性就越高

在5.5引入了MDL(meta data lock)锁来解决在这个问题

阅读全文 »