Google Chrome 要藉由拆開 HTTP Cache 提昇隱私

在「Prepare For Fewer Cache Hits As Chrome Partitions Their HTTP Cache」這邊看到的,Google Chrome 打算要拆開 HTTP Cache 以提昇安全性與隱私性。

有 cache 跟沒有 cache 可以從讀取時間猜測出來,這樣就可以知道瀏覽器是否有這個特定 url 的 cache。

在原文的作者所給的例子沒有這麼明顯,這邊舉個實際一點的例子來說好了... 我想要知道你有沒有看過 zonble 的「返校」這篇文章,我就拿這篇文章裡面特有的資源來判斷。

以這篇文章來說,我可以選擇第一張圖片的網址 https://i0.wp.com/c1.staticflickr.com/1/603/31746363443_3c4f33ab18_n.jpg?resize=320%2C200&ssl=1 這個 url 來判斷讀取時間,藉此我就可以反推你有沒有看過這篇文章,達到攻擊隱私的效果。

解決的方法就是作者文章裡所提到的方法,把 HTTP cache 依照不同的網站而分開 (在 Safari 已經支援這個功能,而 Firefox 正在研究中)。

當然這樣做應該會對流量有些影響,但考慮到這些日子有很多新技術可以增加下載速度,這個功能應該是還能做...

在 SQL 裡面避免大量刪除資料的方式

看到 Percona 的「An Overview of Sharding in PostgreSQL and How it Relates to MongoDB’s」這篇,雖然是在講 PostgreSQL 上的 sharding (以及 partition),突然想到好像沒寫過要怎麼避免大量刪除資料的操作...

一個常見的情境是,想要讓某個表格只保留這一個月的資料,所以每個月開頭都會跑一隻 cron job 負責刪掉上個月的資料,像是 DELETE FROM xxx WHERE timestamp < yyy; 這樣的指令。

這個方式無論是在 PostgreSQL 或是 MySQL 都需要很多時間與 I/O 資源,而透過 partition 將不同時間區段切開到不同的表格,再用 TRUNCATE 直接清空表格剛好可以解這樣的問題。

Percona 的文章裡說了一些 PostgreSQL 的歷史與目前的進展。

在 PostgreSQL 9 或更早以前的版本,一個常見的作法是透過 table inheritance 實做 partition,然後用再用 function 實做 INSERT

CREATE TABLE temperature (
  id BIGSERIAL PRIMARY KEY NOT NULL,
  city_id INT NOT NULL,
  timestamp TIMESTAMP NOT NULL,
  temp DECIMAL(5,2) NOT NULL
);

CREATE TABLE temperature_201901 (CHECK (timestamp >= DATE '2019-01-01' AND timestamp <= DATE '2019-01-31')) INHERITS (temperature);
CREATE TABLE temperature_201902 (CHECK (timestamp >= DATE '2019-02-01' AND timestamp <= DATE '2019-02-28')) INHERITS (temperature);
CREATE TABLE temperature_201903 (CHECK (timestamp >= DATE '2019-03-01' AND timestamp <= DATE '2019-03-31')) INHERITS (temperature);

CREATE OR REPLACE FUNCTION temperature_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.timestamp >= DATE '2019-01-01' AND NEW.timestamp <= DATE '2019-01-31' ) THEN INSERT INTO temperature_201901 VALUES (NEW.*);
    ELSIF ( NEW.timestamp >= DATE '2019-02-01' AND NEW.timestamp <= DATE '2019-02-28' ) THEN INSERT INTO temperature_201902 VALUES (NEW.*);
    ELSIF ( NEW.timestamp >= DATE '2019-03-01' AND NEW.timestamp <= DATE '2019-03-31' ) THEN INSERT INTO temperature_201903 VALUES (NEW.*);
    ELSE RAISE EXCEPTION 'Date out of range!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

在 PostgreSQL 10 之後,就直接支援一些與 partition 相關的設計,像是這樣:

