Quantcast
Channel: PostgreSQL research
Viewing all 253 articles
Browse latest View live

【摘】关于naim幽灵般的牛叫--电网质量不好怎么办?

$
0
0
功放玩的就是电源早有定论。

       08年末玩hifi以来总有一个困惑:为什么同一套系统有时好声,有时又不好?其间怀疑过设备预热不够、个人身心状态差等因素,不可否认,这些也都是可能因素,但总又能找到反例,例如,已热机2天声音还达不到最佳状态,无论身体和心情状态如何,声音总也有好有坏无章可循。
  直到上周6晚,偶尔在音乐间隙听到了不同以往的更大声牛叫,于是关掉音乐专注于牛叫声,是否功放的环牛出毛病了?当时没心思再听下去就关掉设备睡觉了。但第二天下午2点多再开机牛叫声竟神奇的消失了,是否白天声音嘈杂造成原本存在的声音又听不见了?趴在音响架上听,还是听不到,于是开始怀疑是否功放不稳定?
  因此过去的一周一直在关注牛叫,到昨天基本发现了规律:用电高峰时牛叫声大,关掉音乐在聆听位置也听得到,用电低谷时(特别是午休时间和晚上12:00之后)牛叫声音小,不用说在聆听位置,甚至趴在音响架上也听不到,与此相应,牛叫声大的时候声音不好,牛叫声小的时候声音好。当然声音好与不好只是相对我自己这两套系统而言,请使用高级系统的烧友不要拍砖:)。
  今早请教了公司里电源专业的同事,他告诉我:电网中的负载会产生奇次谐波,如3次波、5次波、7次波…..,这些奇次波确实会引起变压器鸣叫,使用合适的滤波电路,可以使这些奇次谐波在电路内部产生自震荡而消耗掉,只输出1次谐波(50HZ)。至于这些问题对声音的影响,因他不是烧友,就只能我说给他听了,呵呵。
  
  这样就有了以下结论和疑问,先说结论:
1、 naim确实对电源质量的依赖性很大,这也是为什么naim有那么多分离供电设备的原因,如果电源不好,不仅声音达不到最佳,连牛都跟着“提意见”。同样的电网环境,我AV系统中的安桥806表现就没这么明显。
2、 声音的好坏,尤其是针对hifi系统而言,影响因素实在太多,三大件、房间、线材自不必说,仅电源就会产生巨大影响。烧友们在对声音不满意的时候,还要多试多思考,千万不要急着升级换系统,冲动是魔鬼。 
再说疑问,请各位老大帮忙解惑(我的hifi配置是naim 5i2cdp+naim nait xs2合并机+spendor sp1/2r2,信号和电源线是naim随机线,喇叭线是三越的naim nac a5):
1、 有没有成熟的纯净电源设备可以推荐?这些纯净电源设备对奇次谐波的过滤能力如何?效果如何?应该买多大功率的?
2、 naim的专用电源是否能有效过滤这些奇次谐波,在劣质电网中专用电源的牛不会也跟着一起“欢唱”吧?
3、 纯净电源设备可以替代naim的专用电源么?
4、 有没有其他方法可以隔离电网中的杂波或减小影响?说明一下,拉专线的方式在我这不好办,因为即使我家电器全关了,不到深夜电网质量依然不好,我又不可能直接从小区变压器上拉。

越好的环牛对市电质量要求越高吗?
可以这样认为,好牛的铁芯磁阻低,有任何的直流成分在里面,立马磁化,开叫。反而如果不是什么好铁芯,本身磁阻大,有那么点直流成分也被高磁阻给挡住了。
学习隆宇顶级滤波器的办法,在交流通路上串十几个正反并联的二极管就可以消除直流成分了。

牛叫不光电压的问题, 因为我在法国电压还是比较稳的.230 到 235顶多了, 但是波型真的很重要, 如果不对称就会有牛叫.

电压不稳也可能导致牛叫
1. 凡是我用过的功放在我家这里都有牛叫声,最近买的的KRELL FPB300C功放也有牛叫.夜里听特别烦,我有点不甘心,一定要打破这个宿命,于是自己买了个万表到家里一量,发现夜里的电压有时高到245V,总之从来没低过240V的.没办法最后买了个7000瓦的稳压器加在前面,才彻底消除了牛叫声,现在即使深夜里走近功放也听不到牛叫声了.
所以建议楼主买个稳压器试试.
2. 电压高是一方面,有时候家里的电压不太高230左右变压器也叫,问了一些人说是市电里有直流成分使变压器磁饱和了所以叫,后来买了台5000W的隔离牛就好了,但是问题是变成隔离牛叫了,不叫的大功率隔离牛也很贵,也就忍了


《黄帝内经》脏腑五行对应表

$
0
0

五脏

五脏之官

将军之官

谋虑出焉

君主之官

神明出焉

仓廪之官

五味出焉

相傅之官

治节出焉

作强之官

伎巧出焉

五腑

小肠

大肠

膀胱

五腑之官

中正之官

决断出焉

受盛之官

化物出焉

仓廪之官

五味出焉

传道之官

变化出焉

州都之官

津液藏焉

气化则能出矣

三焦

心包络

三焦者,决渎之官 ,水道出焉。

膻中者,臣使之官,喜乐出焉。(膻中=心包络)

脏象

脾、胃、大肠、小肠、三焦、膀胱

罢极之本

魄之居也

其华在爪

其充在筋

阳中之少阳

通于春气

生之本

神之变也

其华在面

其充在血脉

阳中之太阳

通于夏气

仓廪之本

营之居也

其华在唇四白

其充在肌

至阴之类

通于土气

气之本

魄之处也

其华在毛

其充在皮

阳中之太阴

通于秋气

封藏之本

精之处也

其华在发

其充在骨

阴中之少阴

通于冬气

凡十一脏,取决于胆也。

五脏生成

肝之合筋也
其荣爪也
其主肺也

心之合脉也
其荣色也
其主肾也

脾之合肉也
其荣唇也
其主肝也

肺之合皮也
其荣毛也
其主心也

肾之合骨也
其荣发也
其主脾也

五脏所主

五充(体)

骨、髓

五华

唇四白

五窍

五脏化液

五脏所藏

肝藏血

血舍魂

心藏脉

脉舍神

脾藏营

营舍意

肺藏气

气舍魂

肾藏精

精舍志

五志

忧、悲

恐、惊

关节分布

两腋

两肘

两髀(髋)

两肘

两腘

脏热分布

左颊红

颜面全部红

鼻红

右颊红

两颧红

舌分布

舌两旁(肝胆)

舌尖

舌中心(肺胃)

舌中心(肺胃)

舌根

气血筋脉注入处

诸筋者皆属于节
(睡觉时,血归于肝)

诸脉者皆属于目
诸血者皆属于心

 

诸气者皆属于肺

诸髓者皆属于脑

五精所并

精气并于肝则忧

精气并于心则喜

精气并于脾则畏

精气并于肺则悲

精气并于肾则恐

精气注入
(五轮)

五脏六腑之精气,皆上注于目而为之精。精之窠为眼,骨之精为瞳子,筋之精为黑眼,血之精为络,其窠气之精为白眼,肌肉之精为约束,裹撷筋骨血气之精而与脉并为系,上属于脑,后出于项中。

黑眼

约束

白眼

瞳子

风轮

血轮

肉轮

气轮

水轮

角膜、黑睛

眼角的血络

眼睑、眼皮

巩膜、白睛

瞳孔


五脏

 

肝藏血

血舍魂

肝气虚则恐

 

实则怒 

 

心藏脉

脉舍神

心气虚则悲

 

实则笑不休

脾藏营

营舍意

脾气虚则四肢不用、五脏不安

实则腹胀,经溲不利

肺藏气

气舍魂

肺气虚则鼻塞不利、少气

实则喘喝胸盈仰息

肾藏精

精舍志

肾气虚则厥

 

实则胀

五气所病

在肝为语
在胆为怒

在心为噫
在小肠为泄

在脾为吞
在胃为逆、为哕 、为恐

在肺为咳
在大肠为泄

在肾为欠为嚏
在下焦为水
膀胱不利为隆,不约为遗溺

五精所并

精气并于肝则忧

精气并于心则喜

精气并于脾则畏

精气并于肺则悲

精气并于肾则恐

五脏所恶

肝恶风

心恶热

脾恶湿

肺恶寒

肾恶燥

病发

惊骇

病在五脏

病在舌本

病在背

病在溪

怒伤肝

喜伤心

思伤脾

忧伤肺

恐伤肾

五病所发

阳病发于冬

阳病发于血

阴病发于肉

阴病发于夏

阴病发于骨

五劳所伤

久行伤筋

久视伤血

久坐伤肉

久卧伤气

久立伤骨

五脏之脉

代(缓)

营、石

五邪所见
(重症)

春得秋脉

(肝旺于春,其脉应弦。春不见弦脉,而建毛脉,为肺克肝之象。)

夏得冬脉

(心旺于夏,其脉应钩。夏不见钩脉,而见石脉,为肾克心之象。)

长夏得春脉

(脾旺于长夏,其脉应缓。长夏不见缓脉,而见弦脉,为肝克脾之象。)

秋得夏脉

(肺旺于秋,其脉应毛。秋不见毛脉,而见钩脉,为心克肺之象。)

冬得长夏脉

(肾旺于冬,其脉应石。冬不见石脉,而见缓脉,为脾克肾之象。)

五邪所乱

邪入于阳则狂,邪入于阴则痹,搏阳则为巅疾,搏阴则为瘖,阳入之阴则静,阴出之阳则怒,是谓五乱。

《黄帝内经》脏腑五行五色五味对应表

$
0
0

五色

五色之见死

色见青如草兹者死

色见赤如衃血者死

色见黄如枳实者死

色见白如枯骨者死

色见黑如炲者死

五色之见生

青如翠羽者生

赤如鸡冠者生

黄如蟹腹者生

白如豕膏者生

黑如乌羽者生

五藏所生之外荣

生于肝,如以缟裹绀

生于心,如以缟裹朱

生于脾,如以缟裹栝楼实

生于肺,如以缟裹红

生于肾,如以缟裹紫

色味当五脏

青当肝

青当筋

赤当心

赤当脉

黄当脾

黄当肉

白当肺

白当皮

黑当肾

黑当骨

生死面相

凡相五色,面黄目青、面黄目赤、面黄目白、面黄目黑,皆不死也。面青目赤、面赤目白、面黑目白、面赤目青,皆死也。


五味

五味所入

酸入肝

苦入心

甘入脾

辛入肺

咸入肾

五味所合

肝欲酸

心欲苦

脾欲甘

肺欲辛

肾欲咸

五味所走

酸走筋

多食之,令人癃
(手足不灵活)

咸走血

多食之,令人渴
(口渴)

甘走肉

多食之,令人悗心
(烦恼)

辛走气

多食之,令人洞心
(心中空虚)

苦走骨

多食之,令人变呕
(呕吐)

五味所禁

酸走筋,筋病无多食酸

咸走血,血病无多食咸

甘走肉,肉病无多食甘

辛走气,气病无多食辛

苦走骨,骨病无多食苦

五禁

肝病禁辛

心病禁咸

脾病禁酸

肺病禁苦

肾病禁甘

五味所伤

多食辛则筋急而爪枯
(味过于辛,筋脉沮弛,精神乃央。)

多食咸则脉凝泣而变色
(味过于咸,大骨气劳,短肌,心气抑。)

多食酸则肉胝绉而唇揭
(味过于酸,肝气以津,脾气乃绝。味过于苦,脾气不濡,胃气乃厚。)

多食苦则皮槁而毛拔

多食甘则骨痛而发落
(味过于甘,心气喘满,色黑,肾气不衡。)

五宜

肝色青,宜食甘

心色赤,宜食酸

脾色黄,宜食咸

肺色白,宜食苦

肾色黑,宜食辛

五病宜食

肝病者宜食

梗米饭、牛肉、枣、葵

心病者宜食

麻、犬肉、李、韭

脾病者宜食

大豆、猪肉、栗、藿

肺病者宜食

麦、羊肉、杏、薤

肾病者宜食

黄黍、鸡肉、桃、葱

五脏所苦

肝苦急,急食甘以缓之

心苦缓,急食酸以收之

脾苦湿,急食苦以燥之

肺苦气上逆,急食苦以泻之

肾苦燥,急食辛以润之

五脏所欲

肝欲散,急食辛以散之

心欲软,急食咸以软之

脾欲缓,急食甘以缓之

肺欲收,急食酸以收之

肾欲坚,急食苦以坚之

用辛补之

用咸补之

用甘补之

用酸补之

用苦补之

酸泻之

甘泻之

苦泻之

辛泻之

咸泻之

《黄帝内经》五行天象对应表

$
0
0

阳干

阴干

天干化合

丁壬

合化木

戊癸

合化火

甲己

合化土

乙庚

合化金

丙辛

合化水

阳支

辰戌

阴支

丑未

地支三会

寅卯辰

巳午未

 

申酉戌

亥子丑

地支化合

亥卯未

三合化木局

寅午戌

三合化火局

 

巳酉丑

三合化金局

申子辰

三合化水局

八卦

震巽

艮坤

干兑

五力

岁星

荧惑星

镇星

太白星

辰星

天三生木

地八成之

故曰其数八

地二生火

天七成之

故曰其数七

天五生土

地十成之

故曰其数十

地四生金

天九成之

故曰其数九

天一生水

地六成之

故曰其数六

静兼

曲直

燔灼

高下

散落

沃衍

五化

生荣

蕃茂

丰满

坚敛

凝坚

宣平

均衡

齐修

宣明

咸整

温和

炎暑

溽蒸

清切

凝肃

湿

发散

明曜

安静

劲肃

流源

宣发

郁蒸

云雨

湿

雾露

摧拉

炎烁

动注

肃杀

凝冽

燔火满

淫溃

苍落

冰雹

平气之纪

敷和

升明

备化

审平

静顺

不及之纪

委和

伏明

卑监

从革

涸流

太过之纪

发生

赫曦

敦阜

坚成

流衍

PostgreSQL range gist index 20x+ speedup than Mysql index combine query

$
0
0
今天一位兄弟跟我抱怨MYSQL里面查IP地址库并发几千每秒的查询数据库就抗不住了.
于是问他要来了他们的IP地址库数据和查询用的SQL以及MYSQL里面的表结构。
把数据转到PostgreSQL里面做一下相对应的压力测试,看看PostgreSQL的表现。
MYSQL里面的表结构如下 : 

