Same Job, Two Engines: InnoDB and Iceberg Internals
🇬🇧 English
The first version of my stock analysis repo ran analytics on an OLTP engine, and the second runs the same workload on an OLAP stack. I chose the OLAP stack for a single optimization, but had to understand the entire lakehouse to take advantage of it.
InnoDB's design has three guarantees that shaped my early choices. It stores all columns of a row together, so fetching one bar for one symbol touches a single spot on disk, which suits ingestion. However, an indicator needing only two columns still fetches every column through the buffer pool. Indexes speed up reads but slow writes, since every write must update each B-tree in the table. That is great for selective reads and awful for write-heavy ingestion, which is why my Raw* tables have only a primary key.
InnoDB also uses an undo log, which allows concurrent reads and writes. When a row is updated or deleted, the old value is stored so other sessions can still read it. Inserts get a smaller undo log that is purged on commit. Update and delete undo logs join a global history list, which InnoDB purges once every session that started before the commit has finished. This mechanism is Multi-Version Concurrency Control, or MVCC, which lets inserts and updates happen without blocking reads.
Without realizing it, I had designed my InnoDB database using an OLAP fundamental. My financialdata table held the datetime along with OHLC prices, and every technical indicator required a join on it to find the date. It was one of my worst data designs, and I only realized it once the database held over 100GB of data. Fixing it was brutal.
🇸🇦 العربية
InnoDB مقابل Iceberg: البنية الداخلية لـ OLTP وOLAP
نفّذت النسخة الأولى من مستودع تحليل الأسهم الخاص بي التحليلات على محرك OLTP، بينما تشغّل النسخة الثانية نفس عبء العمل على منظومة OLAP. اخترت منظومة OLAP من أجل تحسين واحد، لكنني احتجت إلى فهم مستودع البيانات الموحد بالكامل كي أستفيد منه.
يقدّم تصميم InnoDB ثلاثة ضمانات شكّلت خياراتي الأولى. فهو يخزّن جميع أعمدة الصف معًا، لذا فإن جلب شريط واحد لرمز واحد يصل إلى موضع واحد على القرص، وهذا مناسب لاستيعاب البيانات. ومع ذلك، فإن المؤشر الذي يحتاج عمودين فقط يجلب جميع الأعمدة عبر مجمع المخازن المؤقتة. تسرّع الفهارس القراءة لكنها تبطئ الكتابة، لأن كل عملية كتابة يجب أن تحدّث كل شجرة B في الجدول. هذا ممتاز للقراءات الانتقائية وسيئ جدًا لاستيعاب البيانات كثيفة الكتابة، ولهذا تحتوي جداول Raw* لديّ على مفتاح أساسي فقط.
يستخدم InnoDB أيضًا سجل التراجع (undo log) الذي يتيح القراءة والكتابة المتزامنتين. عند تحديث صف أو حذفه، تُحفظ القيمة القديمة كي تتمكن الجلسات الأخرى من قراءتها. تحصل عمليات الإدراج على سجل تراجع أصغر يُحذف عند التثبيت. وتنضم سجلات التراجع الخاصة بالتحديث والحذف إلى قائمة تاريخ عامة، يطهّرها InnoDB بعد انتهاء جميع الجلسات التي بدأت قبل التثبيت. تُعرف هذه الآلية بالتحكم في التزامن متعدد الإصدارات، أو MVCC، وهي تتيح تنفيذ الإدراج والتحديث دون حجب القراءات.
ومن دون أن أدرك ذلك، صممت قاعدة بيانات InnoDB الخاصة بي على أساس من OLAP. كان جدول financialdata يحتوي على التاريخ والوقت مع أسعار OHLC، وكان كل مؤشر فني يتطلب ربطًا به لإيجاد التاريخ. كان هذا من أسوأ تصاميم البيانات لديّ، ولم أدرك ذلك إلا بعد أن تجاوزت قاعدة البيانات 100 جيغابايت. وكان إصلاحه مرهقًا للغاية.
لماذا تستخدم منظومة OLAP بدلًا من InnoDB لتحليل الأسهم؟
يناسب تخزين الصفوف في InnoDB وصيانة الفهارس أثناء الكتابة عملية استيعاب البيانات، لكنه يبطئ الاستعلامات التحليلية التي تستخدم عددًا قليلًا من الأعمدة فقط، بينما صُممت منظومة OLAP مثل Iceberg لمسح الأعمدة عبر مجموعات بيانات كبيرة.
🇧🇩 বাংলা
InnoDB বনাম Iceberg: OLTP ও OLAP-এর অভ্যন্তরীণ কাঠামো
আমার স্টক বিশ্লেষণ রিপোজিটরির প্রথম সংস্করণ একটি OLTP ইঞ্জিনে বিশ্লেষণ চালাত, আর দ্বিতীয় সংস্করণ একই কাজ একটি OLAP স্ট্যাকে চালায়। আমি একটিমাত্র অপ্টিমাইজেশনের জন্য OLAP স্ট্যাক বেছে নিয়েছিলাম, কিন্তু এর সুবিধা নিতে আমাকে পুরো লেকহাউসটি বুঝতে হয়েছিল।
InnoDB-র নকশা তিনটি নিশ্চয়তা দেয়, যা আমার প্রাথমিক সিদ্ধান্তগুলোকে রূপ দিয়েছে। এটি একটি সারির সব কলাম একসঙ্গে সংরক্ষণ করে, তাই একটি প্রতীকের একটি বার আনতে ডিস্কের একটিমাত্র স্থান স্পর্শ করতে হয়, যা ডেটা গ্রহণের জন্য উপযুক্ত। তবে যে সূচকের মাত্র দুটি কলাম দরকার, সেও বাফার পুলের মাধ্যমে সব কলাম পড়ে। সূচক পড়াকে দ্রুত করে কিন্তু লেখাকে ধীর করে, কারণ প্রতিটি লেখায় টেবিলের প্রতিটি B-tree আপডেট করতে হয়। নির্বাচনী পড়ার জন্য এটি চমৎকার, কিন্তু লেখা-নির্ভর ডেটা গ্রহণের জন্য খুবই খারাপ, এ কারণেই আমার Raw* টেবিলে শুধু প্রাইমারি কি আছে।
InnoDB একটি undo log-ও ব্যবহার করে, যা একই সময়ে পড়া ও লেখার সুযোগ দেয়। কোনো সারি আপডেট বা মুছে ফেলা হলে পুরনো মান সংরক্ষিত থাকে, যাতে অন্য সেশন এখনও তা পড়তে পারে। ইনসার্টের জন্য একটি ছোট undo log তৈরি হয়, যা কমিটের সময় মুছে ফেলা হয়। আপডেট ও ডিলিটের undo log একটি বৈশ্বিক ইতিহাস তালিকায় যুক্ত হয়, যা InnoDB তখনই পরিষ্কার করে যখন কমিটের আগে শুরু হওয়া সব সেশন শেষ হয়। এই প্রক্রিয়াকে বলে Multi-Version Concurrency Control, বা MVCC, যা পড়াকে আটকে না রেখে ইনসার্ট ও আপডেট করার সুযোগ দেয়।
বুঝতে না পেরে আমি আমার InnoDB ডেটাবেসটিকে একটি OLAP ভিত্তির উপর নকশা করে ফেলেছিলাম। আমার financialdata টেবিলে তারিখ-সময়ের সঙ্গে OHLC মূল্য ছিল, এবং প্রতিটি প্রযুক্তিগত সূচককে তারিখ খুঁজতে এর সঙ্গে জয়েন করতে হতো। এটি ছিল আমার সবচেয়ে খারাপ ডেটা নকশাগুলোর একটি, এবং ডেটাবেসে ১০০GB-এর বেশি ডেটা জমার পর আমি তা বুঝতে পারি। এটি ঠিক করা ছিল অত্যন্ত কষ্টকর।
স্টক বিশ্লেষণে InnoDB-এর পরিবর্তে কেন OLAP স্ট্যাক ব্যবহার করবেন?
InnoDB-র সারি সংরক্ষণ ও লেখার সময় সূচক রক্ষণাবেক্ষণ ডেটা গ্রহণের জন্য উপযুক্ত, কিন্তু মাত্র কয়েকটি কলাম স্পর্শকারী বিশ্লেষণমূলক পড়াকে ধীর করে। অন্যদিকে Iceberg-এর মতো OLAP স্ট্যাক বড় ডেটাসেট জুড়ে কলাম স্ক্যান করার জন্য তৈরি।
🇩🇪 Deutsch
InnoDB vs. Iceberg: Interna von OLTP und OLAP
Die erste Version meines Aktienanalyse-Repositorys lief auf einer OLTP-Engine, die zweite führt dieselbe Arbeitslast auf einem OLAP-Stack aus. Ich habe mich wegen einer einzigen Optimierung für den OLAP-Stack entschieden, musste aber das gesamte Lakehouse verstehen, um sie zu nutzen.
Das Design von InnoDB bietet drei Garantien, die meine frühen Entscheidungen geprägt haben. Es speichert alle Spalten einer Zeile zusammen, sodass das Abrufen eines Kursbalkens für ein Symbol nur eine Stelle auf der Festplatte berührt, was sich gut für den Datenimport eignet. Ein Indikator, der nur zwei Spalten benötigt, liest dennoch alle Spalten über den Buffer Pool. Indizes beschleunigen Lesevorgänge, verlangsamen aber Schreibvorgänge, da jeder Schreibvorgang jeden B-Baum der Tabelle aktualisieren muss. Das ist hervorragend für selektive Lesevorgänge und schlecht für schreibintensive Importe, weshalb meine Raw*-Tabellen nur einen Primärschlüssel haben.
InnoDB verwendet außerdem ein Undo-Log, das gleichzeitiges Lesen und Schreiben ermöglicht. Wird eine Zeile aktualisiert oder gelöscht, wird der alte Wert gespeichert, damit andere Sitzungen ihn weiterhin lesen können. Einfügungen erzeugen ein kleineres Undo-Log, das beim Commit bereinigt wird. Undo-Logs von Aktualisierungen und Löschungen werden einer globalen Verlaufsliste hinzugefügt, die InnoDB bereinigt, sobald alle Sitzungen, die vor dem Commit begonnen haben, beendet sind. Dieser Mechanismus heißt Multi-Version Concurrency Control, kurz MVCC, und erlaubt es, Einfügungen und Aktualisierungen ohne Blockierung von Lesevorgängen durchzuführen.
Ohne es zu bemerken, hatte ich meine InnoDB-Datenbank nach einem OLAP-Grundprinzip entworfen. Meine Tabelle financialdata enthielt das Datum mit Uhrzeit sowie die OHLC-Kurse, und jeder technische Indikator erforderte einen Join darauf, um das Datum zu finden. Es war eines meiner schlechtesten Datendesigns, und ich erkannte es erst, als die Datenbank über 100 GB umfasste. Die Korrektur war mühsam.
Warum einen OLAP-Stack statt InnoDB für die Aktienanalyse verwenden?
Die zeilenweise Speicherung und die Indexpflege beim Schreiben von InnoDB eignen sich für den Datenimport, verlangsamen aber analytische Lesevorgänge, die nur wenige Spalten betreffen. Ein OLAP-Stack wie Iceberg ist dagegen für das Scannen von Spalten über große Datensätze hinweg konzipiert.
🇪🇸 Español
InnoDB vs Iceberg: Funcionamiento interno de OLTP y OLAP
La primera versión de mi repositorio de análisis bursátil ejecutaba los análisis en un motor OLTP, y la segunda ejecuta la misma carga de trabajo en una pila OLAP. Elegí la pila OLAP por una única optimización, pero tuve que entender todo el lakehouse para aprovecharla.
El diseño de InnoDB ofrece tres garantías que moldearon mis primeras decisiones. Almacena todas las columnas de una fila juntas, así que obtener una barra de un símbolo toca un único punto del disco, lo que resulta adecuado para la ingesta. Sin embargo, un indicador que necesita solo dos columnas sigue leyendo todas las columnas a través del buffer pool. Los índices aceleran las lecturas pero ralentizan las escrituras, ya que cada escritura debe actualizar cada árbol B de la tabla. Esto es excelente para lecturas selectivas y pésimo para la ingesta con muchas escrituras, por lo que mis tablas Raw* solo tienen una clave primaria.
InnoDB también usa un registro de deshacer (undo log), que permite lecturas y escrituras concurrentes. Cuando una fila se actualiza o se elimina, el valor anterior se conserva para que otras sesiones puedan seguir leyéndolo. Las inserciones generan un registro de deshacer más pequeño que se purga al confirmar. Los registros de deshacer de actualizaciones y eliminaciones se unen a una lista global de historial, que InnoDB purga una vez que han terminado todas las sesiones iniciadas antes de la confirmación. Este mecanismo es el Control de Concurrencia Multiversión, o MVCC, que permite que las inserciones y actualizaciones se produzcan sin bloquear las lecturas.
Sin darme cuenta, había diseñado mi base de datos InnoDB con un fundamento OLAP. Mi tabla financialdata contenía la fecha y hora junto con los precios OHLC, y cada indicador técnico requería un join sobre ella para encontrar la fecha. Fue uno de mis peores diseños de datos, y solo me di cuenta cuando la base de datos superó los 100 GB. Corregirlo fue brutal.
¿Por qué usar una pila OLAP en lugar de InnoDB para el análisis bursátil?
El almacenamiento por filas de InnoDB y el mantenimiento de índices durante la escritura favorecen la ingesta, pero ralentizan las consultas analíticas que solo tocan unas pocas columnas, mientras que una pila OLAP como Iceberg está diseñada para escanear columnas en grandes conjuntos de datos.
🇫🇷 Français
InnoDB contre Iceberg : fonctionnement interne d'OLTP et d'OLAP
La première version de mon dépôt d'analyse boursière exécutait ses analyses sur un moteur OLTP, et la seconde exécute la même charge de travail sur une pile OLAP. J'ai choisi la pile OLAP pour une seule optimisation, mais j'ai dû comprendre l'ensemble du lakehouse pour en tirer parti.
La conception d'InnoDB offre trois garanties qui ont façonné mes premiers choix. Elle stocke toutes les colonnes d'une ligne ensemble, de sorte que la récupération d'une barre pour un symbole ne touche qu'un seul emplacement sur le disque, ce qui convient à l'ingestion. Cependant, un indicateur qui n'a besoin que de deux colonnes récupère malgré tout toutes les colonnes via le pool de tampons. Les index accélèrent les lectures mais ralentissent les écritures, car chaque écriture doit mettre à jour chaque arbre B de la table. C'est excellent pour les lectures sélectives et catastrophique pour l'ingestion à forte charge d'écriture, c'est pourquoi mes tables Raw* n'ont qu'une clé primaire.
InnoDB utilise aussi un journal d'annulation (undo log), qui permet les lectures et écritures concurrentes. Lorsqu'une ligne est mise à jour ou supprimée, l'ancienne valeur est conservée afin que d'autres sessions puissent encore la lire. Les insertions génèrent un journal d'annulation plus petit, purgé lors de la validation. Les journaux d'annulation des mises à jour et suppressions rejoignent une liste d'historique globale, qu'InnoDB purge une fois que toutes les sessions démarrées avant la validation sont terminées. Ce mécanisme est le Multi-Version Concurrency Control, ou MVCC, qui permet aux insertions et aux mises à jour de se produire sans bloquer les lectures.
Sans m'en rendre compte, j'avais conçu ma base de données InnoDB selon un principe OLAP. Ma table financialdata contenait la date et l'heure avec les prix OHLC, et chaque indicateur technique nécessitait une jointure sur celle-ci pour trouver la date. C'était l'un de mes pires choix de conception de données, et je ne m'en suis rendu compte que lorsque la base dépassait 100 Go. Le corriger a été éprouvant.
Pourquoi utiliser une pile OLAP plutôt qu'InnoDB pour l'analyse boursière ?
Le stockage par lignes d'InnoDB et la maintenance des index à l'écriture conviennent à l'ingestion, mais ralentissent les lectures analytiques qui ne touchent que quelques colonnes, alors qu'une pile OLAP comme Iceberg est conçue pour parcourir des colonnes dans de grands ensembles de données.
🇮🇳 हिन्दी
InnoDB बनाम Iceberg: OLTP और OLAP की आंतरिक संरचना
मेरे स्टॉक विश्लेषण रिपॉज़िटरी के पहले संस्करण ने विश्लेषण एक OLTP इंजन पर चलाया था, और दूसरा संस्करण वही वर्कलोड एक OLAP स्टैक पर चलाता है। मैंने एक ही अनुकूलन के लिए OLAP स्टैक चुना, लेकिन उसका लाभ उठाने के लिए मुझे पूरे लेकहाउस को समझना पड़ा।
InnoDB का डिज़ाइन तीन गारंटियाँ देता है, जिन्होंने मेरे शुरुआती निर्णयों को आकार दिया। यह किसी पंक्ति के सभी कॉलम एक साथ संग्रहीत करता है, इसलिए किसी एक सिंबल का एक बार लाने के लिए डिस्क पर एक ही स्थान तक पहुँच होती है, जो इनजेशन के लिए उपयुक्त है। हालाँकि, जिस इंडिकेटर को केवल दो कॉलम चाहिए, वह भी बफ़र पूल के माध्यम से सभी कॉलम पढ़ता है। इंडेक्स पढ़ने को तेज़ करते हैं, पर लिखने को धीमा करते हैं, क्योंकि हर लिखाई में तालिका के हर B-tree को अपडेट करना पड़ता है। यह चयनात्मक रीड के लिए बढ़िया है, लेकिन लिखने-भारी इनजेशन के लिए बहुत बुरा है, इसीलिए मेरी Raw* तालिकाओं में केवल प्राइमरी की है।
InnoDB एक undo log भी उपयोग करता है, जो समवर्ती रीड और राइट की अनुमति देता है। जब कोई पंक्ति अपडेट या डिलीट होती है, तो पुराना मान सहेजा जाता है ताकि दूसरे सेशन अब भी उसे पढ़ सकें। इंसर्ट के लिए छोटा undo log बनता है, जो कमिट होने पर हटा दिया जाता है। अपडेट और डिलीट के undo log एक वैश्विक इतिहास सूची में जुड़ते हैं, जिसे InnoDB तब साफ़ करता है जब कमिट से पहले शुरू हुए सभी सेशन समाप्त हो जाते हैं। इस तंत्र को Multi-Version Concurrency Control, या MVCC, कहते हैं, जो इंसर्ट और अपडेट को रीड को रोके बिना होने देता है।
मुझे इसका एहसास नहीं था, पर मैंने अपना InnoDB डेटाबेस एक OLAP बुनियाद पर डिज़ाइन कर दिया था। मेरी financialdata तालिका में तारीख-समय के साथ OHLC कीमतें थीं, और हर तकनीकी इंडिकेटर को तारीख खोजने के लिए उस पर join करना पड़ता था। यह मेरे सबसे खराब डेटा डिज़ाइनों में से एक था, और मुझे तब पता चला जब डेटाबेस में 100GB से अधिक डेटा हो गया। इसे ठीक करना बहुत कठिन था।
स्टॉक विश्लेषण के लिए InnoDB के बजाय OLAP स्टैक क्यों उपयोग करें?
InnoDB का रो स्टोरेज और लिखने के समय इंडेक्स का रखरखाव इनजेशन के लिए उपयुक्त है, लेकिन केवल कुछ कॉलम छूने वाली एनालिटिकल रीड को धीमा करता है, जबकि Iceberg जैसा OLAP स्टैक बड़े डेटासेट में कॉलम स्कैन करने के लिए बनाया गया है।
🇮🇩 Bahasa Indonesia
InnoDB vs Iceberg: Cara Kerja Internal OLTP dan OLAP
Versi pertama repositori analisis saham saya menjalankan analitik di mesin OLTP, dan versi kedua menjalankan beban kerja yang sama di tumpukan OLAP. Saya memilih tumpukan OLAP untuk satu optimasi, tetapi saya harus memahami seluruh lakehouse agar bisa memanfaatkannya.
Desain InnoDB memberikan tiga jaminan yang membentuk pilihan awal saya. Ia menyimpan semua kolom dalam satu baris secara bersamaan, sehingga mengambil satu bar untuk satu simbol hanya menyentuh satu lokasi di disk, yang cocok untuk ingesti. Namun, indikator yang hanya membutuhkan dua kolom tetap mengambil semua kolom melalui buffer pool. Indeks mempercepat pembacaan tetapi memperlambat penulisan, karena setiap penulisan harus memperbarui setiap B-tree dalam tabel. Ini bagus untuk pembacaan selektif dan sangat buruk untuk ingesti yang berat penulisan, itulah sebabnya tabel Raw* saya hanya memiliki primary key.
InnoDB juga menggunakan undo log, yang memungkinkan pembacaan dan penulisan berjalan bersamaan. Ketika sebuah baris diperbarui atau dihapus, nilai lama disimpan agar sesi lain tetap dapat membacanya. Penyisipan menghasilkan undo log yang lebih kecil yang dibersihkan saat commit. Undo log untuk pembaruan dan penghapusan masuk ke daftar riwayat global, yang dibersihkan InnoDB setelah setiap sesi yang dimulai sebelum commit selesai. Mekanisme ini disebut Multi-Version Concurrency Control, atau MVCC, yang memungkinkan penyisipan dan pembaruan terjadi tanpa memblokir pembacaan.
Tanpa menyadarinya, saya telah merancang database InnoDB saya menggunakan prinsip dasar OLAP. Tabel financialdata saya menyimpan tanggal dan waktu bersama harga OHLC, dan setiap indikator teknikal memerlukan join ke tabel tersebut untuk menemukan tanggalnya. Ini adalah salah satu desain data terburuk saya, dan saya baru menyadarinya ketika database sudah berisi lebih dari 100GB data. Memperbaikinya sangat melelahkan.
Mengapa menggunakan tumpukan OLAP alih-alih InnoDB untuk analisis saham?
Penyimpanan baris InnoDB dan pemeliharaan indeks saat penulisan cocok untuk ingesti, tetapi memperlambat pembacaan analitis yang hanya menyentuh beberapa kolom, sedangkan tumpukan OLAP seperti Iceberg dibangun untuk memindai kolom pada kumpulan data besar.
🇯🇵 日本語
InnoDB と Iceberg:OLTP と OLAP の内部構造
株式分析リポジトリの最初のバージョンでは分析を OLTP エンジン上で実行していましたが、2 番目のバージョンでは同じワークロードを OLAP スタック上で実行しています。私は一つの最適化のために OLAP スタックを選びましたが、その恩恵を受けるにはレイクハウス全体を理解する必要がありました。
InnoDB の設計には、初期の選択を形作った三つの保証があります。行のすべての列がまとめて格納されるため、一つの銘柄の一本のバーを取得するにはディスク上の一か所にアクセスするだけで済み、取り込みに適しています。ただし、二つの列しか必要としない指標でも、バッファプールを通じてすべての列を読み込みます。インデックスは読み取りを速めますが、書き込みを遅くします。書き込みのたびにテーブル内のすべての B ツリーを更新しなければならないからです。これは選択的な読み取りには優れていますが、書き込み負荷の高い取り込みには非常に不向きです。そのため、私の Raw* テーブルは主キーのみを持っています。
InnoDB はまた undo ログも使用し、並行した読み取りと書き込みを可能にしています。行が更新または削除されると古い値が保存され、他のセッションがそれを読み続けられるようになります。挿入では、より小さな undo ログが作られ、コミット時に消去されます。更新と削除の undo ログはグローバルな履歴リストに連なり、コミットより前に開始されたすべてのセッションが終了すると InnoDB がそれらを削除します。この仕組みが Multi-Version Concurrency Control、すなわち MVCC であり、読み取りをブロックせずに挿入と更新を行えるようにしています。
気づかないうちに、私は InnoDB データベースを OLAP の基本原則に基づいて設計していました。financialdata テーブルには日時と OHLC 価格が格納されていて、各テクニカル指標は日付を見つけるためにそのテーブルとの結合を必要としました。これは私の最悪のデータ設計の一つで、データベースが 100GB を超えるまで気づきませんでした。修正は非常に大変でした。
株式分析に InnoDB ではなく OLAP スタックを使うのはなぜですか?
InnoDB の行ストレージと書き込み時のインデックス維持は取り込みに適していますが、少数の列しか使わない分析的な読み取りを遅くします。一方、Iceberg のような OLAP スタックは、大規模なデータセットにわたって列をスキャンするために作られています。
🇧🇷 Português
InnoDB vs Iceberg: funcionamento interno de OLTP e OLAP
A primeira versão do meu repositório de análise de ações executava as análises em um motor OLTP, e a segunda executa a mesma carga de trabalho em uma pilha OLAP. Escolhi a pilha OLAP por causa de uma única otimização, mas precisei entender todo o lakehouse para aproveitá-la.
O design do InnoDB traz três garantias que moldaram minhas primeiras escolhas. Ele armazena todas as colunas de uma linha juntas, então buscar uma barra de um símbolo acessa um único ponto do disco, o que é adequado para a ingestão. No entanto, um indicador que precisa de apenas duas colunas ainda busca todas as colunas pelo buffer pool. Os índices aceleram as leituras, mas tornam as escritas mais lentas, pois cada escrita precisa atualizar cada árvore B da tabela. Isso é ótimo para leituras seletivas e péssimo para ingestão com muitas escritas, por isso minhas tabelas Raw* têm apenas uma chave primária.
O InnoDB também usa um undo log, que permite leituras e escritas concorrentes. Quando uma linha é atualizada ou excluída, o valor antigo é armazenado para que outras sessões ainda possam lê-lo. Inserções geram um undo log menor, que é descartado no commit. Os undo logs de atualizações e exclusões entram em uma lista global de histórico, que o InnoDB limpa depois que todas as sessões iniciadas antes do commit terminam. Esse mecanismo é o Multi-Version Concurrency Control, ou MVCC, que permite que inserções e atualizações ocorram sem bloquear as leituras.
Sem perceber, eu havia projetado meu banco de dados InnoDB com base em um fundamento OLAP. Minha tabela financialdata continha a data e hora junto com os preços OHLC, e cada indicador técnico exigia um join nela para encontrar a data. Foi um dos piores designs de dados que já fiz, e só percebi quando o banco passou de 100GB de dados. Corrigi-lo foi brutal.
Por que usar uma pilha OLAP em vez do InnoDB para análise de ações?
O armazenamento por linhas do InnoDB e a manutenção de índices durante a escrita são adequados para ingestão, mas tornam lentas as leituras analíticas que acessam apenas algumas colunas, enquanto uma pilha OLAP como o Iceberg é construída para varrer colunas em grandes conjuntos de dados.
🇷🇺 Русский
InnoDB против Iceberg: внутреннее устройство OLTP и OLAP
Первая версия моего репозитория для анализа акций выполняла расчёты на OLTP-движке, а вторая запускает ту же нагрузку на OLAP-стеке. Я выбрал OLAP-стек ради одной оптимизации, но чтобы воспользоваться ею, пришлось разобраться во всём lakehouse.
Конструкция InnoDB даёт три гарантии, которые определили мои первые решения. Она хранит все столбцы строки вместе, поэтому получение одного бара для одного тикера обращается к одному месту на диске, что подходит для загрузки данных. Однако индикатору, которому нужны только два столбца, всё равно приходится читать все столбцы через буферный пул. Индексы ускоряют чтение, но замедляют запись, поскольку каждая запись должна обновить каждое B-дерево таблицы. Это отлично для избирательных чтений и ужасно для загрузки с интенсивной записью, поэтому мои таблицы Raw* содержат только первичный ключ.
InnoDB также использует журнал отмен (undo log), который позволяет читать и записывать одновременно. Когда строка обновляется или удаляется, старое значение сохраняется, чтобы другие сеансы могли его прочитать. Вставки создают меньший журнал отмен, который очищается при фиксации. Журналы отмен обновлений и удалений попадают в глобальный список истории, который InnoDB очищает, когда завершаются все сеансы, начатые до фиксации. Этот механизм называется Multi-Version Concurrency Control, или MVCC, и он позволяет выполнять вставки и обновления, не блокируя чтение.
Сам того не осознавая, я спроектировал свою базу InnoDB на основе OLAP-принципа. В таблице financialdata хранились дата и время вместе с ценами OHLC, и каждому техническому индикатору требовался join с ней, чтобы найти дату. Это была одна из моих худших схем данных, и я понял это только тогда, когда база выросла больше чем до 100 ГБ. Исправлять её было очень тяжело.
Зачем использовать OLAP-стек вместо InnoDB для анализа акций?
Построчное хранение InnoDB и обслуживание индексов при записи подходят для загрузки данных, но замедляют аналитические чтения, которые затрагивают лишь несколько столбцов, тогда как OLAP-стек вроде Iceberg создан для сканирования столбцов в больших наборах данных.
🇨🇳 简体中文
InnoDB 与 Iceberg:OLTP 与 OLAP 内部机制
我的股票分析项目第一版在 OLTP 引擎上运行分析,第二版则在 OLAP 技术栈上运行相同的工作负载。我选择 OLAP 技术栈是为了一项优化,但要充分利用它,就必须理解整个湖仓架构。
InnoDB 的设计包含三项保证,塑造了我早期的选择。它将一行的所有列存放在一起,因此为某个股票代码获取一根K线只需访问磁盘上的一个位置,这适合数据摄取。然而,一个只需要两列的指标仍然会通过缓冲池读取所有列。索引加快了读取速度,却会拖慢写入,因为每次写入都必须更新表中的每一棵 B 树。这对于选择性读取很有利,但对于写入密集型的数据摄取却非常糟糕,这也是我的 Raw* 表只有主键的原因。
InnoDB 还使用撤销日志,从而支持并发读写。当一行被更新或删除时,旧值会被保存下来,以便其他会话仍能读取。插入操作会生成较小的撤销日志,并在提交时被清除。更新和删除的撤销日志会加入一个全局历史列表,InnoDB 会在所有在该提交之前开始的会话结束后再将其清除。这一机制即多版本并发控制(MVCC),它使插入和更新无需阻塞读取即可进行。
我当时并未意识到,我设计的 InnoDB 数据库采用了 OLAP 的基本思路。我的 financialdata 表同时保存日期时间和 OHLC 价格,而每个技术指标都需要与该表连接以查找日期。这是我最糟糕的数据设计之一,直到数据库中的数据超过 100GB 时我才意识到问题。修复它非常艰难。
股票分析为什么要用 OLAP 技术栈而不是 InnoDB?
InnoDB 的行存储和写入时的索引维护适合数据摄取,但会拖慢只涉及少数几列的分析型读取;而 Iceberg 等 OLAP 技术栈是为在大型数据集上扫描列而构建的。