2010年12月31日 星期五

自制彈性的 bash prompt + 解決問題的流程

最近開了幾個 branch 要切來切去, 每次還要下「hg branch」確認狀態, 有點麻煩。就找了一下有沒有人提供啥方案, 這種常見的痛苦, 應該早有人解掉了。結果找到 Prompt Extension, 完全符合我的需求, 官網文件很清楚, 設定也簡單。

滿足需求後想知道它怎麼做的, 關鍵在於如何每次執行 hg 指令就檢查並更新 prompt。只有用 bash 提供的 API 才能正確地更新 prompt, 其它手段應該都是無效的。翻了一下 Prompt Extension 原始碼, 發覺它並沒有 hook 掉 hg 的各個指令。於是我猜是 hg update 本來就會換 prompt, 改看 mercurial 原始碼。看了一陣子覺得不像, 於是回頭交叉比對看看, 是誰改了 prompt。

試了關掉 prompt / 打開 prompt / 不同 hg 指令, 最後發覺....... bash 每執行完一個指令就會重設 prompt 啊!! 從 Prompt Extension 學到的是, 設 PS1 時可以搭配單引號內加函式, 這樣每次更新 PS1 時, 可用函式視情況顯示不同的訊息。之前都用雙引號, 所以只有一次的效果。

換句話說, Prompt Extension 做的事是:
  • 提供設 PS1 的範例。
  • 提供一個 hg 指令來 parse 格式化字串, 藉以顯示不同的 repository 訊息。
總結此次解題的成果:
  • 判斷問題有解: 成功。
  • 背景知識: 知道只有 bash 提供 API 才有機會, 算是成功。
  • 猜測解決的大概方向: 失敗。明明有了正確的知識, 結果卻先猜 Prompt Extension 解的。
  • 第一次修正猜測方向: 失敗。一廂情願地猜到 mercurial 身上, 急著跳下去解, 卻沒先確認這個假設。
  • 回頭驗證假設: 成功。搭配背景知識, 找到正確的原因。
一開始猜的方向錯誤, 繞了一圈才找到做法。幸好我有提早回頭確認一開始的假設, 省了一些冤枉路。愈來愈熟悉「假設 -> 驗證」的樹狀解題流程, 漸漸抓到根本的解題方法, 再來就是增加經驗, 累積背景知識了。這種系統化的解題流程應該是大學時要學會的事, 結果到 26 歲才開竅, 唉呀呀。

2010年12月30日 星期四

mysql 取出最後 insert row 的 id

依官網所言, 有設 auto-increment 的情況, 在 insert 完後, 可用「SELECT LAST_INSERT_ID();」取出最後新增的 row 的 id。測試結果不同 mysql client 各自記各自的 last insert id, 不用擔心 race condition。我原本誤以為這個 function 會取出全域的結果, 結果是我多慮了。

這篇提到 Python 可用 cursor.lastrowid 取出, 不過我試了沒效。所以就自己手工多下「SELECT LAST_INSERT_ID();」取資料了。

用 sort 依兩欄數字排序

我是用 Ubuntu 8.04, 附上測的結果

$ cat in
77      1
7       11
7       3
8       2
7       1
$ sort in
7       1
7       11
7       3
77      1
8       2
$ sort -n in
7       1
7       11
7       3
8       2
77      1
$ sort -n -k1,2 in
7       1
7       11
7       3
8       2
77      1
$ sort -n -k 1,2 in
7       1
7       11
7       3
8       2
77      1
$ sort -n -k1 -k2 in
7       1
7       3
7       11
8       2
77      1

結論: 不要寫成 "sort -n -k1,2", 要寫成 "sort -n -k1 -k2", man page 明明是寫前者啊...., 我是亂試試出來的。

2010年12月26日 星期日

用 mysqladmin 觀察細部變化

大致上熟悉 explain、profiling、show processlist 等的用法, 但還不熟用 mysqladmin 觀察更細部的變化。網路上的文件提到用 mysqladmin extended -r -i10 觀察 10 秒內各細部資訊的相對變化, 但項目太多, 很難觀察。

後來想注意到可以用 grep 幫忙過濾。比方說只關心是否用到寫入硬碟的暫存表, 就加個 "grep Created_tmp_disk_tables":
mysqladmin -uUSER -pPASSWORD extended -r -i10 | grep Created_tmp_disk_tables
若不知要觀察啥 (我目前的情況...), 至少可以先去掉沒變化的項目:
mysqladmin -uUSER -pPASSWORD extended -r -i10 | grep -v "| 0   "
還在摸索怎麼用較適當。

登出其它台 Gmail / Google Account

不知道怎麼登出其它台的 Google Account, 不過登出 Gmail 有同等效果
  1. 進 Gmail
  2. 中間下方有個「Last account activity: X hours ago on this computer. Details」, 點 Details
  3. 點「Sign out all other sessions」

2010年12月24日 星期五

Scale out, HA, backup (for mysql)

前一篇經 DK 說明, 發覺我沒有細分需求和方法。混在一起寫變得很亂。

Scale out

目的:
  • 加機器就能應付成長的流量 (ref.)。
作法:
  • Replication 可以應付大量讀取、少量寫入的情況。
  • Sharding (partition) 可以應付大量寫入的情況 (各 server 應付不同段的資料)。

High availability

目的:
  • 網站能持續提供服務。
作法:
  • Master-Slave Replication: 寫入密集的情況下, Master 和 Slave 的資料有時間差,  掛掉 Master 後需要處理資料不同步的情況。
  • MMM 或 DRBD 可以確保資料同步。MMM 不需暖機, 服務中斷時間最短。 DRBD 較易設定, 但需要暖機時間。

Backup

目的: 
  • 可以找回舊資料。
作法:
  • Replication 可以做到「差不多即時」備份, 但若誤砍資料, slave 上的資料也「差不多即時」飛了。
  • 使用 replication 後, 可以在 slave 上固定間隔時間備份資料, 降低對網站效能的影響, 且不用停止服務。
  • 備份方式分為 logical 和 raw backup 兩種類型, 各有優缺點。搭配支援 snapshot 的 file system 用 raw backup, 時間和空間成本都很划算。
  • DB 本身要搭配 crash-safe 的方案 (如 MySQL + InnoDB), 確保 server 掛掉時, 資料有保持一致。
  • 針對 InnoDB 做 logical backup 的話, 用 XtraBackup 較快。
  • 一定要測 restore, 我半信半疑的測了一下, 馬上發現少備份使用者帳號的 DB ......

結論

Scale out、HA、backup 是三種不同的需求, 各自有不同的實踐手段。接下來會先:
  • 做 logical backup: 易於實作, 資料量小時沒什麼缺點。
  • 做 replication: 協助 backup 和為 scale out 讀取做準備。
  • 將 DB 操作包在自己寫的 lib 裡: 之後需要 scale out 時比較好套。
剩下的東西, 待之後有更深的需求再來細讀吧。

參考資料

2010年12月23日 星期四

PNG 教戰守則

DK 那看到的, Does PNG work everywhere?。

重點:
  • 需要全彩但不用半透明的話, 用 JPEG
  • 用 PNG8, PNG24 太大了, GIF 也比 PNG8大
  • 用最佳化工具壓 PNG: find . -name '*.png' -print0 | xargs -P4 -0 -n1 pngout
  • 看不懂半透明部份的說明, 需要時再細看吧

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...