CREATE TABLE ip_address_pool (
  id int(10) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  start_ip varchar(20) NOT NULL COMMENT '起始ip',
  end_ip varchar(20) NOT NULL COMMENT '截止ip',
  province varchar(128) NOT NULL COMMENT '省名',
  city varchar(128) NOT NULL COMMENT '城市',
  region_name varchar(128) NOT NULL COMMENT '地区名',
  company_name varchar(128) NOT NULL COMMENT '公司名',
  start_ip_decimal bigint(10) DEFAULT NULL,
  end_ip_decimal bigint(10) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY idx_start_ip_Decimal (start_ip_decimal),
  KEY idx_end_ip_Decimal (end_ip_decimal)
) ENGINE=InnoDB AUTO_INCREMENT=436820 DEFAULT CHARSET=utf8 COMMENT='ip地址对应表';

MYSQL里面的查询SQL如下 : 

select 
  province,
  start_ip_Decimal as startIpDecimal,
  end_ip_Decimal as endIpDecimal
  from ip_address_pool
  where
  #{ip}>=start_ip_Decimal and
  #{ip}<=end_ip_Decimal;

数据量大概40W.
由于MYSQL里面没有IP地址类型,  所以他们把IP地址转换为数值类型来存储并用来做IP地址范围的匹配.
IP地址的转换算法是32位的二进制IP地址转10进制数字。
在PostgreSQL9.2里面新增了range类型, 例如可以用来存储ip地址范围, int值的范围.
具体的应用可以参见我以前写的BLOG : 
因此这个应用场景, PostgreSQL有三种选择来实现它 : 
1. 和MySQL里面一样, 使用两个字段分别存储起始的IP数字
2. 使用iprange, 直接存储IP地址范围
3. 使用int8range, 存储转换后的数字范围

接下来是三种方法的表结构 : 
1. 和MySQL里面一样, 使用两个字段分别存储起始的IP数字

CREATE TABLE ip_address_pool (
  id serial8 primary key,
  start_ip inet NOT NULL ,
  end_ip inet NOT NULL ,
  province varchar(128) NOT NULL ,
  city varchar(128) NOT NULL ,
  region_name varchar(128) NOT NULL ,
  company_name varchar(128) NOT NULL ,
  start_ip_decimal bigint ,
  end_ip_decimal bigint 
) ;
-- 以下索引其实只需要建一个就够了, PostgreSQL btree索引支持>=,>,<=,<,=等几种操作符, 同时IP地址段也不存在交叠的情况.
-- 如何避免交叠呢, 在并发的情况下插入和更新ip_address_pool表, 是没有办法避免交叠情况的发生的, 例如
-- 1. 先查询需要插入的IP地址段是否已经存在表里面
-- 2. 不存在则插入.但是这里存在一个问题, 并发的情况下, 多个进程都可能认为插入的数据不存在, 都插入了, 但是并发插入的数据中可能有交叠的.
-- 3. 在MYSQL中只能使用全表锁来避免这个问题.
-- 4. 在PostgreSQL中则不需要全表锁, 因为可以使用range类型, 建立range类型的exclusive 约束, 这个在我前面两篇关于range的BLOG里面讲到过.
create index idx_ip_address_pool_sip on ip_address_pool (start_ip_decimal);
create index idx_ip_address_pool_eip on ip_address_pool (end_ip_decimal);
2. 使用iprange, 直接存储IP地址范围

create type iprange as range (subtype=inet);

CREATE TABLE ip_address_pool_2 (
  id serial8 primary key,
  ip_segment iprange NOT NULL ,
  province varchar(128) NOT NULL ,
  city varchar(128) NOT NULL ,
  region_name varchar(128) NOT NULL ,
  company_name varchar(128) NOT NULL
) ;

CREATE INDEX ip_address_pool_2_range ON ip_address_pool_2 USING gist (ip_segment);


3. 使用int8range, 存储转换后的数字范围

CREATE TABLE ip_address_pool_3 (
  id serial8 primary key,
  start_ip inet NOT NULL ,
  end_ip inet NOT NULL ,
  province varchar(128) NOT NULL ,
  city varchar(128) NOT NULL ,
  region_name varchar(128) NOT NULL ,
  company_name varchar(128) NOT NULL ,
  ip_decimal_segment int8range
) ;

-- 从第一个表把数据转换成range类型并存储到这个表

insert into ip_address_pool_3 (id,start_ip,end_ip,province,city,region_name,company_name,ip_decimal_segment) select id,start_ip,end_ip,province,city,region_name,company_name,int8range(start_ip_decimal,end_ip_decimal+1) from ip_address_pool;

CREATE INDEX ip_address_pool_3_range ON ip_address_pool_3 USING gist (ip_decimal_segment);


接下来测试一下第一种方法和第三种方法的性能差别 : 
1. 
测试脚本:

 \setrandom ip 0 2094967294
select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where :ip>=start_ip_Decimal and :ip<=end_ip_Decimal;

 测试结果:

pg92@db-172-16-3-33-> pgbench -M prepared -c 8 -j 8 -f ./ip_test.sql -n -T 60 -h 127.0.0.1 -U postgres postgres
transaction type: Custom query
scaling factor: 1
query mode: simple
number of clients: 8
number of threads: 8
duration: 60 s
number of transactions actually processed: 20389
tps = 339.576580 (including connections establishing)
tps = 339.618604 (excluding connections establishing)

为什么只有300多呢?原因是建立的不是复合索引, 注意因为这里使用的是范围检索, 不是= , 所以检索速度和取值范围关系很大, 分别取三个值, 从小到大.  来看看查询耗时.

postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 1>=start_ip_Decimal and 1<=end_ip_Decimal;
                                                                          QUERY PLAN                                                
                          
------------------------------------------------------------------------------------------------------------------------------------
--------------------------
 Index Scan using idx_ip_address_pool_sip on ip_address_pool  (cost=10000000000.00..10000000004.51 rows=1 width=22) (actual time=0.0
04..0.004 rows=1 loops=1)
   Index Cond: (1 >= start_ip_decimal)
   Filter: (1 <= end_ip_decimal)
 Total runtime: 0.014 ms
(4 rows)

postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 1123371940>=start_ip_Decimal and 1123371940<=end_ip_Decimal;
                                                                    QUERY PLAN                                                      
               
------------------------------------------------------------------------------------------------------------------------------------
---------------
 Index Scan using idx_ip_address_pool_sip on ip_address_pool  (cost=0.00..3899.49 rows=75277 width=22) (actual time=37.572..37.573 r
ows=1 loops=1)
   Index Cond: (1123371940 >= start_ip_decimal)
   Filter: (1123371940 <= end_ip_decimal)
   Rows Removed by Filter: 96523
 Total runtime: 37.604 ms
(5 rows)

postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 4123371940>=start_ip_Decimal and 4123371940<=end_ip_Decimal;
                                                                     QUERY PLAN                                                     
                 
------------------------------------------------------------------------------------------------------------------------------------
-----------------
 Index Scan using idx_ip_address_pool_sip on ip_address_pool  (cost=0.00..17557.23 rows=1251 width=22) (actual time=168.138..168.139
 rows=1 loops=1)
   Index Cond: (4123371940::bigint >= start_ip_decimal)
   Filter: (4123371940::bigint <= end_ip_decimal)
   Rows Removed by Filter: 436810
 Total runtime: 168.165 ms
(5 rows)

-- 所以需要建立复合索引, 
create index idx_ip_address_pool_ip on ip_address_pool (start_ip_decimal,end_ip_decimal);

-- 建完后还是分三个值来测试一下响应时间 :
postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 1>=start_ip_Decimal and 1<=end_ip_Decimal;
QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------------
-----
Index Scan using idx_ip_address_pool_ip on ip_address_pool (cost=0.00..4.61 rows=1 width=22) (actual time=0.004..0.005 rows=1 loop
s=1)
Index Cond: ((1 >= start_ip_decimal) AND (1 <= end_ip_decimal))
Total runtime: 0.014 ms
(3 rows)

postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 1123371940>=start_ip_Decimal and 1123371940<=end_ip_Decimal;
QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------------
------------
Index Scan using idx_ip_address_pool_ip on ip_address_pool (cost=0.00..8754.53 rows=75277 width=22) (actual time=5.995..5.996 rows
=1 loops=1)
Index Cond: ((1123371940 >= start_ip_decimal) AND (1123371940 <= end_ip_decimal))
Total runtime: 6.017 ms
(3 rows)

postgres=# explain analyze select province, start_ip_Decimal as startIpDecimal, end_ip_Decimal as endIpDecimal from ip_address_pool where 4123371940>=start_ip_Decimal and 4123371940<=end_ip_Decimal;
QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------------
-------------
Index Scan using idx_ip_address_pool_ip on ip_address_pool (cost=0.00..8737.49 rows=1251 width=22) (actual time=27.042..27.044 row
s=1 loops=1)
Index Cond: ((4123371940::bigint >= start_ip_decimal) AND (4123371940::bigint <= end_ip_decimal))
Total runtime: 27.079 ms
(3 rows)

-- 那么它的TPS能达到多少呢?
pg92@db-172-16-3-33-> pgbench -M prepared -c 8 -j 8 -f ./ip_test.sql -n -T 60 -h 127.0.0.1 -U postgres postgres
transaction type: Custom query
scaling factor: 1
query mode: prepared
number of clients: 8
number of threads: 8
duration: 60 s
number of transactions actually processed: 216400
tps = 3606.368660 (including connections establishing)
tps = 3606.821632 (excluding connections establishing)
-- 有提高, 但是还远远不够.

3. 
测试脚本:

\setrandom ip 0 2094967294
select province,ip_decimal_segment  from ip_address_pool_3 where ip_decimal_segment @> :ip::int8;

测试结果:

pg92@db-172-16-3-33-> pgbench -M simple -c 8 -j 8 -f ./ip_test.sql -n -T 60 -h 127.0.0.1 -U postgres postgres
transaction type: Custom query
scaling factor: 1
query mode: simple
number of clients: 8
number of threads: 8
duration: 60 s
number of transactions actually processed: 3498195
tps = 58301.468890 (including connections establishing)
tps = 58307.865068 (excluding connections establishing)

-- 使用prepared还能有提升, 如下

pg92@db-172-16-3-33-> pgbench -M prepared -c 8 -j 8 -f ./ip_test.sql -n -T 60 -h 127.0.0.1 -U postgres postgres
transaction type: Custom query
scaling factor: 1
query mode: prepared
number of clients: 8
number of threads: 8
duration: 60 s
number of transactions actually processed: 4810415
tps = 80171.925111 (including connections establishing)
tps = 80180.458975 (excluding connections establishing)


-- 使用range类型还是测试一下那三个值的耗时, 分布就比较均匀了.

postgres=# explain analyze select province,ip_decimal_segment  from ip_address_pool_3 where ip_decimal_segment @> int8 '1';
                                                                   QUERY PLAN                                                       
            
------------------------------------------------------------------------------------------------------------------------------------
------------
 Index Scan using ip_address_pool_3_range on ip_address_pool_3  (cost=0.00..862.55 rows=437 width=38) (actual time=0.034..0.035 rows
=1 loops=1)
   Index Cond: (ip_decimal_segment @> 1::bigint)
 Total runtime: 0.045 ms
(3 rows)

postgres=# explain analyze select province,ip_decimal_segment  from ip_address_pool_3 where ip_decimal_segment @> int8 '1123371940';
                                                                   QUERY PLAN                                                       
            
------------------------------------------------------------------------------------------------------------------------------------
------------
 Index Scan using ip_address_pool_3_range on ip_address_pool_3  (cost=0.00..862.55 rows=437 width=38) (actual time=0.036..0.036 rows
=1 loops=1)
   Index Cond: (ip_decimal_segment @> 1123371940::bigint)
 Total runtime: 0.052 ms
(3 rows)

postgres=# explain analyze select province,ip_decimal_segment  from ip_address_pool_3 where ip_decimal_segment @> int8 '4123371940';
                                                                   QUERY PLAN                                                       
            
------------------------------------------------------------------------------------------------------------------------------------
------------
 Index Scan using ip_address_pool_3_range on ip_address_pool_3  (cost=0.00..862.55 rows=437 width=38) (actual time=0.058..0.059 rows
=1 loops=1)
   Index Cond: (ip_decimal_segment @> 4123371940::bigint)
 Total runtime: 0.069 ms
(3 rows)


【其他】
1. PostgreSQL支持函数索引,所以我们不需要改表结构就可以使用函数索引来达到加速的目的。
例如 : 

CREATE TABLE ip_address_pool (
  id serial8 primary key,
  start_ip inet NOT NULL ,
  end_ip inet NOT NULL ,
  province varchar(128) NOT NULL ,
  city varchar(128) NOT NULL ,
  region_name varchar(128) NOT NULL ,
  company_name varchar(128) NOT NULL ,
  start_ip_decimal bigint ,
  end_ip_decimal bigint 
) ;
create index idx_ip_address_1 on ip_address_pool using index gist (int8range(start_ip_decimal, end_ip_decimal+1::int8));
select * from ip_address_pool where int8range(start_ip_decimal, end_ip_decimal+1::int8) @> ?;


【注意】
1. pgbench 的random值使用的是有符号int4类型 , 因此超出了本例最大的40亿的值, 所以在测试过程中我使用了0到20亿的数值区间. 
不过这个基本上不影响测试结果.
 如果要让pgbench支持int8需要修改pgbench的源码.
2. PostgreSQL的range类型除了可以很好的利用它的gist索引作为检索之外, 还可以使用它来做排他约束, 也就是防止数据交叠.
这个在MySQL中就只能通过全表锁来搞定. 
3. MySQL里面可以使用osdb来测试, 源码4. PostgreSQL 优化相关的BLOG可以参考如下:
5. 使用PostgreSQL存储IP数据的话, 还可以使用掩码, 这样的话就不需要存储两个字段了, 直接存在一个字段就可以.
当然也可以加一个存储比特位的字段, 使用bit函数来处理包含关系.
另一种用法是把这个比特运算放到内存中执行, 内存中存储IP比特位以及对应到数据库的记录的ID信息, 获取ID后去数据库查询, 也就是把数据库的范围查询变成主键查询. 也可以提高效率.
6. range类型是9.2新增的数据类型, 如果要在其他版本中使用, 可以参考 http://blog.osdba.net/?post=96, 实现了float8range. 
timestamprange则可以参考http://www.pgxn.org/dist/temporal/
Flag Counter

