Percona 正式推出相容於 MongoDB 的產品「Percona Server for MongoDB」

Percona 正式推出與 MongoDB 相容的產品 Percona Server for MongoDB:「Percona Delivers Free, Open Source Percona Server for MongoDB」。

挑重點講,其實最重要的是 data engine 多了 Percona 自家的 PerconaFT 以及 FacebookRocksDB

Percona Server for MongoDB offers all the features of MongoDB 3.0 Community Edition, along with two additional storage engine options – PerconaFT and Facebook’s RocksDB

PerconaFT 是基於被併購的 Tokutek 所研發的 TokuDB (Fractal tree index) 而誕生的產品,在效能上有相當的優勢...

如果有機會的話來研究看看吧 :o

MySQL 的 Index 設計技巧

Percona 的「Indexing 101: Optimizing MySQL queries on a single table」這篇講了最基本的 index 設計技巧,雖然文章裡沒提到,但最好是需要 B-treeB+ tree 的背景知識。

MySQL 的 query 大致分成幾個階段。先決定要使用哪些 index (或是完全不用),然後透過 index 抓出符合條件資料 (或是 table scan),最後再細部過濾。

以文章裡提到的「Multiple inequalities」範例裡這樣的 SQL query 來討論:

SELECT * FROM t WHERE c > 100 and b < 10 and d = 'xyz'

如果 index 是 (d, c),需要在透過這組 index 抓出資料後再過濾 b < 10 的條件。而如果 index 是 (d, b),需要在取出資料後再過濾 c > 100 的條件。也就是 B+ tree 做不到的事情,就要另外 post-processing。

另外也有提到 covering index 對效能提昇的原理,不過這就有點屬於怪招了...

Percona 講 TokuDB

Percona 的「Getting to know TokuDB for MySQL」這篇文章雖然標題是想要宣傳 TokuDB,但其實把 MySQL 的歷史也講了一遍...

前面講到 InnoDB 的崛起時,就有提到就算你不使用 InnoDB 提供的 transaction,他的 crash-safe 性質也仍然是許多人選用 InnoDB 的重要因素之一:

Even those that don’t really need transactions rejoice in the crash resistance strength of InnoDB.

後面提到 TokuDB 時當然都會提到 Fractal Tree Indexes 這個資料結構對於現代硬體設備的優點。而英文版維基百科在今年三月時總算建立了 Fractal tree index 這個條目,整理的還算完整,之前是去看投影片了解這個資料結構的特性...

Percona 目前對 TokuDB 的等級是放在 beta 版,等 GA 後再來完整的測過一次,另外也想要測能不能在同一個 transaction 內使用 InnoDB table & TokuDB table,這對 zero-downtime migration 還蠻重要的,如果不可行的話工程就比較大了...

MySQL 5.7.4

在「The MySQL 5.7.4 Milestone Release is available」這篇可以看到 MySQL 5.7.4 的消息。除了 InnoDB 的改善外,可以看到對 AES 加密的功能 (AES Encryption Modes)。

不過...

Historically, and still used as defaults in 5.6 and 5.7, we are using a relatively small key size (128 bits, corresponding to “SECRET” according to NSA) and block mode (ECB, encrypting equal blocks with equal code blocks) to calculate the cipher.

居然是支援 ECB,這會不會驚爆我的眼球啊,我以為最少是 CTR...

ECB 代表相同內容的 block 就會被加密成相同的密文,這樣就有很多可以攻擊的方式了。而 CTR 至少可以抵抗這一點...

另外一個賣點是「InnoDB Spatial Indexes in 5.7.4 LAB release」,目前只支援二維資料:

Currently, InnoDB spatial index supports only two dimension data, but we do have plan to extend to multi-dimension. In addition, we are doing more performance tuning to make it more efficient.

R-tree 實做的,畢竟是個開始...

Percona 的 TokuDB

Percona 這幾個月對 TokuDB 的評價一直都很不錯,再加上在 Percona Server 5.6.16-64.0 裡加入對 TokuDB 的支援 (目前還是掛在 ALPHA 階段),看起來是打算再納入這個產品線?:「Percona Server 5.6.16-64.0 with TokuDB engine now available」。

與兩年前的 Percona XtraDB Cluster 情境有點像,看起來會是新的主打產品?

