密碼輸入上的 UX

Hacker News 上看到「Gmail password first character is case insensitive on mobile device (support.google.com)」這篇,在講密碼輸入上的 UX。

在 Hacker News 上的討論看到這則:

This is a well-understood feature. Facebook does the same thing[0].

Quote:

Facebook actually accepts three forms of your password:

* Your original password.

* Your original password with the first letter capitalized. This is only for mobile devices, which sometimes capitalize the first character of a word.

* Your original password with the case reversed, for those with a caps lock key on.

[0]: https://www.zdnet.com/article/facebook-passwords-are-not-case-sensitive-update/

接受三種密碼,第一種是完全正確的密碼,第二種是第一個字如果是大寫時的密碼 (在行動裝置上可能的行為),第三種是大小寫全部相反的密碼,這在沒注意到 caps lock 時會發生。

強度不會削弱太多,但對於 user experience 好很多的設計。

MySQL InnoDB 的 OPTIMIZE TABLE 的 Lock

Backend Twhttps://www.facebook.com/groups/616369245163622/posts/2467225396744655/ 這邊看到:

先大概回答一下假設,DELETE 後的空間是可以被同一個表格重複使用的,所以應該是還好,不過離峰時間跑一下 OPTIMIZE TABLE 也沒什麼關係就是了。

裡面提到的「13.7.2.4 OPTIMIZE TABLE Statement」(MySQL 5.7 文件) 以及「13.7.2.4 OPTIMIZE TABLE Statement」(MySQL 5.6 文件) 都有講到目前比較新的版本都已經是 Online DDL 了:(這邊抓 5.6 的文件,有支援的版本資訊)

Prior to Mysql 5.6.17, OPTIMIZE TABLE does not use online DDL. Consequently, concurrent DML (INSERT, UPDATE, DELETE) is not permitted on a table while OPTIMIZE TABLE is running, and secondary indexes are not created as efficiently.

As of MySQL 5.6.17, OPTIMIZE TABLE uses online DDL for regular and partitioned InnoDB tables, which reduces downtime for concurrent DML operations. The table rebuild triggered by OPTIMIZE TABLE is completed in place. An exclusive table lock is only taken briefly during the prepare phase and the commit phase of the operation. During the prepare phase, metadata is updated and an intermediate table is created. During the commit phase, table metadata changes are committed.

文件上有提到會有一小段 lock 的時間,不過一般來說應該不會造成太大問題。

這邊要講的是早期的經典工具 pt-online-schema-change (pt-osc),這是使用 TRIGGER-based 的方式在跑,他的範例就直接提供了一個不需要 Online DDL 支援的版本:

Change sakila.actor to InnoDB, effectively performing OPTIMIZE TABLE in a non-blocking fashion because it is already an InnoDB table:

pt-online-schema-change --alter "ENGINE=InnoDB" D=sakila,t=actor

這在早期的時候還蠻常被拿出來用的,如果還在維護一些舊系統的話還蠻推薦的...

PostgreSQL 的 Job Queue、Application Lock 以及 Pub/Sub

Hacker News Daily 上看到一篇講 PostgreSQL 做 Job Queue、Application Lock 以及 Pub/Sub 的方法:「Do You Really Need Redis? How to Get Away with Just PostgreSQL」,對應的討論在「Do you really need Redis? How to get away with just PostgreSQL (atomicobject.com)」這邊可以翻到。

拿 PostgreSQL 跑這些東西的確有點浪費,不過如果是自己的專案,不想要把 infrastructure 搞的太複雜的話,倒是還不錯。

首先是 Job Queue 的部份,從他的範例看起來他是在做 async job queue (不用等回傳值的),這讓我想到很久前寫的 queue service (應該是 2007 年與 2012 年都寫過一次),不過我是用 MySQL 當作後端,要想辦法降低 InnoDB 的 lock 特性。

async job queue 設計起來其實很多奇怪的眉角,主要就是在怎麼處理失敗的狀態。大多數的需求可以放到兩個種類,最常見用的是 at-least-once,保證最少跑一次,大多數從設計上有設計成 idempotence 的都可以往這類丟,像是報表類的 (重複再跑一次昨天的報表是 OK 的),另外每天更新會員狀態也可以放在這邊。