enum

$
0
0
enum定义的值在C里面其实是用数字代表的.
如下 : 

[root@db-172-16-3-150 ~]# cat h.c
#include <stdio.h>

typedef enum unit_of_measure {
  COUNT, KG, ML
} unit_of_measure;

int main() {
  fprintf(stdout, "COUNT:%i, KG:%i, ML:%i\n", COUNT, KG, ML);
  return 0;
}
// 结果
[root@db-172-16-3-150 ~]# gcc -O3 -Wall -Wextra -Werror -g ./h.c -o h && ./h
COUNT:0, KG:1, ML:2


这个特性也适合于数组结合起来用来表示数组的元素位置.

PostgreSQL cursor in batch commit use case

$
0
0
一位网友问到的问题如下 : 

Hello,
       德哥,我想请您请教一个关于postgresql批量提交方面的问题。 
       由于我们现在的项目是在从oracle转pg,所以遇到了很多oracle中曾经写批量提交方面的问题,
       类似如下情况:
       FOR c IN cur LOOP   ---游标
       --更新 
      UPDATE tbname s
      SET col1 = now(),
          col2 = now(),
          col3 = to_char(SYSDATE, 'yyyymmdd') ,
          col4 = c.orgcode_temp
      WHERE s.id = c.id;
    
      --计算,每500提交一次
      i := i + 1;
      IF MOD(i, 500) = 0 THEN
        COMMIT;
      END IF;
      IF MOD(i, 5000) = 0 THEN
        dbms_lock.sleep(10);
      END IF;
    
    END LOOP;
    COMMIT; --提交

类似这种的问题,现在想问问您,对于这种批量提交有什么好的方法吗?


由于PostgreSQL函数在处理时是作为一个事务来处理的, 不能像Oracle那样在函数中使用commit做部分提交. 
除非写在exception中, 那会回滚前面的非exception部分, 执行exception部分, 同样无法达到以上目的.

所以不能单纯依靠PostgreSQL函数来解决以上问题. 需要在外部声明with hold游标, 在函数中使用这个游标. 这样是可以的.
以下均为autocommit模式. 即自动提交
1. 创建以下函数替换以上函数

create or replace function f_batch(b int, c refcursor) returns void as $$
declare
  i int := 0;
  rec record;
begin
  loop
    fetch c into rec;
    if not found then
      raise notice 'cursor is empty. close it';
      close c;
      return;
    end if;
    raise notice 'do some thing , rec:%', rec;
    if i>=b then
      raise notice 'reach batch limit.';
      return;
    end if;
    i := i+1;
  end loop;
  return;
end;
$$ language plpgsql strict;

2. 在会话中声明游标, 

digoal=# declare c1 cursor with hold for select relname from pg_class;
DECLARE CURSOR

3. 通过多次调用函数来实现, 每次调用为一次事务.