先花了一些查,發現「How TokuDB Fractal TreeTM Indexes Work」這份投影片整理的還不錯,說明了簡化版 fractal tree 的結構,以及為什麼可以取代 B-treeB+tree。也說明了 fractal tree 最重要的精神是拿 CPU 計算能力與 memory bandwidth 換取資料結構的特性,善用磁碟在 sequence i/o 遠比 random i/o 快的事實。

維基百科裡的「TokuDB」也寫了一些東西可以看,像是說明 fractal tree 是 cache-oblivious algorithm,這點讓 cache tuning 的複雜性降低。

這樣應該順便玩看看 Docker 或是 Vagrant 才對?

Datomic 以及 RethinkDB...

Baron Schwartz (Percona 的 Chief Performance Architect) 寫了一篇「Immutability, MVCC, and garbage collection」狂酸 DatomicRethinkDB (喔,還稍微提到 CouchDB)。

裡面提到了 append-only B-tree 這的資料結構,優點以及會遇到的問題。(而這些問題都是致命的...)

下面的 comment 就看到 Datomic 的人跑出來反擊了,不過我懶的看了... XD

RDBMS 這麼多人發展這麼久了,不太有機會有萬靈丹突然出現解決一切問題... (這表示之前的人都是笨蛋?)

新出來一個 RDBMS 系統,官網做的很漂亮,是由一個商業公司拿錢發展出來,號稱可以解決很多問題,大概都可以先跳過去... XD

用 C Macro 實作的紅黑樹...

用 C Macro 實作的紅黑樹 (Red-black tree) 很經典,不過每次都忘記怎麼用... XD

紅黑樹是平衡二元搜尋樹的一種,除了二元搜尋樹有的結構外,節點的資訊多了顏色。然後利用顏色達到平衡的特性。

先定義單一節點的資料結構:

struct element {
    char *key;

    int value1;
    char *value2;

    RB_ENTRY(element) meta;
};

紅黑樹的每個節點都需要紀錄母、左、右節點的指標,以及顏色,其中 RB_ENTRY() 所代表的資料結構會負責紀錄這些值。

再來是定義母節點的資料結構,這樣之後就可以使用 struct tree tree1;struct tree tree2;struct tree tree3; 產生許多 tree 了:

RB_HEAD(tree, element);

這樣就會產生 struct tree 這個資料結構。如果只用一次可以偷懶寫成:

RB_HEAD(tree, element) tree1;

定義完資料結構後,接著比較函數 (要如何在兩個元素之間挑出大的那個):

int element_cmp(struct element *a, struct element *b)
{
    return strcmp(a->key, b->key);
}

接著就可以產生 C 語言的 function prototype,以及實際的 function:

RB_PROTOTYPE(tree, element, meta, element_cmp);
RB_GENERATE(tree, element, meta, element_cmp);

然後程式裡面就可以這樣初始化:

struct tree tree1;
RB_INIT(&tree1);

其中 tree1 就變成之後所有操作的基礎。

增加元素:

struct element *el;
el = malloc(sizeof(struct element));
el->key = strdup("key1");
el->value1 = 1;
el->value2 = strdup("value2");
RB_INSERT(tree, &tree1, el);

如果要尋找的話可以用 RB_FIND()

el->key = "key2";
pointer = RB_FIND(tree, &tree1, el);

其他的就翻 tree.h 檔裡面類推...

Perl 的 Object::Destroyer

使用 HTML::Tree 時因為有 circular reference,會要求你要使用 ->delete() 告知 object 打斷 reference 以避免 memory leak。於是就得很小心寫,要注意每個步驟以免某些狀況下忘記 ->delete() 而造成 leak:

my $html = HTML::TreeBuilder->new_from_content($body);
foreach my $element ($html->look_down('a', qr{某個 RE 條件})) {
    if (符合某個條件) {
        # 做某些事情...

        $element->delete;
        $html->delete;
        return;
    }

    # 做某些事情...
    $element->delete;
}
$html->delete;

後來找到了 Object::Destroyer,利用另外一個 object 的存活幫忙回收,於是就可以簡化成:

my $html = HTML::TreeBuilder->new_from_content($body);
my $htmlD = Object::Destroyer->new($html, 'delete');
foreach my $element ($html->look_down('a', qr{某個 RE 條件})) {
    my $elementD = Object::Destroyer->new($element, 'delete');
    if (符合某個條件) {
        return;
    }
    # 做某些事情...
}

這樣就不會 leak 了...