CREATE TABLE temperature (
  id BIGSERIAL NOT NULL,
  city_id INT NOT NULL,
  timestamp TIMESTAMP NOT NULL,
  temp DECIMAL(5,2) NOT NULL
) PARTITION BY RANGE (timestamp);

CREATE TABLE temperature_201901 PARTITION OF temperature FOR VALUES FROM ('2019-01-01') TO ('2019-02-01');
CREATE TABLE temperature_201902 PARTITION OF temperature FOR VALUES FROM ('2019-02-01') TO ('2019-03-01');
CREATE TABLE temperature_201903 PARTITION OF temperature FOR VALUES FROM ('2019-03-01') TO ('2019-04-01');

雖然還是有些限制,但可以看出比起以前簡單不少。

而有了 partition 後,文章的後續就在討論這跟 MongoDB 的 sharding 有什麼關係,但這就不是我關注的事情了...

大型 WordPress 站台會用到的 LudicrousDB (以及 HyperDB)

最近收到 HyperDB 的 mailing list 信件 (開頭是「[HyperDB] How can I set up HyperDB with latest version.」這封),有人提到 HyperDB 很久沒更新了... 結果在信理看到有人回了「stuttter/ludicrousdb」這個專案:

LudicrousDB is an advanced database interface for WordPress that supports replication, failover, load balancing, & partitioning

兩個專案都是抽換掉 WordPress 在處理 database 的 library,然後希望自己控制 master/slave 的讀寫分離以及各機房之間的處理 (還有 replication lag),而不要靠 ProxySQL 這類工具來做 (以時間來看,當初他們發展這些工具時,ProxySQL 這類的方案也還不夠成熟,大家都不會想要選這個方向...)。

先記錄下來,如果之後有遇到時可以當作是一個選項...

Google 的 Cloud Spanner

GoogleCloud Spanner 這個服務拿出來賣了:「Introducing Cloud Spanner: a global database service for mission-critical applications」,以及說明的「Inside Cloud Spanner and the CAP Theorem」。

Cloud Spanner 的規劃上是希望有 RDBMS 的能力 (像是 ACID 特性),又有強大的擴充能力 (scalability) 與可用性 (availability):

Today, we’re excited to announce the public beta for Cloud Spanner, a globally distributed relational database service that lets customers have their cake and eat it too: ACID transactions and SQL semantics, without giving up horizontal scaling and high availability.

在說明裡有提到 Cloud Spanner 是做到 CAP theorem 裡面的 CP:

The purist answer is “no” because partitions can happen and in fact have happened at Google, and during some partitions, Spanner chooses C and forfeits A. It is technically a CP system.

然後把 A 拉高到使用者不會在意 downtime 的程度:

However, no system provides 100% availability, so the pragmatic question is whether or not Spanner delivers availability that is so high that most users don't worry about its outages.

當然,比較讓人爭議的是 Twitter 上 Google Cloud 官方帳號的 tweet,直接講同時解決了 CAP 三個條件:

價錢不算便宜,不過對於想要找方案的人至少有選擇...

MySQL 5.7...

Oracle 的「MySQL :: MySQL 5.7 Reference Manual :: 1.4 What Is New in MySQL 5.7」列出 MySQL 5.7 預定會有的功能。由於還在發展階段,這頁還會繼續變動。

針對 ALTER TABLE 有不少改善,以下的條件下 ALTER TABLE 將不會產生 temporily table (不會卡住):

  • table 改名。
  • column 改名。
  • column 改 default value。
  • enum 或 set 在不修改原來值的情況下增加值。
  • partition 相關操作。
  • index 改名。
  • index 新增與刪除。(僅限 InnoDB)

幾個常見的操作變得更簡單了,pt-online-schema-change 的功能會慢慢被整合回 MySQL。

然後 InnoDB 要支援 spatial data types 了,不過 index 還沒支援... 不知道有沒有機會看到 :o