digoal=# select f_batch(5,'c1');
NOTICE:  do some thing , rec:(pg_statistic,11,10818,0,10,0,12550,0,15,387,15,2840,0,t,f,p,r,26,0,f,f,f,f,f,t,1674,1,{postgres=arwdDxt/postgres},)
NOTICE:  do some thing , rec:(pg_type,11,71,0,10,0,0,0,8,334,8,0,0,t,f,p,r,30,0,t,f,f,f,f,t,1674,1,{=r/postgres},)
NOTICE:  do some thing , rec:(pg_toast_2619,99,11050,0,10,0,12552,0,2,10,2,0,2841,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE:  do some thing , rec:(pg_toast_2619_index,99,0,0,10,403,12554,0,2,10,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(pg_authid_rolname_index,11,0,0,10,403,0,1664,2,1,0,0,0,f,t,p,i,1,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(pg_authid_oid_index,11,0,0,10,403,0,1664,2,1,0,0,0,f,t,p,i,1,0,f,f,f,f,f,t,0,0,,)
NOTICE:  reach batch limit.
 f_batch 
---------
 
(1 row)

digoal=# select f_batch(5,'c1');
NOTICE:  do some thing , rec:(pg_attribute_relid_attnam_index,11,0,0,10,403,0,0,16,2281,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(pg_attribute_relid_attnum_index,11,0,0,10,403,0,0,11,2281,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(pg_toast_1255,99,11047,0,10,0,0,0,0,0,0,0,2837,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE:  do some thing , rec:(pg_toast_1255_index,99,0,0,10,403,0,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(pg_toast_2604,99,11044,0,10,0,12586,0,0,0,0,0,2831,t,f,p,t,3,0,f,f,f,f,f,t,1674,1,,)
NOTICE:  do some thing , rec:(pg_toast_2604_index,99,0,0,10,403,12588,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  reach batch limit.
 f_batch 
---------
 
(1 row)

digoal=# select f_batch(500,'c1');
中间省略
NOTICE:  do some thing , rec:(pg_toast_12392_index,99,0,0,10,403,12782,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  do some thing , rec:(sql_packages,12269,12408,0,10,0,12793,0,1,10,1,12409,0,f,f,p,r,5,0,f,f,f,f,f,t,1674,1,"{postgres=arwdDxt/postgres,=r/postgres}",)
NOTICE:  do some thing , rec:(pg_toast_12412_index,99,0,0,10,403,12802,0,1,0,0,0,0,f,f,p,i,2,0,f,f,f,f,f,t,0,0,,)
NOTICE:  cursor is empty. close it
 f_batch 
---------
 
(1 row)

游标已关闭.

digoal=# select f_batch(5,'c1');
ERROR:  cursor "c1" does not exist
CONTEXT:  PL/pgSQL function f_batch(integer,refcursor) line 7 at FETCH


使用这种方法需要注意关闭游标, 因为其他会话看不到这个游标, 也无法去关闭这个游标. 只有声明这个游标的会话可以关闭它.
游标长时间不关闭会影响vacuum回收垃圾. 这个PostgreSQL的mvcc机制有关. 例如 : 
SESSION A : 

digoal=# declare c1 cursor with hold for select * from pg_class;
digoal=# select * from pg_cursors ;
 name |                        statement                        | is_holdable | is_binary | is_scrollable |         creation_time   
      
------+---------------------------------------------------------+-------------+-----------+---------------+-------------------------
------
 c1   | declare c1 cursor with hold for select * from pg_class; | t           | f         | t             | 2013-07-30 17:23:35.3859
97+08
(1 row)


SESSION B : 

digoal=# insert into t select generate_series(1,10000);
INSERT 0 10000
digoal=# delete from t;
DELETE 10002
digoal=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  "t": found 0 removable, 10002 nonremovable row versions in 45 out of 45 pages
DETAIL:  10002 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM


SESSION A : 

fetch 10000 from c1;
digoal=# fetch 100000 from c1;
 relname | relnamespace | reltype | reloftype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | relallvisibl
e | reltoastrelid | reltoastidxid | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relha
spkey | relhasrules | relhastriggers | relhassubclass | relispopulated | relfrozenxid | relminmxid | relacl | reloptions 
---------+--------------+---------+-----------+----------+-------+-------------+---------------+----------+-----------+-------------
--+---------------+---------------+-------------+-------------+----------------+---------+----------+-----------+------------+------
------+-------------+----------------+----------------+----------------+--------------+------------+--------+------------
(0 rows)


SESSION B : 

digoal=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  "t": found 0 removable, 10002 nonremovable row versions in 45 out of 45 pages
DETAIL:  10002 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM


SESSOIN A : 

digoal=# close c1;
CLOSE CURSOR


SESSION B : 

digoal=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  "t": removed 0 row versions in 44 pages
INFO:  "t": found 0 removable, 58 nonremovable row versions in 45 out of 45 pages
DETAIL:  58 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM

博客导出工具: 豆约翰

$
0
0
这几天网易博客好像有点问题, 无法导出内容. 网上搜索了一下博客备份的工具.
发现一个很好用的备份工具, 豆约翰. 确实非常强大.
只可惜目前网易博客导出有个小bug.
 网易博客中有2中格式.
user.blog.163.com和blog.163.com/user.
但是带有@符号的用户无法备份(例如user@126), 原因是这种用户没有user@126.blog.163.com的域名. 转义后为user%40126.blog.163.com
工具地址 : 

太阳山

$
0
0
浙江江山太阳山, 海拔1300以上位置拍到的罕见花草, 还有红豆杉.
太阳山 - 德哥@Digoal - PostgreSQL
 
太阳山 - 德哥@Digoal - PostgreSQL
 
太阳山 - 德哥@Digoal - PostgreSQL
 
太阳山 - 德哥@Digoal - PostgreSQL
 

【转载】天文器材参考指南(新手入门参考)

$
0
0

天文器材主要分为4类:支架系统(赤道仪、经纬仪)、望远镜镜筒(OTA)、目镜、摄影用摄像头、CCD等。

一 支架系统

       其中,支架系统是最重要的,望远镜能否舒适的观测,效果咋样,可以说一个好的支架是必须的。这一点新手往往会忽略,而很多商家业在大量推销很多很便宜的望远镜系统,往往配置的是低成本的粗制滥造的脚架系统,望远镜架上去晃的不行,很难舒服的观测!把

大量的时间浪费在这些廉价的系统上即打击兴趣又得不偿失。

       从结构形式上支架主要分为赤道式和经纬式二大类,经纬式就是两个调整轴一个跟地面平行、一个垂直,一般较便宜, 重量较轻, 搬运、调试都比较方便。但当你需要对天体进行自动跟踪时,地平式支架就显得力不从心了,尽管由计算机自动控制的望远镜可以在地平状态下进行自动跟踪,但由于整个视场会绕视场中心旋转,无法进行天体摄影,而且跟踪精度也较差。赤道式支架(又称赤道仪)是进行跟踪天体摄影的必备器材。无论选择哪一种支架,其稳定性都是最重要的,稳定性差的地平式和赤道式支架它们给观测,尤其是调焦和找星带来了很大的麻烦,使天文观测的乐趣大打折扣。一个优质的照相机三角架往往比一般的望远镜自带的支架要好用,照相机三角架的说明书上一般都会给出其最大负荷,但由于望远镜的镜筒与照相机相比要长得多,对三角架云台的力矩也大得多,所以选择最大负荷比望远镜的重量大一倍左右的三角架比较理想。

       对于天文摄影而言,赤道仪比望远镜本身还要重要,因为望远镜有时仅仅用于导星,而赤道仪跟踪的好坏及稳定程度却直接关系到照片的质量。

       在你准备入手一台赤道仪或者经纬台时,有几个问题时必须先考虑清楚的:

        1. 你准备花多少精力和时间来熟悉天空?如果你对夜空和要观测的天体足够熟悉,而且不认为对照星图自己找星是一项苦差使的话,那么你就可以选择较便宜、更加便携、较轻也较易于使用的经纬台。反之,那些带有精密坐标机构,甚至计算机控制自动找星(有GoTo功能)的赤道仪将是最佳选择。需要说明的是随着电子工业的发展以及规模生产的优势,目前国际上主要望远镜生产厂家的GoTo赤道仪的价格越来越趋于合理,不再高不可攀。

  2. 你的观测地有多远?如何搬运你的望远镜,是否有运输工具(车)以及搬运时你愿意付出多少劳动?这个问题的答案不但决定着望远镜的口径,也关系到望远镜的光学结构以及相配合的支架系统的选择。请记住一条由无数天文爱好者付出了很多代价得出的结论,即望远镜的使用频率与其重量成反比。我们认为一台经常被带出去观测的望远镜要远远好于那些由于太笨重而被留在家里的望远镜。

        3.你是否打算进行天体摄影、或是CCD成像?“天体摄影”和“CCD”都是昂贵的,这是需要一定的经济和时间门槛的爱好,经济条件或者是时间方面暂时不允许的话,一定不要盲目上设备。

        设备推荐(今后有合适新品,会及时更新):

           LXY(天文家园的同好)DIY版 2英寸AIM经纬台 + 摄影三脚架

------ 对于手工找星熟练或者想天地两用(也拍摄风景花鸟)、或者没有车无法搬运沉重器材的以及经费充裕的人士,以下推荐是首选,因为这是最便携的合格器材!不算镜子,整套重量3KG,一个摄影双肩背包连镜子带架子背起来就走,可以说是最方便的器材:

          三脚架经济条件好的,推荐法国捷信的,一般可考虑在 曼富图、金钟、百诺三个牌子里选择,只是要注意:1 要买3节式的(天文镜比照相机重得多所以要考虑结构的稳定性)2 要单买三脚架,不要买云台一体式的 3 一般500元以下的杂牌不要买哪些顶不住天文镜

       

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

大概最低预算:1500元左右,最大可支撑镜子:106以下的APO或者150F5以下的牛反。

        裕众的   SKYTEE-2 微动经纬台 

               以下引用天文家园的 “喜欢天文”胸的评价:

1、负载能力强,稳定性超好。
配以EQ5短版脚架,这个经纬台虽重一点,但是优越的稳定性会让你感觉值得。首先架设并不过于复杂,承载80-130的折射镜绰绰有余(估计160的镜子也没问题)同时装上130apo和100ed及两套相关寻星相机等附属物品总重量已超出15公斤,经纬台表现稳(感觉还有充足的负载余量)在195倍调焦时一改以前使用K3经纬台是的那种颤动和不可触及的情形,你可以从容调焦几乎觉不出有手的触及。
2、平衡性好,微动功能顺滑。
SKYTEE-2经纬台如同赤道仪一样配有重锤,这也是他能在微动、随动调整时达到轻松与顺滑的关键所在!通过对重锤的调整能使镜子找到仰俯角平衡点,这时就是不锁紧随动扳手也能使镜子停在任意角度,而不会出现镜子仰角达到一定程度后随重力作用继续上仰甚至无法控制的情况发生。并且在调整微动旋钮时会是你感到异常的轻松与顺滑。
在左右两个挂镜装置方面我的体会是:单镜架设时首选带有重锤一侧使用,挂双镜时重量大的镜子挂在重锤侧并待双镜挂好后调整平衡锤。
3、一台多用,适应范围广。
左右两个挂镜点不仅可以分别挂镜,还可以接挂其他外围设备:相机或其它东西。

4、鸠尾槽非常精致。双锁紧旋钮的大型鸠尾槽无论安装大镜子还是小镜子都会让你用得放心。

优点说了一堆了,说点不足吧。

1、没有配套铝箱。
这一点我觉得很关键,外出时没有合适的箱包会比较麻烦,最好有个铝箱与之配套(哪怕是选购)个人单个定做铝箱很麻烦的尤其是在挖模环节。
2、总体重量重了一点。本体重量约5.5-6公斤,加上脚架和重锤(好像是1.8公斤X2)大约在12-13公斤左右,但还是可以接受。(这一点对我来说不算是缺点,因为我并不追求便携性)

3  配套的鸠尾槽做工太差,拧紧的手旋螺丝用几次后会滑丝,要是裕众不改进这个问题,还要买家额外付出成本买LXY的鸠尾槽。
总之,如果不是刻意追求价格和便携性的话,SKYTEE-2将是相当不错的选择!

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 预算:经纬仪1980,架子980,最大可支撑镜子:160以下的APO或者C8以下

 晶华的 ZII 微动经纬台:

  自重含脚架7.8KG,承重10KG,可以承载4-5寸的apo折射镜或者20的牛反

自重适中,有微动和随动功能 。 预算:全套1500左右

天文器材参考指南(新手入门参考) - 深圳市天文学会 - 深圳市天文学会(深圳观星会)天文器材参考指南(新手入门参考) - 深圳市天文学会 - 深圳市天文学会(深圳观星会)

 

缺点:使用为动旋钮跟随目标时,镜子会有轻微晃动必须等稳定后再观测。当然这是微动经纬仪的通病(即时是高桥的云台TGM2,也有晃动),今后晶华会出电动升级套件,这个问题就会解决。

 

天文器材参考指南(新手入门参考) - 深圳市天文学会 - 深圳市天文学会(深圳观星会)

 

信达的 EQ3W赤道仪

目前,价格最低的,合格能用的赤道仪,缺点载重比较低,极限是110级别的折射或者150级的牛反,另外没有自动跟踪(可以另购马达升级),建议只升级1个马达,不建议升级成GOTO模式(价格已接近HEQ5了),适合预算紧张的用户

另:

    1)EQ3D跟EQ3W价格差不多,建议选择EQ3W,主要是W版标配极轴镜,三角架是钢管的相对结实。

     2)市场上很多价格低得离谱的所谓EQ3赤道仪,那些不要上当,要买信达出的

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 大概预算:2000元左右,最大可支撑镜子:106以下的APO或者150F5以下的牛反。

 信达的 HEQ5 Pro 和 NEQ6 Pro赤道仪

 HEQ5 Pro 可以说是目前价格最低的,带Goto功能,能进行深空摄影的赤道仪,也是世界上用户最多的赤道仪,经过无数爱好者验证,完全可以满足深空摄影的精度需求。NEQ6和HEQ5相比载重量更大,可达16KG

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 

 大概预算:HEQ5PRO 5500元左右,NEQ6Pro  8800左右

星特朗CGEM赤道仪

CGEM赤道仪拥有豪放的外表,而且它的承载能力大(与NEQ6PRO相当)并且抗震性能好,对于目视观测和摄影都非常理想。人机工程学设计——CGEM赤道仪采用友好的人机工程学设计,巨大的高度角和方位角调节螺栓,能够快速而且舒适地在极轴校准时进行调整。内置赤经和赤纬电机线路的设计使得外表看起来很清爽和简洁,安装毫无困难。创新——CGEM系列有一个创新的极轴校准步骤叫All-Star。All-Star允许用户选择任意明亮的星,然后软件会计算并帮助进行极轴校准。CGEM另一个大创新是周期误差永久校正(PEC),这能够让用户算出蜗杆传动装置的周期误差,同时赤道仪保留有PEC记录,这对天文摄影来说是非常好的。性能——当天体在天子午圈(假想的从北极到南极并过观测者的线)附近的时候,CGEM 会进行良好的跟踪,不会中断摄影。

缺点:

   1)  价格想对较高,比NEQ6Pro 贵了1K多。

   2)用户相对较少,有问题不容易得到同好帮助。

   3)  想要拍摄深空的同好,请先不要购买这款产品,因为导星时,会出现DEC轴有时无法调整Bug,想要拍深空请大家等到星特朗解决该问题后再说(Goto和拍摄行星没有问题)。

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

大概预算:1万元左右,载重与NEQ6Pro相当

 

发烧级推荐:

A) 派拉蒙MX

      啥也不说了,派拉蒙绝对是世界最顶级的赤道仪之一,精度!自动控制程度,搭配的控制软件TheSky6都是专业级的,现在新推出了MX级,自重只有23KG,而载重高达40KG(小日本的恶魔系列可以说是望尘莫及),对于发烧友或者需架大镜子的用户来说,派拉蒙MX是不二选择,目前价格:大概6万3-6万5左右(不含立柱或脚架),派拉蒙是各天文台使用最多的专业赤道仪!

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 

B) AP Macth1GTO

AP的APO望远镜是最抢手的No 1,很多用户为了买一台AP望远镜不惜排队2-3年,他的赤道仪也是顶级的!AP Match1Gto 以HEQ5的自重,承载超过NEQ6达4KG,精度和做工都比小日本的恶魔200的高,价格跟恶魔200又差不多,可以说是恶魔200的终极杀手,缺点:一般要排队3个月-半年。

 

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

价格:5万左右

 

 C) ASA的 DDM60

ASA是奥地利著名的天望公司,他的赤道仪和RC摄星镜都是精品。而且ASA的赤道仪是据说不需要导星即可支持深空摄影!还有一点就是他的对极轴方式,是最先进和方便的,透过激光在天球上打出北极星实时位置的小圈,然后调整赤道仪把北极星在天空中套入小圈!载重大概 25Kg左右。价格:65000,其实这个价格可以买派拉蒙MX了,不过他的自重较轻,对于在乎重量的人也是一个选择。

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

 二 望远镜

      望远镜按结构主要分为双筒、折射式、反射式和折返式。

      反射式:

反射望远镜是使用曲面和平面的面镜组合来反射光线,并形成影像的光学望远镜,而不是使用透镜折射或弯曲光线形成图像的屈光镜。反射式望远镜所用物镜为凹面镜,有球面和非球面之分;比较常见的反射式望远镜的光学系统有牛顿式反射望远镜与卡塞格林式反射望远镜。

反射式望远镜的性能很大程度上取决于所使用的物镜。通常使用的球面物镜具有容易加工的特点,但是如果所设计的望远镜焦比比较小,则会出现比较严重的光学球面像差;这时,由于平行光线不能精确的聚焦于一点,所以物像将会变得模糊。因而大口径,强光力的反射式望远镜的物镜通常采用非球面设计,最常见的非球面物镜是抛物面物镜。由于抛物面的几何特性,平行于物镜的光线将被精确的汇聚在焦点上,因而能大大改善像质。但即使是抛物面物镜的望远镜仍然会存在轴外像差。

      一个弯曲的主镜是反射望远镜基本的光学元件,并且在焦平面上形成影像。从凹面镜到焦平面的距离称为焦长焦距,底片或数位感应器可以在此处记录影像,或是安置目镜以便眼睛能观看。 反射镜虽然能够消除色差,但是仍然有其他的像差:

当使用非抛物面镜时会有球面像差成像不在平面上。
彗形像差
畸变(视野)

在反射镜的设计和修正上会使用折反射镜来消除其中的一些像差。

几乎所有用于研究的大型天文望远镜都是反射镜,有下列的原因:

在采用透镜之下,必须整块镜片材料皆为没有缺点和均匀而没有多相性,而反射镜只需要将一个表面完美的磨光,磨制相对简易。
不同颜色的光在穿透介质时会有不同的传播速度。对未做修正的透镜,这会造成折射镜特有的色差。制作大的消色差透镜所费巨大,反射镜则完全没有这个问题。
反射镜可以在更广阔的范围内研究光谱,因为有些波长在穿过折射镜或折反射镜的透镜时会被吸收掉。
大口径透镜在制造和操作上都有技术上的困难。其一是所有的材料都会因为重力而下垂,观测时举得最高而且也是相对较重的透镜只能在镜片周围加以支撑,另一方面,面镜除了反射面以外,可以在反射面的背面和其他的侧边进行支撑。

       主焦点的设计使用在天文台的大望远镜上,观测者置身于镜筒内反射光线汇聚的焦点上。在过去都是由天文学家自己置身其中,如今都由CCD取代了。

File:Newtontelescope.png

  折射望远镜

       是一种使用透镜做物镜,利用屈光成像的望远镜。折射望远镜最初的设计是用于侦查和天文观测,但也用于其他设备上,例如双筒望远镜、长焦距的远距照像摄影机镜头。较常用的折射式望远镜的光学系统有两种形式:即伽利略式望远镜和开普勒式望远镜,其优点是成像比较鲜明、锐利;缺点是有色差。现在销售的折射镜一般分为:普消(多数为长焦)、ED和APO镜。

普通消色差(普消):

      一般采用长焦设计,F12甚至更高,普通望远镜在F15焦比时可以与F8焦比的ED镜媲美,优点是价格便宜,缺点镜筒太长不方便运输携带。

消色差折射镜(ED):

      设计使用两片玻璃(有不同色散度的"冕牌玻璃"和燧石玻璃)做物镜,降低了色差和球面像差。两片玻璃的每一个面都要抛光,然后组合在一起。消色差透镜可以让两种不同波长(通常是红色和蓝色)的光,都能聚焦在相同的焦平面上。

高度消色差折射镜(APO):

      使用特别的材料,特别低色散度的材料,来制造物镜。他的设计能让三种不同的颜色(通常是红色、绿色和蓝色)汇聚在相同的焦平面上,颜色的残差错误(二级光谱)比消色差透镜低了一个数量级。这种望远镜的主镜是萤石(CaF2)或超低色散(ED)玻璃的透镜,产生非常清晰没有色差的影像。这种望远镜在业余天文望远镜的市场中是非常高价值的产品。高度消色差折光镜的口径已经可以做到553毫米,但多数仍在80~152毫米之间。主流产品均采用3片式设计和采用FPL53光学玻璃,在口径130及以下可以做到F6的焦比,150以上一般最短是F7的。

折反射望远镜 

反射折射这个名词在光学系统中的意思就是既有透镜也有面镜的系统。反射折射的光学系统常用在望远镜和照相机使用的质轻、长焦透镜。 通常的设计是利用特殊形状的透镜来修正反射镜的像差。反射式望远镜镜系统的物镜虽然没有色差,但球面反射镜存在球面像差,而且焦距越长的球面反射镜对加工精度要求越高。非球面的抛物面反射镜虽然在光轴中心不存在像差,但在光轴以外存在球差和彗差,而且加工难度大,成本也高。折反射式望远镜就是针对反射式系统的这些缺点,而试图利用透镜折射系统的优点来补偿。目前世界上常见的折反射式望远镜类型有两种,施密特式(施卡)和马克苏托夫式(马卡)。

 施卡:

      是在1931年由德国光学家施密特发明的优秀广视野望远镜。在镜筒最前端的光学元件是施密特修正板,这块板是经过研磨接近平行的非球面薄透镜,可以确实的改正与消除主镜造成的球面像差。施密特-卡塞格林式的主要好处是它的光路经过折叠之后使镜筒可以缩成很短而矮胖,因而增加了可携带性,在观察行星和深空天体时的光学性能也都很好。
File:Schmidt-Cassegrain.png

        马卡:

马克苏托夫-卡塞格林式是在1940年由苏联光学家德密特利·马克苏托夫发明的马克苏托夫望远镜的改良型。马克苏托夫式的机械部分比卡塞格林式简单,并且有封闭的镜筒和全部都是球面镜的光学系统。与相似的施密式最关键的不同的是弯月型的修正板也设计成容易磨制的球面透镜,而不是施密特式的非球面透镜设计。因为焦距比较长,因此马克苏托夫式的视野比施密特-卡塞格林式的狭窄,一般也比较重;但是较小的次镜使他的解析力比施密特-卡塞格林式好。

File:Maksutov-Cassegrain.png

马克苏托夫-卡塞格林式的光路图。

望远镜的主要参数

物镜口径,经常被简称为“口径”,指的是望远镜中起主要聚光作用的那片镜片未受遮挡的部分,也就是实际有效的那部分镜片的直径。一般以毫米做单位。

物镜口径与望远镜的分辨本领有直接的关系。天文望远镜中刚刚能够区分开两个星点的角距离叫做分辨角,用希腊字母δ表示,采用弧度做单位。分辨角越小,表示越能分辨出靠得近的天体。分辨角与物镜口径的关系(瑞利关系)是:

\delta = \frac{1.22\lambda}{D}

其中λ是入射光的波长,D是望远镜的物镜口径。上式仅仅是望远镜理论上能够达到的分辨角的极限。实际上由于大气湍流、望远镜镜片本身的形状偏差等原因望远镜很少能够到达此理论值。从上式中可以看出,物镜口径越大,分辨角越小,望远镜的分辨本领越高,分辨出天体细节的能力越强。此外,望远镜的口径越大,收集到的光越多,从而能够看到越为暗弱的天体。基于以上原因,现代的大型望远镜都以追求大的物镜口径为主要目标。

出瞳直径,光线经过目镜汇聚后,在目镜后形成的亮斑的直径。

对于肉眼使用的光学器材,光线必须经过瞳孔后进入视网膜成像,人类的瞳孔在白天大约为3毫米,夜晚最大可达7毫米左右。在用光学器材观察的时候,目镜汇聚光线形成的亮斑将投射到瞳孔上,因此,越大的出瞳直径,给人感觉成像的亮度也越大。但大于瞳孔直径的出瞳直径是没有意义的。

出瞳直径的计算公式为: p = D / M 其中p代表出瞳直径,D代表物镜口径,M代表放大倍数。

购买指南

     这个因人而异,但是也主要决定于你的经济实力和时间,和是否要进行天文摄影

     玩天文必备,便携装备:

           经济型:LXY的AIM经纬台+裕众80ED+国产三脚架,预算5K

           小康型:LXY的AIM经纬台+LXY8/90APO+法国捷信三脚架,预算8-10K

           腐败型:LXY的AIM经纬台+TMB80APO+法国捷信三脚架,预算20K

     对于目视派:

           经济紧张的:最低预算4K左右:信达EQ3W赤道仪 + 信达150F5抛物面牛反(小黑)

           小康型:       信达HEQ5PRO赤道仪+80/90的APO(LXY/裕众/锐星/英田),预算1万2

            腐败型:      信达NEQ6PRO赤道仪+130APO(裕众/锐星/英田),预算3万

            发烧型:       派拉蒙MX赤道仪+TEC180FL APO,预算20万

            便携型:        LXY版AIM+三角架+裕众80APO/F6,预算7.5K

            深空经济型:信达10寸dob牛反,预算3.5K

            深空腐败型: 自制400以上Dob牛反

      行星摄影:

            经济型:HEQ5PRO赤道仪+信达200/F5抛物面牛反(大黑),预算8.5K

            腐败性:星特朗CGEM赤道仪+C11HD,预算2万

        深空摄影:

             经济型:信达HEQ5PRO赤道仪+80/90的APO(裕众/锐星/英田)+文佳60/220导星镜+qhy5,预算1万5

            腐败型:信达NEQ6PRO赤道仪+发骚器(FSQ)106或者APM130/F6APO+3.5寸TMB平常镜,预算6万

            发烧型: 派拉蒙MX赤道仪+ASA200/300的RC,预算20万

三 目镜

又称接目镜,通常是一个透镜组,可以连接在各种不同光学设备,像是望远镜和显微镜的后端。所以如此命名,是因为当设备被使用时,它常是最接近使用者眼睛的透镜。物镜的透镜和面镜收集光线并引导至焦点生成影像;目镜被安置在焦点,主要的功能在放大影像,放大的倍率则与目镜的焦距有关。

双筒望远镜的目镜通常是永久固定在镜筒上,因此它们的视野和放大倍率都是预先就被设定好的。望远镜和显微镜,目镜通常都可更换,而通过目镜的更换,使用者可以调整视野和倍率。例如,望远镜就经常以更换目镜来增加或减少倍率;目镜也为使用者提供提供不同视野和适眼距的调整。

除了伽利略式望远镜的目镜采用凹透镜以外,大多数望远镜的目镜都可以等效为凸透镜。一个好的目镜应该尽可能消除色差像差、提供优良的像质,提供较大的表观视场,较长的适眼距(出瞳距离)以方便人们使用,提供较好的目镜罩以减少杂光干扰。设计优秀的目镜还考虑了戴眼镜的人使用,使用了橡皮可翻目镜罩或者可调升降目镜罩。目镜的光学系统的设计有多种形式,如:惠更斯目镜(H式或HW式)、冉士登目镜(R式或SR式)这些属于第一代目镜。第二代目镜具有代表性的有四种:凯尔纳目镜(K式)、普罗素目镜(PL式)、阿贝无畸变目镜(OR式目镜)、爱尔弗广角目镜。第三代目镜最著名的目镜是TV的Nagler目镜,它拥有更加出色的表现,特别是在视场修正技术方面。在小型天文望远镜中,大部分目镜的接口遵循三个标准,即外径为0.965英寸(24.5毫米,已淘汰)、1.25英寸(31.7毫米)和2英寸(50.8毫米),具有相同接口标准的目镜可以互相替换使用。

几种目镜结构图:

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

天文器材参考指南(未完待续) - 深圳天文之家 - 深圳天文之家

目镜的内部反射和散射

内部反射有时也称为散射,导致穿过目镜的光线不仅分散还降低了目镜产生影像的对比。当影像的效果很差时就会出现"鬼影",称为幻像。多年以来,设计时玻璃与玻璃之间制造很小的空气隙,就能有效的改善这个问题。

薄透镜可以采用在元件表面镀膜的方法来解决这个问题。这一层厚度只有一或两个波长的膜,可以改变通过元件的光线折射来减少反射和散射。有些镀膜可经由全反射的过程吸收这些光线以低浅角度射入的光线,使它们不会穿过透镜。

目镜的侧向色差
       色差的产生是因为不同的颜色(波长)由一种介质到另一种介质时,有不同的折射率。对目镜而言,色差来自穿越空气和玻璃之间的界面。蓝光和红光在经过目镜之后不能聚焦在同一个焦点上,这种现象对点光源 的结果是可能产生一个围绕着焦点的模糊色环,通常的结果是造成影像模糊不清。有几种方法可以减缓这个问题,一种是利用薄膜来改正目镜的元素。较为传统的方法则是利用多个不同玻璃和曲度的元素来消减变形。纵向色差在光学望远镜中,因为焦距很长而成为很显著的效应;显微镜,因为一般的焦距都很短,就不受这种效应的影响。通常,目镜在改善色差时,这两种都需要做修正。

目镜的焦长(焦距)
       焦长是平行的光经过目镜后汇聚的点与目镜主平面的距离。在使用时,目镜焦长和物镜焦长的结合,确定了放大倍率。当单独提到目镜时,他的单位通常是毫米(mm);而当在一架可以更换目镜的仪器上使用时,有些用户喜欢使用经过目镜后所能得到的放大倍数做为单位。对望远镜,一些特殊的目镜可以产生不同的角放大率,并且望远镜和显微镜的组合倍率可以用下面的公式来计算:

\mathrm{MA}= \frac{f_O}{f_E}

此处:
MA是要计算的角放大倍率,
fO是望远镜物镜的焦长,
fE是目镜的焦长,要用同样的测量单位来表示。

因此,要提高放大倍率,可以将目镜的焦长减短,或是将仪器本身的焦长加长。例如,焦长25mm的目镜用在物镜焦长1200mm的望远镜上,放大倍率是48倍;焦长4mm的目镜用在相同的望远镜上,放大倍率是300倍。

业余天文学家使用的望远镜的目镜倾向于将焦长标示出来。在天文学,焦长的表示单位通常是毫米(mm),范围则在3至50毫米之间。实际的放大倍率则依使用的望远镜的焦长来决定。但是当描述观测现象时,天文学家对于目镜的标示,却又惯用放大倍率,而不是标示目镜的焦长。在观测报告上使用放大倍率是比较方便的,因为它更直接的提示了观测者实际上看到的是什么的看法。由于放大倍率是依赖所使用的望远镜决定,因此单独只提放大倍率对望远镜的目镜是毫无意义的。

目镜的视野
      视野,经常会使用缩写FOV,描述的是经由目镜能看见的目标 (从观测者所在地测量得到的角度) 。目镜的视野范围会根据各自所结合的望远镜或显微镜的放大率而有所变化,也和目镜本身的性质有关。目镜由他们的视野阑做区分,这是进入目镜的光线抵达场透镜前所经过的最狭窄孔径。由于这些可变的因素,"视野"这个名词通常有两种意义,并且总是只表示其中之一。
实视野是使用某一架望远镜时,由于具体的放大效果,通过目镜能看见的真实天空的角度大小,它的范围通常在0.1度至2度之间。视视野是被测量的目镜所有的一个恒定值,范围从35度至80以上。它本身,明显的是一个抽象的数值,但是可以经由望远镜与目镜结合所得到的的放大率测量出实视野。目镜的视视野通常都会作为目镜的特性标示出来,为用户提供一个方便的方法,计算在自己的望远镜上使用时的实视野。目镜的使用者通常都需要计算实视野,因为这表示出目镜与望远镜结合时,实际上能看见的天空大小。计算实视野最方便的方法取决于是否知道视视野。如果已经知道视视野,实视野可以经由下面的近似公式计算:

FOV_C= \frac{FOV_P}{mag}
FOV_C= \frac{FOV_P}{(\frac{f_T}{f_E})}

此处:

FOVC是实视野,计量的单位是以FOVP时所提供的角度单位来测量。.
FOVP 是视视野。
mag是放大倍数。
fT是望远镜的焦长。
fE是目镜的焦长,用与fT相同的量度单位来标示。

  购买指南:

          目镜市场现在比较混乱,低端市场充斥着大量所谓PL目镜,高级一点的号称TMB目镜(TMB老先生怕是要哭了),这些所谓TMB只不过是用了TMB的一张设计图而已,然后大部分是国内宁波的宇众产(注意不是云南裕众)的,质量实在是对不起TMB这三个字!

          基本上,看行星推荐晶华的短焦目镜5mm、5.5mm,配合晶华或者裕众的2x巴罗,价格也很实惠,这是最具性价比的行星目镜,看深空推荐裕众的70度系列,尤其是70度26mm。如果追求82度或者100度建议还是直接上TV的Nangle和ETHOS系列,虽然裕众和晶华也出产了82度和100度目镜,但是价格也都超过1K了,比TV打折时只低20%左右,不如直接买TV目镜了;广角目镜还有一个选择就是宾得的XW系列,评价跟TV不相上下。看行星的顶级目镜现在大多数都不好买到,只能淘2手如TMB MONO(真正进口德国产的)系列,蔡司的系列等,替代的选择有TV的Nangle 2.5 和宾得的 XW5。

 

注:资料和图片大部分转自 维基百科和天文家园论坛。

UW的目镜好,还是TMB目镜的好呢

$
0
0
以下是网友的评论 : 
这2个目镜我都有,老版TMB 7MM和OEM的UW 6MM
不管从观测舒适度还是成像效果来说毫无疑问TMB完胜,UW的黑圈的确比较严重,原因是UW眼罩短了那么2-3MM
TMB的可旋升眼罩非常适用,不管你戴不戴眼镜都非常舒服,另外TMB目镜悬下眼罩还带螺纹接口,貌似28MM规格

新版TMB目镜改进了消光,绝对值得拥有

再详细点
UW为2组4片,TMB为3组5片,物镜端都为内置巴罗结构,目镜端UW为PL结构,TMB为K结构,巴罗倍数基本一样都是2.5X-3X左右,巴罗接口结构完全一样,两个目镜的巴罗端可以直接旋下互换
同时UW和TMB都可以拆掉巴罗直接使用,大概相当于焦距X2.5-X3的目镜
UW号称66度视野,但边缘畸变已经非常严重了,实际只有55度左右成像质量较好,而TMB畸变明显好得多

一位淘宝卖家的解说.
您刚发来的 关于UW66 度目镜  和 58度行星目镜的评论,应该说都不是专业的评论,只能是使用者自己的评论。
 (15:56:53):
只能这样说, 如果是以 UW66度目镜和 同厂的58度行星目镜对比,
66度 比58度视角更大,相对控制边缘也更难。 
另外,66度目镜是基本结构,  58度目镜其实都知道是内置增倍镜,复合结构目镜。
 (15:58:18):
58度行星目镜 是以58度目镜基础配上专门设计的增倍组件,使像质达到非常好的控制性能。
当然,价格也会高点。
 (15:59:08):
在选用上, UW66 度 总体看是不如58度行星目镜,但是 UW66 度 的 10mm以内的目镜,价位要低点,
另外10mm以上的目镜,58度行星目镜就不做设计了
 (16:00:02):
如果上高倍,那上行星目镜好了

80EQ开光射月

$
0
0
最近杭州的雾霾非常严重, 能见度极低. 所以能看到月亮实在是非常惊讶, 赶紧把小八搬到楼下.
没带口罩, 不一会喉咙就难受得不行. 用手机随便拍了几张, 20mm的目镜, 40倍放大的样子. 效果非常之烂.
下次用neq6+bkp2001000再拍一下, 看看专业和入门的区别到底有多大.

80EQ开光射月 - 德哥@Digoal - PostgreSQL
 
80EQ开光射月 - 德哥@Digoal - PostgreSQL
80EQ开光射月 - 德哥@Digoal - PostgreSQL
 
 

lua 本地变量的作用域

$
0
0
lua 不加前缀定义的为全局变量, 例如 : 
i = 1   -- 这样定义的为全局变量.
定义本地变量使用local前缀, 例如 : 
local i = 1 -- 定义一个本地变量.
本地变量的作用域比较诡异, 特别是在命令行中很"诡异", 需要理解这个chunk.

Unlike global variables, local variables have their scope limited to the block
where they are declared. A block is the body of a control structure, the body of a
function, or a chunk (the file or string where the variable is declared):

本地变量定义在一个函数体中, 那么作用域就在函数中.
如果定义在一个控制结构中, 那么就在这个控制结构中.
如果定义在一个文件中, 那么作用域就在这个文件中.
如果是使用命令行的话, 一条完整的命令就是一个chunk, 所以例如 : 

> local i = 1
> print(i)
nil

因为上面那条local i = 1是一个chunk, 定义完就抛弃了.
所以下面打印的是全局变量i, 而不是本地变量i.
除非写在一个执行体中.

> do 
>> local i = 1
>> print(i)
>> end
1

在命令行中一个chunk很好区分, >就是一个chunk , >>表示执行体未结束.
对于文件的话, 本地变量作用域在文件中, 所以以下文件可以打印出i=1

[root@db-172-16-3-150 ~]# vi lua
local i = 1
print(i)
[root@db-172-16-3-150 ~]# lua ./lua
1

在控制结构中的例子 : 

> if true then
>> local x = 1
>> print(x)
>> end
1
> print(x)
nil

> i = 0
> while i < x do
local x = i*2 -- this x is local
print(x)
i = i+1
end
0
2
4
6
8
10
12
14
16
18

Lua 函数用法和它的"诡异"之处

$
0
0
Lua 函数调用时, 需要带括号(对于单个参数的函数,某些值不需要用括号, 如字符串, 表). 
但是注意return是可以带括号也可以不带括号的.
这里重点说到括号, 因为括号和返回多值的函数关系很大, 也就是"诡异"的地方, 后面会举例.

函数可以作为一个语句执行, 那有点类似一个过程语言, 执行完的函数结果被抛弃掉.
例如 : 
print("abc") -- 这作为一个语句执行.
函数也可以在一个表达式中执行, 那么结果会被返回, 对于多值函数需要注意返回的值的个数.
例如 :
i = math.sin(123)  -- 这里的math.sin函数在表达式中, 所以结果返回.

函数调用必须带括号, 除了单个参数的函数, 并且参数类型为字符串, 表构造器时, 可以不带括号.
例如:

> print {1,2,3}
table: 0x9465c0
> print [====[
>> hellp
>> nihao
>> ]]
>> ]====]
hellp
nihao
]]
> print "hello"
hello
> print {}
table: 0x946d10