另外少見一點的是 at-most-once 與 exactly-once,最多只跑一次與只跑一次,通常用在不是 idempotence 的操作上,像是扣款之類的,這邊的機制通常都會跟商業邏輯有關,反正不太好處理...

第二個是 Application Lock,跨機器時的 lock 機制,量沒有很大時拿 PostgreSQL 跑還行,再大就要另外想辦法了,馬上想到的是 ZooKeeper,但近年設計的系統應該更偏向用 etcdConsul 了...

最後提到的 Pub/Sub,一樣是在量大的時候拿 PostgreSQL 跑還行,更大的時候就要拿 Kafka 這種專門為了效能而設計出來的軟體出來用...

繞過 Screensaver Lock 的有趣話題...

Hacker News Daily 上看到「Screensaver lock by-pass via the virtual keyboard」這篇,裡面這邊題到了 screensaver lock 的有趣話題。

先講嚴肅一點的,這個 bug 被編號為 CVE-2020-25712,問題出在 xorg-x11-server 上:

A flaw was found in xorg-x11-server before 1.20.10. A heap-buffer overflow in XkbSetDeviceInfo may lead to a privilege escalation vulnerability. The highest threat from this vulnerability is to data confidentiality and integrity as well as system availability.

比較有趣的事情是,這個 bug 是小朋友在亂玩時拉出 virtual keyboard 觸發的:

A few weeks ago, my kids wanted to hack my linux desktop, so they typed and clicked everywhere, while I was standing behind them looking at them play... when the screensaver core dumped and they actually hacked their way in! wow, those little hackers...

然後他說他自己搞不出來:

I tried to recreate the crash on my own with no success, maybe because it required more than 4 little hands typing and using the mouse on the virtual keyboard.

另外一個人也說他家小朋友也弄出 segfault 了:

My kids came upon a similar cinnamon-screensaver segfault! I've emailed details of how to reproduce the problem to root@linuxmint.com.

小朋友超強 XDDD

用 flock 防止指令同時間重複執行

flock(1) 是個好用的工具,可以避免指令同時重複執行。基本的用法是:

flock /tmp/example.lock /usr/bin/example

從這邊的 /tmp/example.lock 可以看出是透過檔案系統層的鎖實做的,也因為這樣的設計,所以用在 NFS 上時,可以規劃出跨機器的鎖定機制。(不過要注意舊版的 NFSv2/NFSv3 是可以刻意不跑 lock daemon 的,這樣就爛掉了 XD)

配合 crontab 執行時,-n 也是常用的選項,用在「這次沒跑也沒關係」的東西上,通常用在是計算出來後丟到 cache 內的程式,跑比較久的時候就跳過這次...

柏林鑰匙

Daily Hacker News 上看到「Berlin key」這個東西,用機械結構就可以強迫使用者一定要鎖門的鑰匙。

門平常都是上鎖的,要解鎖要先用鑰匙打開,然後從另外一邊鎖上後才能拿出來:

是個有年代的設計,但現在在柏林還是有不少這樣的設計:

Invented by the Berliner locksmith Johannes Schweiger, the Berlin key was massively produced by the Albert Kerfin & Co company starting in 1912. With the advent of more recent locking technologies, this kind of lock and key is becoming less common. It was estimated that 8000-10000 are still in use today in Berlin, Germany.

現代則是用自動門的門禁來管制,但這個設計還是很有趣...

RDBMS 裡的各種 Lock 與 Isolation Level

來推薦其他人寫的文章 (雖然是在 Medium 上...):「複習資料庫的 Isolation Level 與圖解五個常見的 Race Conditions」、「對於 MySQL Repeatable Read Isolation 常見的三個誤解」,另外再推薦英文維基百科上的「Snapshot isolation」條目。

兩篇文章都是中文 (另外一個是英文維基百科條目),就不重複講了,這邊主要是拉條目的內容記錄起來,然後寫一些感想...

SQL-92 定義 Isolation 的時候,技術還沒有這麼成熟,所以當時在訂的時候其實是以當時的技術背景設計 Isolation,所以當技術發展起來後,發生了一些 SQL-92 的定義沒那麼好用的情況:

Unfortunately, the ANSI SQL-92 standard was written with a lock-based database in mind, and hence is rather vague when applied to MVCC systems. Berenson et al. wrote a paper in 1995 critiquing the SQL standard, and cited snapshot isolation as an example of an isolation level that did not exhibit the standard anomalies described in the ANSI SQL-92 standard, yet still had anomalous behaviour when compared with serializable transactions.

其中一個就是 Snapshot Isolation,近代的資料庫系統都用這個概念實做,但實際上又有不少差別...

另外「Jepsen: MariaDB Galera Cluster」這篇裡出現的這張也很有用,裡面描述了不同層級之間會發生的問題:

這算是當系統有一點規模時 (i.e. 不太可能使用 SERIALIZABLE 避免這類問題),開發者需要了解的資料庫限制...

Cloudflare 改善了同時下載同一個檔案的效率...

在「Live video just got more live: Introducing Concurrent Streaming Acceleration」這邊 Cloudflare 說明他們改善了同時下載同一個 cache-miss 檔案時的效率。

本來的架構在 cache-miss 時,CDN 這端會先取得 exclusive lock,然後到 origin server 抓檔案。如果這時候有其他人也要抓同一個檔案,就會先卡住,避免同時間對 origin server 產生大量連線:

這個架構在一般的情況下其實還 ok,就算是 Windows Update 這種等級的量,畢竟就是一次性的情況而已。但對於現代愈來愈普及的 HTTP(S) streaming 技術來說,因為檔案一直產生,這就會是常常遇到的問題了。

由於 lock 機制增加了不少延遲,所以在使用者端就需要多抓一些緩衝時間才能確保品質,這增加了直播的互動延遲,所以 Cloudflare 改善了這個部分,讓所有人都可以同時下載,而非等到發起的使用者下載完才能下載:

沒有太多意外的,從 Cloudflare 內部數字可以看出來這讓 lock 時間大幅下降,對於使用者來說也大幅降低了 TTFB (time to first byte):

不確定其他家的情況...

AWS 推出了 S3 Object Lock,保護資料被刪除的可能性

AWS 推出了 S3 Object Lock,可以設定條件鎖住 S3 上的 object,以保護資料不被刪除:「AWS Announces Amazon S3 Object Lock in all AWS Regions」。

這個功能跟會計做帳的概念很像,也就是寫進去後就不能改,也不能刪除,保留一定時間後才移除掉:

You can migrate workloads from existing write-once-read-many (WORM) systems into Amazon S3, and configure S3 Object Lock at the object- and bucket-levels to prevent object version deletions prior to pre-defined Retain Until Dates or Legal Hold Dates.

AWS 提供有兩種模式,一個是 Governance mode,這個模式下可以設定某些 IAM 權限可以移除 S3 Object Lock。另外一個是 Compliance mode,這個模式下連 root account 都不能刪除:

S3 Object Lock can be configured in one of two modes. When deployed in Governance mode, AWS accounts with specific IAM permissions are able to remove object locks from objects. If you require stronger immutability to comply with regulations, you can use Compliance Mode. In Compliance Mode, the protection cannot be removed by any user, including the root account.

Percona XtraDB Cluster 裡各種與 LOCK 相關的指令會產生的效果

在「FLUSH and LOCK Handling in Percona XtraDB Cluster」這邊看到在 Percona XtraDB Cluster 內各種不同形式的 LOCK 指令會有不同的效果。有些跟一開始用的印象已經不太一樣了...

FLUSH TABLE WITH READ LOCKFLUSH TABLE <tablename> (WITH READ LOCK|FOR EXPORT) 都會直接讓整個 node 卡住,但 LOCK TABLE <tablename> READ/WRITE 就只會卡對應的表格,另外 GET_LOCK 本來應該是完全不支援,現在似乎變成 experimental 的功能了 (參考「PXC Strict Mode」這邊),這樣一來 MogileFS 的資料庫部分就可以在上面跑了嗎?(當初就是因為這個問題而另外弄一組 DRBD + HeartbeatMySQL 起來跑 XD)

之後看一下什麼時候加進去的...