我很高興看到我的文章〈你的可執行檔是一個 SQLite 資料庫〉引起了人們的共鳴。這是一個我思考了很久的格式,這個想法似乎也觸動了許多人。

快速回顧:SELF,一種程式碼本身就是 SQLite 資料庫的格式。我們可以利用 binfmt_misc 觸發一個自訂的解譯器,該解譯器會映射 segments 表中的列並跳轉到進入點,如此一來,一整類的二進位工具都可以被 SQL 取代。

最讓我驚訝的是,將檔案格式設為 SQLite 資料庫如何能將一切都簡化為 SQL。一個我和其他人透過評論立即想到的想法是:如果可執行檔是一個資料庫,而資料庫是可以寫入的,那麼執行中的程式是否也能用它來儲存其狀態?🤔

是的!🤯 我們不僅可以將一個完整的發行版,還可以將每個應用程式的所有狀態都整合到單一檔案中,從而無需 /var/、/tmp/、/home/ 或任何其他檔案系統。程式可以將其自身狀態儲存在它正在執行的同一個檔案中,並且可以以交易的方式進行。

self-httpd 是一個執行此操作的概念驗證網頁伺服器。它是一個從資料庫執行的單一檔案程式。該檔案包含程式碼、網站、路由以及所有訪客記錄。所有狀態都在與程式碼相同的 SQLite 檔案中更新。

這個網頁伺服器已上線:https://selfdb.exe.xyz。1 1 如果網站無法正常運作,我很抱歉。我部署在他們最小的方案上。我附上了網站的螢幕截圖以供後人參考!它是一個檔案,一個 SQLite 資料庫,同時也是伺服器。它是網站,它是程式,也是訪客記錄和狀態。

我非常欽佩 Justine Tunney 的工作,他之前的作品 redbean:一個單一檔案的網頁伺服器,建構為一個實際可攜式可執行檔(Actually Portable Executable),並包含一個自解壓縮的 ZIP 封存檔,這啟發了我的想法。

SELF 在很多方面都沒那麼出色。它依賴更簡單的工具來實現非常相似的目標,但我驚訝於有多少東西可以簡化到單一領域:SQL。

而 redbean 需要包含一個封存格式(ZIP),資料庫本身就是容器。Redbean 提供 Lua 鉤子來操作回應,而 SELF 中的對應功能是在 handlers 表中新增一列。

如果 redbean 是個實際可攜式可執行檔(Actually Portable Executable),那麼這就是一個實際可查詢的可執行檔(Actually Queryable Executable)。其中一個可以在任何地方執行,另一個你可以從中 SELECT。

程式如何存取自身?🤔

目前,你無法使用 /proc/self/exe。2 2 有趣的是,Linux VFS 維護者最近在核心中加入了對透明 binfmt_misc 的支援,這將使 /proc/self/exe 指向原始檔案。我在此寫了相關內容。當 binfmt_misc 匹配時,核心根本不會 execve 你的檔案,而是 execve 解譯器,並將路徑傳遞給它:

self-exec 將 argv + 1 傳遞給程式,因此程式的 argv[0] 是可執行檔本身的路徑。解譯器在跳轉到進入點之前也會釋放其 SQLite 連線,因此程式可以開啟自己的檔案並查詢它。

這是相當不受限制且神奇的。你可以讀取自己的 segment 表或旁邊的新表格。寫入的內容會在多次呼叫之間持續存在。✨

我們範例中的網頁伺服器有三個表格:routes、visits 和 presses。我們將記錄每一位訪客和每一次按鈕點擊。

建構應用程式的感覺非常普通且熟悉。我們執行 DDL 來建立應用程式結構,並 INSERT 網站內容。

資產管線看起來像一個「正常的網頁伺服器」,直到你意識到它正在使用 SQL 從自身查詢內容。哦,還有「自身」是一個 SQLite 資料庫。

https://selfdb.exe.xyz 頁面顯示了許多有趣的額外資訊,除了訪客記錄和按鈕點擊之外。我包含了 segments、symbols 和 relocations。這些並非在建構時就嵌入,而是在執行時從自身查詢。

一旦你擁有進行 ACID 交易的能力,就會有有趣的事情成為可能。網頁伺服器可以在執行時編輯自己的內容,並且編輯是交易式的。UPDATE 會被提交到與程式碼相同的檔案,而 ROLLBACK 則會撤銷它。

由於檔案格式是 SQLite,我們也可以利用現有的豐富工具。sqldiff 可以精確告訴你一個「部署做了什麼」,這可以讓我們審核並識別同一程式兩個版本之間的變更。

全文字搜尋呢?FTS5 只需要一個 CREATE VIRTUAL TABLE 的距離,因此網頁伺服器可以在其內部索引自己的頁面,並且之後仍然是一個網頁伺服器:

這一切都不是我寫的機器碼。這是 SQLite 已經擁有的機器碼,程式透過成為一個資料庫而免費繼承了它。

靜態網站產生器曾風靡一時,但未來是一個實際可查詢的可執行檔。

我真的很享受像 exe.dev 這類產品所推崇和流行的簡潔性。人們經常渴望回到透過 scp 和 ssh 部署單一檔案的「美好舊時代」,而 SELF 是一種讓這種情況再次成為可能,而且更好!我們不再只是運送一個 PHP 封存檔,而是將整個系統或應用程式的閉包運送到 libc。

如果資料和程式碼交織在一起,我們該如何進行部署?

我們可以將重新部署視為資料遷移,而遷移是兩個 INSERT ... SELECT,因為程式和資料是同一個檔案!

交換檔案,重新啟動,訪客記錄就會在新建構中保留下來。你甚至可以反向操作,對程式碼本身進行。segments 表就像任何其他表格一樣。😈

https://selfdb.exe.xyz 上有一個按鈕。按下它會將一個 INSERT 操作寫入提供該頁面的可執行檔中。

程式碼位於 fzakaria/selfdb,如果你好奇的話。它可能有點半成品,而且絕對是 AI 輔助的,但我對此沒意見。我想探索這個想法,看看它是否可行以及可能實現什麼。

我認為我只觸及了一些有趣可能性的表面。我很好奇其他人會如何利用它,並且我很樂意看到更多「實際可查詢的可執行檔」的範例出現在實際應用中。3 3 一位朋友建議的想法是透過多播 DNS 進行發現,透過交易來傳播程式更新。

結果發現,當我們重新構想我們認為僅僅是位元佈局規範的東西實際上是一個更好的資料庫時,我們幾十年來使用的許多機器碼就變得不再必要。程式就是資料庫,資料庫就是程式。

「永遠、永遠不要低估玩樂的重要性」