函数的结构
包含函数名, 参数, 函数体几个部分.
例如 : 

function add(a)
  local sum = 0
  for i = 1, #a do
    sum = sum + a[i]
  end
  return sum
end

函数的参数, 和本地变量类似, 调用函数时为值传递的方式. 在函数中修改这个变量对传入的变量没有影响. 
同时, 函数调用时允许传入的参数个数和函数定义的个数不一致的情况.
例如

function f (a,b)
  print(a,b)
end

可以这么调用 : 

> function f(a,b)
>>   print(a,b)
>> end
> f()  -- a,b都为nil
nil     nil
> f(1)  -- a=1, b=nil
1       nil
> f(2)
2       nil
> f(1,2,3)  -- a=1, b=2, 3抛弃
1       2
> f(1,2)
1       2

如果函数参数缺失的情况下, 可以给它默认值, 我现在还不清楚是不是可以在函数定义时指定, 如果不能的话就这么这么搞了.

function f(a,b)
  if a == nil then a = 1 end
  if b == nil then b = 1 end
  print(a,b)
end

为什么不用 a= a or 1呢? 因为当传入的是boolean值时, false的话, false or 1也变1了.
这个是Lua的一种逻辑判断值的取值问题. 例如

a or b  -- 当a = nil或false时, a or b这个逻辑判断表达式的值就是b, 当a不为false或者nil时, 那么这个表达式的值就是a.
> print(false or 1)
1
> print(0 or false)
0
> print(0 or "hello")
0
> print(nil or "hello")
hello
> print(false or "hello")
hello

a and b 则当a为真(不为false或nil)时, 表达式的结果等于b, 如果a为真, 则表达式的结果为a.

> print(1 and false)
false
> print(1 and nil)
nil
> print(1 and 2)
2
> print(false and "hello")
false
> print(nil and "hello")
nil


Lua支持一个函数返回多个值, 但是返回多个值时, 有多少个值传递, 或者被抛弃, 和用法有关, 比较诡异的地方来了.

> print(string.find("hello","llo"))
3       5
string.find("hello","llo")函数返回2个值, 第一个值为匹配到的字符串的开始位置, 第二个值为结束位置.

但是, 当多值函数后面再有表达式时, 多值函数就只返回第一个值, 后面的值被抛弃.

> print(string.find("hello","llo"), "hell")  -- 这样的话string.find("hello","llo")只返回了第一个结果3. 5被抛弃了.
3       hell

在赋值时也一样

> a,b = string.find("hello","llo")
> print(a,b)
3       5
> a,b = string.find("hello","llo"), "he"
> print(a,b)
3       he

还有一种情况, 如果要强制使用仅仅返回1个结果的话, 在函数外加括号就可以. 这就是文章开头提到的括号用法.

> a=(string.find("hello","llo"))
> print(a)
3
> a=string.find("hello","llo")
> print(a)
3
> print(string.find("hello","llo"))
3       5
> print((string.find("hello","llo"))) -- 多值函数用括号包一层, 返回第一个结果值. 而不是整个list
3


多值函数例子 : 

> function max(a)
  local mi = 1 -- index
  local m = a[mi]
  for i=1,#a do
    if a[i] > m then
      mi = i; m = a[i]
    end
  end
  return m, mi
end
> print(max({1,2,3,4,5}))
5       5
> print(max({1,2,3,4,5,100}))
100     6


比较容易记住Lua的多值返回函数的诡异的例子 : 

> function foo0() end
> function foo1() return "a" end
> function foo2() return "a", "b" end
> x,y = foo2()
> print(x,y)
a       b
> x = foo2()
> print(x)
a
> x,y,z = 10,foo2()   -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值. 没有值的话, 全取.
> print(x,y,z)
10      a       b
> x,y = foo0()
> print(x,y)
nil     nil
> x,y = foo1()
> print(x,y)
a       nil
> x,y,z = foo2()
> print(x,y,z)
a       b       nil
> x,y = foo2(), "hello"   -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
> print(x,y)
a       hello
> x,y = foo0(), "hello", "nihao"
> print(x,y)
nil     hello
> t = {foo0(), foo2(), 4}  -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
> print(t)
table: 0x9515c0
> for i = 1,#t do
>> print(t[i])
>> i = i+1
>> end
nil
a
4
> t = {foo0(), foo2()}
> for i = 1,#t do     
print(t[i])
i = i+1
end
nil
a
b
> print(foo2(),1)   -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
a       1
> print(foo2())
a       b





张至顺道长 - 炁体源流,八部金刚功

$
0
0
张至顺道长讲解《炁体源流》完整版

八部金刚功

夜晚利用高亮手电指星的小窍门, 无需寻星镜,指星笔.

$
0
0
今天拿着手电筒接在寻星镜的目镜端当探照灯玩, 突发奇想, 是不是可以接在望远镜的目镜端呢.
于是尝试了一下, 只要手电够亮, 指星完全没有问题, 至少我打木星是一击即中的,
器材:
80eq
olight s20 Baton 高亮模式.
目镜, 开信无畸变16.8mm

信达EQ6系列赤道仪使用全攻略

RHEL 7 will allows a PCIe SSD device to act as a cache for other Block DEV.

$
0
0
红帽7将允许快速的块设备充当低速块设备的缓存. 太棒了啊.

Fast Block Devices Caching Slower Block Devices

The ability to have fast block devices act as a cache for slower block devices is introduced as a Technology Preview in Red Hat Enterprise Linux 7.0 Beta. This feature allows a PCIe SSD device to act as a cache for direct-attached storage (DAS) or storage area network (SAN) storage, which improves file system performance.

[参考]

工作太忙, 处理一些二手闲置物品

$
0
0
1. 歌德的SR225i . 一口价, 1200 RMB.
耳机+耳机包+铁三角转接头. 一口价, 1250RMB

简介
2011年11月购自淘宝, 全新国行. 工作太忙买来后没怎么使用(估计不超过100小时), 成色见图.
二大爷推荐的耳机, 确实不错, 虽然外观看起来很山寨. 声音绝对有磁性.
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 
处理一些二手物品 - 德哥@Digoal - PostgreSQL
 


2. SONY CDP-x777es
简介
2011年购自淘宝, 二手.
一口价 5500RMB 送3000VA的火牛.
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL

一直用这个变压器供电, 自己加了一个延迟启动电路, 否则启动这个变压器的时候会跳闸.
这个变压器也有近20公斤.
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 


3. PASS 1.7前级
简介
2011年购自淘宝, 全新, 广西梧州苏哥作品.
2000RMB
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 

4. 苹果magic mouse
没正式用过, 严格来说我的MAC AIR也没正式用过. 新鲜了几天, 后面就躺着积灰, 现在老婆拿去当上网本了.
260RMB
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 


5. SHARP夏普空气净化器-KC-W200SW
年会送的, 全新未拆封, 未使用. 
一口价 1599 RMB
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 
工作太忙, 处理一些二手闲置物品 - 德哥@Digoal - PostgreSQL
 


CentOS 7 lvm cache dev VS zfs VS flashcache VS bcache VS direct SSD

$
0
0
本文测试结果仅供参考, rhel 7.0的lvm cache也只是一个预览性质的特性, 从测试结果来看, 用在生产环境也尚早.

前段时间对比了Linux下ZFS和FreeBSD下ZFS的性能, 在fsync接口上存在较大的性能差异, 这个问题已经提交给zfsonlinux的开发组员. 
ZFS从功能和性能来讲, 确实是一个非常强大的文件系统, 包括块设备的管理.
Linux下如果要达到ZFS的部分功能, 需要软RAID管理, lvm, filesystem的软件组合.
RHEL 7开始, lvm针对SSD加入了类似flashcache, bcache的缓存功能. 支持writeback, writethrough模式. 
本文将介绍一下lvm cache的使用, 同时对比一下它和zfs, flashcache, bcache以及直接使用ssd的性能差别.
理论上讲lvm cache 和bcache, flashcache的writeback模式, 相比直接使用ssd性能应该差不多(但是实际测试下来lvm的cache性能很不理想, 比zfs略好, 但是有大量的读, SSD iostat利用率很高, 并且lvm的条带使用不均匀, 不如zfs). ZFS使用ZIL后, 理论性能应该和前者也差不多, 但是zfsonlinux这块有我前面提到的性能问题, 所以就另当别论了.
另一方面, lvm cache的cache是独享的, 所以一个lv cache卷只能给一个lv orig卷使用. 这点和ZFS差别较大 . 但是zfs l2arc又不支持回写, 也是个缺陷.

本文测试环境 : 
DELL R720xd
12 * 4TB SATA, 2*300G SAS(安装OS)
宝存 1.2T PCI-E SSD
CentOS 7 x64
CentOS 7 lvm cache dev VS zfs VS flashcache VS bcache VS direct SSD - 德哥@Digoal - PostgreSQL research
测试工具, dd, pg_test_fsync.
测试fsync数据块大小8KB.

宝存SSD驱动安装.

[root@localhost soft_bak]# tar -zxvf release2.6.9.tar.gz 
release2.6.9/
release2.6.9/shannon-2.6.18-274.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-358.23.2.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-279.1.1.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/uninstall
release2.6.9/shannon-2.6.32-279.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-220.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-v2.6-9.src.rpm
release2.6.9/shannon-2.6.18-92.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-131.0.15.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-8.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-238.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/install
release2.6.9/shannon-2.6.32-431.5.1.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-128.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-371.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-308.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-53.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-71.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-431.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-358.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-194.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.18-164.el5.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-358.6.2.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
release2.6.9/shannon-2.6.32-279.22.1.el6.x86_64.x86_64-v2.6-9.x86_64.rpm
[root@localhost soft_bak]# rpm -ivh release2.6.9/shannon-v2.6-9.src.rpm
Updating / installing...
   1:shannon-2.6.18-v2.6-9            ################################# [100%]
warning: user spike does not exist - using root
warning: group spike does not exist - using root
warning: user spike does not exist - using root
warning: group spike does not exist - using root
warning: user spike does not exist - using root
warning: group spike does not exist - using root

# uname -r
3.10.0-123.el7.x86_64
# yum install -y kernel-devel-3.10.0-123.el7.x86_64 rpm-build gcc make ncurses-devel

# cd ~/rpmbuild/SPECS/
[root@localhost SPECS]# ll
total 8
-rw-rw-r--. 1 root root 7183 May 21 17:10 shannon-driver.spec
[root@localhost SPECS]# rpmbuild -bb shannon-driver.spec
[root@localhost SPECS]# cd ..
[root@localhost rpmbuild]# ll
total 0
drwxr-xr-x. 3 root root 32 Jul  9 19:56 BUILD
drwxr-xr-x. 2 root root  6 Jul  9 19:56 BUILDROOT
drwxr-xr-x. 3 root root 19 Jul  9 19:56 RPMS
drwxr-xr-x. 2 root root 61 Jul  9 19:48 SOURCES
drwxr-xr-x. 2 root root 32 Jul  9 19:48 SPECS
drwxr-xr-x. 2 root root  6 Jul  9 19:50 SRPMS
[root@localhost rpmbuild]# cd RPMS
[root@localhost RPMS]# ll
total 0
drwxr-xr-x. 2 root root 67 Jul  9 19:56 x86_64
[root@localhost RPMS]# cd x86_64/
[root@localhost x86_64]# ll
total 404
-rw-r--r--. 1 root root 412100 Jul  9 19:56 shannon-3.10.0-123.el7.x86_64.x86_64-v2.6-9.x86_64.rpm
[root@localhost x86_64]# rpm -ivh shannon-3.10.0-123.el7.x86_64.x86_64-v2.6-9.x86_64.rpm

Disk /dev/dfa: 1200.0 GB, 1200000860160 bytes, 2343751680 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 65536 bytes
Disk label type: dos
Disk identifier: 0x7e462b44


PostgreSQL安装

yum -y install lrzsz sysstat e4fsprogs ntp readline-devel zlib zlib-devel openssl openssl-devel pam-devel libxml2-devel libxslt-devel python-devel tcl-devel gcc make smartmontools flex bison perl perl-devel perl-ExtUtils* OpenIPMI-tools openldap-devel
wget http://ftp.postgresql.org/pub/source/v9.3.4/postgresql-9.3.4.tar.bz2
tar -jxvf postgresql-9.3.4.tar.bz2
cd postgresql-9.3.4
./configure --prefix=/opt/pgsql9.3.4 --with-pgport=1921 --with-perl --with-tcl --with-python --with-openssl --with-pam --with-ldap --with-libxml --with-libxslt --enable-thread-safety --enable-debug --enable-cassert
gmake world && gmake install-world
ln -s /opt/pgsql9.3.4 /opt/pgsql


测试iops
1. 直接使用SSD

# mkfs.xfs -f /dev/dfa1
meta-data=/dev/dfa1              isize=256    agcount=32, agsize=6553592 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=0
data     =                       bsize=4096   blocks=209714944, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=102399, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@localhost postgresql-9.3.4]# mount -t xfs /dev/dfa1 /mnt
[root@localhost postgresql-9.3.4]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  1.5G   49G   3% /
devtmpfs                  16G     0   16G   0% /dev
tmpfs                     16G     0   16G   0% /dev/shm
tmpfs                     16G  8.9M   16G   1% /run
tmpfs                     16G     0   16G   0% /sys/fs/cgroup
/dev/sda3                497M   96M  401M  20% /boot
/dev/mapper/centos-home  173G   33M  173G   1% /home
/dev/dfa1                800G   34M  800G   1% /mnt

[root@localhost postgresql-9.3.4]# /opt/pgsql/bin/pg_test_fsync -f /mnt/1
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   56805.093 ops/sec      18 usecs/op
        fdatasync                       45160.147 ops/sec      22 usecs/op
        fsync                           45507.091 ops/sec      22 usecs/op
        fsync_writethrough                            n/a
        open_sync                       57602.016 ops/sec      17 usecs/op

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                   28568.840 ops/sec      35 usecs/op
        fdatasync                       32591.457 ops/sec      31 usecs/op
        fsync                           32736.908 ops/sec      31 usecs/op
        fsync_writethrough                            n/a
        open_sync                       29071.443 ops/sec      34 usecs/op

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write       40968.787 ops/sec      24 usecs/op
         2 *  8kB open_sync writes      28805.187 ops/sec      35 usecs/op
         4 *  4kB open_sync writes      18107.673 ops/sec      55 usecs/op
         8 *  2kB open_sync writes        834.181 ops/sec    1199 usecs/op
        16 *  1kB open_sync writes        417.767 ops/sec    2394 usecs/op

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close             35905.678 ops/sec      28 usecs/op
        write, close, fsync             35702.972 ops/sec      28 usecs/op

Non-Sync'ed 8kB writes:
        write                           314143.606 ops/sec       3 usecs/op

iostat SSD使用率59%

[root@localhost postgresql-9.3.4]# dd if=/dev/zero of=/mnt/1 obs=4K oflag=sync,nonblock,noatime,nocache count=1024000
1024000+0 records in
128000+0 records out
524288000 bytes (524 MB) copied, 6.95128 s, 75.4 MB/s

iostat SSD使用率27.60

2. 使用lvm cache

# umount /mnt

清除设备信息(注意, 将丢失数据)

# dd if=/dev/urandom bs=512 count=64 of=/dev/dfa
# dd if=/dev/urandom bs=512 count=64 of=/dev/sdb
...
# dd if=/dev/urandom bs=512 count=64 of=/dev/sdm

创建pv

# pvcreate /dev/sdb
...
# pvcreate /dev/sdm

注意, 创建dfa的pv时报错, 跟踪后发现是需要修改lvm.conf

[root@localhost ~]# pvcreate /dev/dfa
  Physical volume /dev/dfa not found
  Device /dev/dfa not found (or ignored by filtering).

[root@localhost ~]# pvcreate -vvvv /dev/dfa 2>&1|less
#filters/filter-type.c:27         /dev/dfa: Skipping: Unrecognised LVM device type 252

[root@localhost ~]# ll /dev/dfa
brw-rw----. 1 root disk 252, 0 Jul  9 21:19 /dev/dfa

[root@localhost ~]# ll /dev/sdb
brw-rw----. 1 root disk 8, 16 Jul  9 21:03 /dev/sdb

[root@localhost ~]# cat /proc/devices 
Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
 13 input
 21 sg
 29 fb
128 ptm
136 pts
162 raw
180 usb
188 ttyUSB
189 usb_device
202 cpu/msr
203 cpu/cpuid
226 drm
245 shannon_ctrl_cdev
246 ipmidev
247 ptp
248 pps
249 megaraid_sas_ioctl
250 hidraw
251 usbmon
252 bsg
253 watchdog
254 rtc

Block devices:
259 blkext
  8 sd
  9 md
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
252 shannon
253 device-mapper
254 mdp


修改/etc/lvm/lvm.conf, 添加宝存的type

[root@localhost ~]# vi /etc/lvm/lvm.conf
    # types = [ "fd", 16 ]
    types = [ "shannon", 252 ]

可以创建pv了.

[root@localhost ~]# pvcreate /dev/dfa
  Physical volume "/dev/dfa" successfully created


创建新的vg

[root@localhost ~]# pvs
  PV         VG     Fmt  Attr PSize   PFree
  /dev/dfa          lvm2 a--    1.09t 1.09t
  /dev/sda5  centos lvm2 a--  238.38g    0 
  /dev/sdb          lvm2 a--    3.64t 3.64t
  /dev/sdc          lvm2 a--    3.64t 3.64t
  /dev/sdd          lvm2 a--    3.64t 3.64t
  /dev/sde          lvm2 a--    3.64t 3.64t
  /dev/sdf          lvm2 a--    3.64t 3.64t
  /dev/sdg          lvm2 a--    3.64t 3.64t
  /dev/sdh          lvm2 a--    3.64t 3.64t
  /dev/sdi          lvm2 a--    3.64t 3.64t
  /dev/sdj          lvm2 a--    3.64t 3.64t
  /dev/sdk          lvm2 a--    3.64t 3.64t
  /dev/sdl          lvm2 a--    3.64t 3.64t
  /dev/sdm          lvm2 a--    3.64t 3.64t


创建机械盘和SSD盘2个VG

[root@localhost ~]# vgcreate vgdata01 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj /dev/sdk /dev/sdl /dev/sdm
  Volume group "vgdata01" successfully created
[root@localhost ~]# vgcreate vgdata02 /dev/dfa
  Volume group "vgdata02" successfully created


在机械盘的vg上创建lv

[root@localhost ~]# lvcreate -L 100G -i 12 -n lv01 vgdata01
  Using default stripesize 64.00 KiB
  Rounding size (25600 extents) up to stripe boundary size (25608 extents).
  Logical volume "lv01" created
[root@localhost ~]# lvs
  LV   VG       Attr       LSize   Pool Origin Data%  Move Log Cpy%Sync Convert
  home centos   -wi-ao---- 172.69g                                             
  root centos   -wi-ao----  50.00g                                             
  swap centos   -wi-ao----  15.70g                                             
  lv01 vgdata01 -wi-a----- 100.03g 

在SSD VG上创建cache data和cache meta lv.

[root@localhost ~]# lvcreate -L 100G -n lv_cdata vgdata02
  Logical volume "lv_cdata" created
[root@localhost ~]# lvcreate -L 100M -n lv_cmeta vgdata02
  Logical volume "lv_cmeta" created

将cache data和cache meta lv转换成cache pool

[root@localhost ~]# lvconvert --type cache-pool --poolmetadata vgdata02/lv_cmeta vgdata02/lv_cdata
  Logical volume "lvol0" created
  Converted vgdata02/lv_cdata to cache pool.
[root@localhost ~]# lvs
  LV       VG       Attr       LSize   Pool Origin Data%  Move Log Cpy%Sync Convert
  home     centos   -wi-ao---- 172.69g                                             
  root     centos   -wi-ao----  50.00g                                             
  swap     centos   -wi-ao----  15.70g                                             
  lv01     vgdata01 -wi-a----- 100.03g                                             
  lv_cdata vgdata02 Cwi-a-C--- 100.00g 

将机械盘LV转换成CACHE lv.

[root@localhost ~]# lvconvert --type cache --cachepool vgdata02/lv_cdata vgdata01/lv01
  Unable to find cache pool LV, vgdata02/lv_cdata

报错, 目前不支持跨VG创建cache lv.
本地VG则支持.

[root@localhost ~]# lvcreate -L 100G -n lv01 vgdata02
  Logical volume "lv01" created
[root@localhost ~]# lvconvert --type cache --cachepool vgdata02/lv_cdata vgdata02/lv01
  vgdata02/lv01 is now cached.


所以需要调整一下, 把ssd加入vgdata01, 同时创建lvm条带时需要制定一下块设备.

[root@localhost ~]# lvremove /dev/mapper/vgdata02-lv01
Do you really want to remove active logical volume lv01? [y/n]: y
  Logical volume "lv01" successfully removed
[root@localhost ~]# lvremove /dev/mapper/vgdata01-lv01 
Do you really want to remove active logical volume lv01? [y/n]: y
  Logical volume "lv01" successfully removed
[root@localhost ~]# lvchange -a y vgdata02/lv_cdata
[root@localhost ~]# lvremove /dev/mapper/vgdata02-lv_cdata
Do you really want to remove active logical volume lv_cdata? [y/n]: y
  Logical volume "lv_cdata" successfully removed
[root@localhost ~]# vgremove vgdata02
  Volume group "vgdata02" successfully removed

扩展vgdata01

[root@localhost ~]# vgextend vgdata01 /dev/dfa
  Volume group "vgdata01" successfully extended


创建条带lvm, 同时指定机械盘(指定4K大小的条带).

[root@localhost ~]# lvcreate -L 100G -i 12 -I4 -n lv01 vgdata01 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj /dev/sdk /dev/sdl /dev/sdm
  Rounding size (25600 extents) up to stripe boundary size (25608 extents).
  Logical volume "lv01" created

创建cache lvm , 指定SSD.

[root@localhost ~]# lvcreate -L 100G -n lv_cdata vgdata01 /dev/dfa
  Logical volume "lv_cdata" created
[root@localhost ~]# lvcreate -L 100M -n lv_cmeta vgdata01 /dev/dfa
  Logical volume "lv_cmeta" created

转换cache lv

[root@localhost ~]# lvconvert --type cache-pool --poolmetadata vgdata01/lv_cmeta --cachemode writeback vgdata01/lv_cdata
  Logical volume "lvol0" created
  Converted vgdata01/lv_cdata to cache pool.
[root@localhost ~]# lvconvert --type cache --cachepool vgdata01/lv_cdata vgdata01/lv01
  vgdata01/lv01 is now cached.
[root@localhost ~]# lvs
  LV       VG       Attr       LSize   Pool     Origin       Data%  Move Log Cpy%Sync Convert
  home     centos   -wi-ao---- 172.69g                                                       
  root     centos   -wi-ao----  50.00g                                                       
  swap     centos   -wi-ao----  15.70g                                                       
  lv01     vgdata01 Cwi-a-C--- 100.03g lv_cdata [lv01_corig]                                 
  lv_cdata vgdata01 Cwi-a-C--- 100.00g  

在合并后的lv01上创建文件系统.

[root@localhost ~]# mkfs.xfs /dev/mapper/vgdata01-lv01
meta-data=/dev/mapper/vgdata01-lv01 isize=256    agcount=16, agsize=1638912 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=0
data     =                       bsize=4096   blocks=26222592, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=12804, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@localhost ~]# mount /dev/mapper/vgdata01-lv01 /mnt
[root@localhost ~]# df -h
Filesystem                 Size  Used Avail Use% Mounted on
/dev/mapper/vgdata01-lv01  100G   33M  100G   1% /mnt

[root@localhost ~]# /opt/pgsql/bin/pg_test_fsync -f /mnt/1
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                    8124.408 ops/sec     123 usecs/op
        fdatasync                        8178.149 ops/sec     122 usecs/op
        fsync                            8113.938 ops/sec     123 usecs/op
        fsync_writethrough                            n/a
        open_sync                        8300.755 ops/sec     120 usecs/op

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                    4178.896 ops/sec     239 usecs/op
        fdatasync                        6963.270 ops/sec     144 usecs/op
        fsync                            6930.345 ops/sec     144 usecs/op
        fsync_writethrough                            n/a
        open_sync                        4205.576 ops/sec     238 usecs/op

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write        7062.249 ops/sec     142 usecs/op
         2 *  8kB open_sync writes       4229.181 ops/sec     236 usecs/op
         4 *  4kB open_sync writes       2281.264 ops/sec     438 usecs/op
         8 *  2kB open_sync writes        583.685 ops/sec    1713 usecs/op
        16 *  1kB open_sync writes        285.534 ops/sec    3502 usecs/op

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close              7494.674 ops/sec     133 usecs/op
        write, close, fsync              7481.698 ops/sec     134 usecs/op

Non-Sync'ed 8kB writes:
        write                           307025.095 ops/sec       3 usecs/op

iostat SSD 使用率55%

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
dfa               0.00     0.00  878.00 15828.00 56192.00 63312.00    14.31     0.63    0.04    0.51    0.01   0.03  52.80
sdc               0.00   288.00    0.00 8350.00     0.00  4664.00     1.12     0.14    0.02    0.00    0.02   0.02  14.00
sdb               0.00   288.00    0.00 8350.00     0.00  4664.00     1.12     0.12    0.01    0.00    0.01   0.01  11.90
sdd               0.00   288.00    0.00 8350.00     0.00  4664.00     1.12     0.12    0.01    0.00    0.01   0.01  11.90
sdh               0.00   299.00    0.00 8350.00     0.00  4708.00     1.13     0.14    0.02    0.00    0.02   0.02  14.10
sdf               0.00   299.00    0.00 8350.00     0.00  4708.00     1.13     0.12    0.01    0.00    0.01   0.01  11.40
sdi               0.00   299.00    0.00 8350.00     0.00  4708.00     1.13     0.15    0.02    0.00    0.02   0.02  14.30
sdg               0.00   299.00    0.00 8350.00     0.00  4708.00     1.13     0.14    0.02    0.00    0.02   0.02  13.30
sde               0.00   288.00    0.00 8350.00     0.00  4664.00     1.12     0.12    0.01    0.00    0.01   0.01  12.00
sdl               0.00   291.00    0.00 8350.00     0.00  4676.00     1.12     0.14    0.02    0.00    0.02   0.02  14.00
sdk               0.00   291.00    0.00 8352.00     0.00  4676.00     1.12     0.14    0.02    0.00    0.02   0.02  13.60
sdm               0.00   291.00    0.00 8352.00     0.00  4676.00     1.12     0.14    0.02    0.00    0.02   0.02  13.60
sdj               0.00   291.00    0.00 8352.00     0.00  4676.00     1.12     0.14    0.02    0.00    0.02   0.02  14.10

[root@localhost ~]# dd if=/dev/zero of=/mnt/1 obs=4K oflag=sync,nonblock,noatime,nocache count=1024000
1024000+0 records in
128000+0 records out
524288000 bytes (524 MB) copied, 90.1487 s, 5.8 MB/s


直接使用机械盘条带的测试结果 (指定4KiB条带大小)

[root@localhost ~]# lvcreate -L 100G -i 12 -I4 -n lv02 vgdata01 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj /dev/sdk /dev/sdl /dev/sdm
[root@localhost ~]# mkfs.xfs /dev/mapper/vgdata01-lv02
meta-data=/dev/mapper/vgdata01-lv02 isize=256    agcount=16, agsize=1638911 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0
data     =                       bsize=4096   blocks=26222576, imaxpct=25
         =                       sunit=1      swidth=12 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=12803, version=2
         =                       sectsz=512   sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount /dev/mapper/vgdata01-lv02 /mnt
[root@localhost ~]# /opt/pgsql/bin/pg_test_fsync -f /mnt/1
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                    5724.374 ops/sec     175 usecs/op
        fdatasync                        5143.975 ops/sec     194 usecs/op
        fsync                            5248.552 ops/sec     191 usecs/op
        fsync_writethrough                            n/a
        open_sync                        5636.435 ops/sec     177 usecs/op

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                    2763.554 ops/sec     362 usecs/op
        fdatasync                        4121.941 ops/sec     243 usecs/op
        fsync                            4060.660 ops/sec     246 usecs/op
        fsync_writethrough                            n/a
        open_sync                        2701.105 ops/sec     370 usecs/op

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write        5019.091 ops/sec     199 usecs/op
         2 *  8kB open_sync writes       3055.081 ops/sec     327 usecs/op
         4 *  4kB open_sync writes       1715.343 ops/sec     583 usecs/op
         8 *  2kB open_sync writes        786.708 ops/sec    1271 usecs/op
        16 *  1kB open_sync writes        469.455 ops/sec    2130 usecs/op

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close              4490.716 ops/sec     223 usecs/op
        write, close, fsync              4566.385 ops/sec     219 usecs/op

Non-Sync'ed 8kB writes:
        write                           294268.753 ops/sec       3 usecs/op


条带利用率显然没有ZFS使用均匀.

sdc               0.00     0.00    0.00 14413.00     0.00 28988.00     4.02     0.40    0.03    0.00    0.03   0.03  39.90
sdb               0.00     0.00    0.00 14413.00     0.00 28988.00     4.02     0.39    0.03    0.00    0.03   0.03  38.90
sdd               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   0.90
sdh               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   0.90
sdf               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   1.40
sdi               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   0.70
sdg               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.02    0.00    0.00    0.00   0.00   1.90
sde               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   0.90
sdl               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.02    0.00    0.00    0.00   0.00   2.00
sdk               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   1.40
sdm               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.02    0.00    0.00    0.00   0.00   1.70
sdj               0.00     0.00    0.00 7248.00     0.00   328.00     0.09     0.01    0.00    0.00    0.00   0.00   1.00


删除设备

# umount /mnt
[root@localhost ~]# lvremove vgdata01/lv_cdata
  Flushing cache for lv01
  970 blocks must still be flushed.
  0 blocks must still be flushed.
Do you really want to remove active logical volume lv_cdata? [y/n]: y
  Logical volume "lv_cdata" successfully removed
[root@localhost ~]# lvremove vgdata01/lv01
Do you really want to remove active logical volume lv01? [y/n]: y
  Logical volume "lv01" successfully removed
[root@localhost ~]# lvremove vgdata01/lv02
Do you really want to remove active logical volume lv02? [y/n]: y
  Logical volume "lv02" successfully removed
[root@localhost ~]# pvremove /dev/dfa
  PV /dev/dfa belongs to Volume Group vgdata01 so please use vgreduce first.
  (If you are certain you need pvremove, then confirm by using --force twice.)
[root@localhost ~]# vgremove vgdata01
  Volume group "vgdata01" successfully removed
[root@localhost ~]# pvremove /dev/dfa
  Labels on physical volume "/dev/dfa" successfully wiped
[root@localhost ~]# pvremove /dev/sdb
  Labels on physical volume "/dev/sdb" successfully wiped
[root@localhost ~]# pvremove /dev/sdc
  Labels on physical volume "/dev/sdc" successfully wiped
[root@localhost ~]# pvremove /dev/sdd
  Labels on physical volume "/dev/sdd" successfully wiped
[root@localhost ~]# pvremove /dev/sde
  Labels on physical volume "/dev/sde" successfully wiped
[root@localhost ~]# pvremove /dev/sdf
  Labels on physical volume "/dev/sdf" successfully wiped
[root@localhost ~]# pvremove /dev/sdg
  Labels on physical volume "/dev/sdg" successfully wiped
[root@localhost ~]# pvremove /dev/sdh
  Labels on physical volume "/dev/sdh" successfully wiped
[root@localhost ~]# pvremove /dev/sdi
  Labels on physical volume "/dev/sdi" successfully wiped
[root@localhost ~]# pvremove /dev/sdj
  Labels on physical volume "/dev/sdj" successfully wiped
[root@localhost ~]# pvremove /dev/sdk
  Labels on physical volume "/dev/sdk" successfully wiped
[root@localhost ~]# pvremove /dev/sdl
  Labels on physical volume "/dev/sdl" successfully wiped
[root@localhost ~]# pvremove /dev/sdm
  Labels on physical volume "/dev/sdm" successfully wiped
[root@localhost ~]# pvs
  PV         VG     Fmt  Attr PSize   PFree
  /dev/sda5  centos lvm2 a--  238.38g    0 


以下测试可参照, 其中flashcache性能损失极少(甚至比直接使用SSD性能更高).
zfs和lvm性能差不多, lvm略高, 但是LVM的fsync带来了大量的cache设备的读操作, 使得ssd的util比zfs高很多, 相当于浪费了较多的io. 不知原因, ZFSonLinux 则没有这个问题.
3. 使用flashcache
4. 使用bcache
5. 使用zfs

# yum install -y libtoolize autoconf automake
# tar -zxvf spl-0.6.3.tar.gz 
# tar -zxvf zfs-0.6.3.tar.gz
# cd spl-0.6.3
# ./autogen.sh 
# ./configure --prefix=/opt/spl0.6.3
# make && make install

[root@localhost spl-0.6.3]# cd ..
[root@localhost soft_bak]# cd zfs-0.6.3
[root@localhost zfs-0.6.3]# yum install -y libuuid-devel
[root@localhost zfs-0.6.3]# ./configure --prefix=/opt/zfs0.6.3
[root@localhost zfs-0.6.3]# make && make install

[root@localhost ~]# modprobe splat
[root@localhost ~]# /opt/spl0.6.3/sbin/splat -a
------------------------------ Running SPLAT Tests ------------------------------
                kmem:kmem_alloc           Pass  
                kmem:kmem_zalloc          Pass  
                kmem:vmem_alloc           Pass  
                kmem:vmem_zalloc          Pass  
                kmem:slab_small           Pass  
                kmem:slab_large           Pass  
                kmem:slab_align           Pass  
                kmem:slab_reap            Pass  
                kmem:slab_age             Pass  
                kmem:slab_lock            Pass  
                kmem:vmem_size            Pass  
                kmem:slab_reclaim         Pass  
               taskq:single               Pass  
               taskq:multiple             Pass  
               taskq:system               Pass  
               taskq:wait                 Pass  
               taskq:order                Pass  
               taskq:front                Pass  
               taskq:recurse              Pass  
               taskq:contention           Pass  
               taskq:delay                Pass  
               taskq:cancel               Pass  
                krng:freq                 Pass  
               mutex:tryenter             Pass  
               mutex:race                 Pass  
               mutex:owned                Pass  
               mutex:owner                Pass  
             condvar:signal1              Pass  
             condvar:broadcast1           Pass  
             condvar:signal2              Pass  
             condvar:broadcast2           Pass  
             condvar:timeout              Pass  
              thread:create               Pass  
              thread:exit                 Pass  
              thread:tsd                  Pass  
              rwlock:N-rd/1-wr            Pass  
              rwlock:0-rd/N-wr            Pass  
              rwlock:held                 Pass  
              rwlock:tryenter             Pass  
              rwlock:rw_downgrade         Pass  
              rwlock:rw_tryupgrade        Pass  
                time:time1                Pass  
                time:time2                Pass  
               vnode:vn_open              Pass  
               vnode:vn_openat            Pass  
               vnode:vn_rdwr              Pass  
               vnode:vn_rename            Pass  
               vnode:vn_getattr           Pass  
               vnode:vn_sync              Pass  
                kobj:open                 Pass  
                kobj:size/read            Pass  
              atomic:64-bit               Pass  
                list:create/destroy       Pass  
                list:ins/rm head          Pass  
                list:ins/rm tail          Pass  
                list:insert_after         Pass  
                list:insert_before        Pass  
                list:remove               Pass  
                list:active               Pass  
             generic:ddi_strtoul          Pass  
             generic:ddi_strtol           Pass  
             generic:ddi_strtoull         Pass  
             generic:ddi_strtoll          Pass  
             generic:udivdi3              Pass  
             generic:divdi3               Pass  
                cred:cred                 Pass  
                cred:kcred                Pass  
                cred:groupmember          Pass  
                zlib:compress/uncompress  Pass  
               linux:shrink_dcache        Pass  
               linux:shrink_icache        Pass  
               linux:shrinker             Pass  

[root@localhost zfs-0.6.3]# /opt/zfs0.6.3/sbin/zpool create -f -o ashift=12 zp1 sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm
[root@localhost zfs-0.6.3]# export PATH=/opt/zfs0.6.3/sbin:$PATH
[root@localhost zfs-0.6.3]# zpool status
  pool: zp1
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        zp1         ONLINE       0     0     0
          sdb       ONLINE       0     0     0
          sdc       ONLINE       0     0     0
          sdd       ONLINE       0     0     0
          sde       ONLINE       0     0     0
          sdf       ONLINE       0     0     0
          sdg       ONLINE       0     0     0
          sdh       ONLINE       0     0     0
          sdi       ONLINE       0     0     0
          sdj       ONLINE       0     0     0
          sdk       ONLINE       0     0     0
          sdl       ONLINE       0     0     0
          sdm       ONLINE       0     0     0

[root@localhost zfs-0.6.3]# fdisk -c -u /dev/dfa
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x2dd27e66.

The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-2343751679, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-2343751679, default 2343751679): +16777216    
Partition 1 of type Linux and of size 8 GiB is set

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (2-4, default 2): 
First sector (16779265-2343751679, default 16781312): 
Using default value 16781312
Last sector, +sectors or +size{K,M,G} (16781312-2343751679, default 2343751679): +209715200
Partition 2 of type Linux and of size 100 GiB is set

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

添加zil
[root@localhost zfs-0.6.3]# zpool add zp1 log /dev/dfa1

[root@localhost zfs-0.6.3]# zpool status
  pool: zp1
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        zp1         ONLINE       0     0     0
          sdb       ONLINE       0     0     0
          sdc       ONLINE       0     0     0
          sdd       ONLINE       0     0     0
          sde       ONLINE       0     0     0
          sdf       ONLINE       0     0     0
          sdg       ONLINE       0     0     0
          sdh       ONLINE       0     0     0
          sdi       ONLINE       0     0     0
          sdj       ONLINE       0     0     0
          sdk       ONLINE       0     0     0
          sdl       ONLINE       0     0     0
          sdm       ONLINE       0     0     0
        logs
          dfa1      ONLINE       0     0     0

新增zfs
[root@localhost zfs-0.6.3]# zfs create -o atime=off -o mountpoint=/data01 zp1/data01
[root@localhost zfs-0.6.3]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  1.7G   49G   4% /
devtmpfs                  16G     0   16G   0% /dev
tmpfs                     16G     0   16G   0% /dev/shm
tmpfs                     16G  8.9M   16G   1% /run
tmpfs                     16G     0   16G   0% /sys/fs/cgroup
/dev/mapper/centos-home  173G   33M  173G   1% /home
/dev/sda3                497M   96M  401M  20% /boot
zp1                       43T  128K   43T   1% /zp1
zp1/data01                43T  128K   43T   1% /data01

测试
[root@localhost zfs-0.6.3]# /opt/pgsql/bin/pg_test_fsync -f /data01/1
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                                n/a*
        fdatasync                        6107.726 ops/sec     164 usecs/op
        fsync                            7016.477 ops/sec     143 usecs/op
        fsync_writethrough                            n/a
        open_sync                                    n/a*
* This file system and its mount options do not support direct
I/O, e.g. ext4 in journaled mode.

Compare file sync methods using two 8kB writes:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                                n/a*
        fdatasync                        5602.343 ops/sec     178 usecs/op
        fsync                            8100.693 ops/sec     123 usecs/op
        fsync_writethrough                            n/a
        open_sync                                    n/a*
* This file system and its mount options do not support direct
I/O, e.g. ext4 in journaled mode.

Compare open_sync with different write sizes:
(This is designed to compare the cost of writing 16kB
in different write open_sync sizes.)
         1 * 16kB open_sync write                    n/a*
         2 *  8kB open_sync writes                   n/a*
         4 *  4kB open_sync writes                   n/a*
         8 *  2kB open_sync writes                   n/a*
        16 *  1kB open_sync writes                   n/a*

Test if fsync on non-write file descriptor is honored:
(If the times are similar, fsync() can sync data written
on a different descriptor.)
        write, fsync, close              6521.974 ops/sec     153 usecs/op
        write, close, fsync              6672.833 ops/sec     150 usecs/op

Non-Sync'ed 8kB writes:
        write                           82646.970 ops/sec      12 usecs/op

[root@localhost zfs-0.6.3]# dd if=/dev/zero of=/data01/1 obs=4K oflag=sync,nonblock,noatime,nocache count=1024000
1024000+0 records in
128000+0 records out
524288000 bytes (524 MB) copied, 12.9542 s, 40.5 MB/s

zfs直接使用机械盘测试, IOPS分布非常均匀.

[root@localhost ~]# zpool remove zp1 /dev/dfa1
[root@localhost ~]# /opt/pgsql/bin/pg_test_fsync -f /data01/1
5 seconds per test
O_DIRECT supported on this platform for open_datasync and open_sync.

Compare file sync methods using one 8kB write:
(in wal_sync_method preference order, except fdatasync
is Linux's default)
        open_datasync                                n/a*
        fdatasync                        8086.756 ops/sec     124 usecs/op
        fsync                            7312.509 ops/sec     137 usecs/op

sdc               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.03    0.00    0.03   0.03   3.50
sdb               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.03    0.03    0.00    0.03   0.03   3.10
sdd               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.03    0.00    0.03   0.03   3.50
sdh               0.00     0.00    0.00 1092.00     0.00 10920.00    20.00     0.04    0.04    0.00    0.04   0.04   4.20
sdf               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.04    0.00    0.04   0.03   3.70
sdi               0.00     0.00    0.00 1092.00     0.00 10920.00    20.00     0.03    0.03    0.00    0.03   0.03   3.10
sdg               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.03    0.03    0.00    0.03   0.03   2.90
sde               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.03    0.00    0.03   0.03   3.60
sdl               0.00     0.00    0.00 1092.00     0.00 10920.00    20.00     0.02    0.02    0.00    0.02   0.02   2.10
sdk               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.03    0.00    0.03   0.03   3.70
sdm               0.00     0.00    0.00 1092.00     0.00 10920.00    20.00     0.03    0.03    0.00    0.03   0.03   3.00
sdj               0.00     0.00    0.00 1094.00     0.00 10940.00    20.00     0.04    0.04    0.00    0.04   0.04   3.90


[参考] Flag Counter
Viewing all 253 articles
Browse latest View live