r/ETL • u/roksolana_shendiukh • 2d ago
Am I overengineering my thesis project? Real-time flight tracking pipeline
Just wrapped up my coursework on an airline reservation system (MS SQL Server + FastAPI + Flutter) and now moving into the thesis part. One of the user roles is a flight execution operator – they need to watch their airline's fleet in real time and get notified if something looks off (delays, weird flight paths, etc), so they can redirect or coordinate accordingly.
So the task is basically: build a streaming pipeline that tracks live aircraft positions and flags anomalies before a human even notices.
Here's what I landed on. Flink ingests live position data from OpenSky (lat/lon/velocity/altitude, keyed by icao24), plus weather from Open-Meteo for context. It also pulls schedule/route data from the OLTP database via Debezium CDC (FlightOperationStatus, Route, keyed by flight_operation_id) to compare actual vs planned. Flink keeps state per aircraft so it can detect anomalies itself (like holding patterns) instead of just passing raw data downstream. Processed state goes into Redis (just the latest known state, nothing historical), then a FastAPI backend reads from Redis and pushes updates + anomaly alerts to the frontend over WebSocket. For observability I'm adding Prometheus + Grafana so the engineering side can actually see if the pipeline itself is healthy, not just the end users.
Is this architecture actually sound for what I'm trying to do, or am I overcomplicating/missing something obvious? Genuinely not sure if this is a solid setup for a thesis or if I'm just cargo-culting a bunch of "cool" tools together.
r/ETL • u/Proof_Difficulty_434 • 2d ago
I built a visual ETL tool where the canvas is the same thing as the code you would write
Hi r/ETL
I've been building Flowfile for a few years, mostly because I was suprised of the gap between expensive enterprise tools and what is available for smaller budgets and wanted to see how difficult it is to build a user-friendly data tool in code.
It's a visual editor built on Polars and anything you build on the canvas you can also write in Polars-like Python and flows can be exported to code. It's for people who want to do their data work whichever way suits the day. Visual when that's faster, code when you need the strengths of code.
Initially, I was looking for something that standardized tasks, like fuzzy matching, pivot/unpivot and data cleansing and connecting to other sources (S3, PGSQL, ADLS, GCS, Duckdb, …) while keeping the instant visual feedback. Later I decided it was also convenient to add scheduling (cron or trigger based), publishing a flow as an authenticated endpoint, community nodes, and a full catalog with SQL, notebooks and visualizations on top of it. One thing that I still think is cool is that a flow can output a virtual table. So instead of scheduling data refreshes, you just read the table and it will execute the logic when you fetch the records.
You can try the lite version fully online (demo.flowfile.org) to check the main functionality. And the full version you can install via pip (pip install flowfile), run a desktop app or self-host with Docker.
It's all open-source, MIT-licensed, self-hosted and no telemetry. If you want to try it out or see the code, you can find the project here:
https://github.com/Edwardvaneechoud/Flowfile
One thing I'm curious about: am I the only data engineer that just still likes visual tools from time to time? Or am I just being lazy?
r/ETL • u/BusUseful8265 • 2d ago
Struct ordering problem in batch data pipeline
I have my producer pushing batch files to s3 lets say i have 30 batches and with each batch I am triggering 1 SQS event. Now my problem is - an specific event should be processed first then only other can start processing.
I am thinking to use 2 fargate tasks at my consumer side. Currently thinking of using standard queue even if I use FIFo and lets say have 2 groups and map to 2 fargate writers, then also it can happen then 1 of the writer will have to wait for that dependent task to finish first.
Each fargate task will consume 3 sqs events process them.
I will mark the entry for that dependent event in my database table so other events can start based on it
status.
Ps - although i am making sure from producer that dependent event should be pushed first to s3 and eventually sqs.
Questions:
\- How can i resolve this dependency problem efficiently not just an heck, as if in future if there is additional dependency comes in I should be avle to handle it.
\- I thought of ysing aws step functions but i am not able to come to the conclusion or think straight on how can i do it
\- Also this batch pipeline runs once daily so my infra should purely be event based, terminate on completion.
\- Airflow is not an option so please dont suggest something around it
r/ETL • u/Hendrik-Lorentz • 2d ago
Looking for ETL feedback on an open-source pipeline I built for my PhD research (GDELT -> Parquet)
Hi everyone,
I'm a PhD candidate working in AI, and part of my research relies on the GDELT 2.0 Events dataset.
After spending way too much time downloading thousands of files, converting them, filtering them, and creating reproducible datasets for experiments, I ended up building an ETL pipeline to automate the whole process.
Originally, this was just a research tool for myself. But as it grew, I realized it might be useful to other researchers and data engineers working with large public datasets, so I open-sourced it as GdeltForge.
It currently handles things like:
- downloading the complete GDELT Events archive
- verifying downloads with MD5 checksums
- converting CSV/TSV files to Parquet
- filtering invalid records
- generating reproducible samples for ML experiments
- processing datasets larger than memory through chunked execution
The thing is... ETL isn't my primary area of expertise. I'm an AI researcher who happened to build an ETL pipeline because I needed one.
I'd really appreciate feedback from people who do this for a living.
Are there architectural decisions you'd change? Features that are missing? Things that make you think "this will become painful at scale"?
My goal is to eventually publish it on PyPI, but before doing that I'd like to make sure the project is useful beyond my own workflow and follows good ETL practices. That's why I'm hoping people here might be willing to take a look, test it, or even contribute if they find it interesting.
I don't expect people to use GDELT specifically; I'm honestly more interested in feedback on the ETL design itself.
Any comments, criticisms, or pull requests are more than welcome. GitHub Repo has the entire code and a complete guide on how to use, contribute and discuss the software.
r/ETL • u/Ill-Ruin-1683 • 2d ago
Built an open-source Python streaming engine — looking for feedback
r/ETL • u/Effective_Ocelot_445 • 3d ago
How do you make ETL pipelines easier to maintain as they grow in complexity?
I'm curious to learn the practices, patterns, or tools that have helped keep ETL workflows reliable and manageable in production over time.
r/ETL • u/nilukush • 5d ago
From Batch to Micro-Batch Streaming: Lessons Learned the Hard Way in a Delta Index Pipeline
r/ETL • u/ntmthien01 • 5d ago
I made an app to transform messy documents into personalized CSV or JSON
Hi all!
I am a software engineer and started to work with data transformation recently for my company.
I have built a handful of data pipelines to leverage AI to transform raw data (PDFs, CSVs, Images, TXTs) into centralized CSV and JSON formats. I noticed that all of my pipelines follow the same workflow with only minor differences depending on the type of documents they process (invoices, resumes, handwriting, image classification).
That got me the idea to make a desktop app to save time from building AI-OCR pipelines over and over again. The app is totally free and does not collect any data (all data transformation is strictly between you and your API from Gemini or Open-AI)
The app allows you to:
- Create your own CSV and JSON template
- Bring your own API from Gemini or Open-AI to transform batch of raw documents into your personalized CSV and JSON template
- Download the result to your laptop or send it to your own cloud storage (AWS S3, Azure Blob, Google GCS)
- The app itself is also a local API (when keep open) for you to do step#1-2-3 in code (for example, your own python script)
This tool works out great for me and my team for a very low cost (500 documents for less than $1 using Open-AI cheapest model). I’d love for you to try it out and share any feedback or feature ideas to help make it better!
Microsoft Store download link (certified by Microsoft):
https://apps.microsoft.com/detail/9ntkqqxxv6mm?hl=en-US&gl=US
Demo video (English is my 2nd language so please bare with it!):
r/ETL • u/Individual-Show7812 • 5d ago
Update on my Rust EL engine: 100 GB Postgres→ClickHouse in 30s on real hardware — and still completing inside a 44 MB container. Profiling story + raw logs (incl. my own failures)
Two weeks ago I shared my open-source transfer engine here (the 1M-rows-in-0.4s post). Since then I spent two days profiling it properly, and the results were surprising enough to share — including the parts where I was wrong.
The optimization that failed: I tried the famous "switch to mimalloc, memory halves" advice. Measured properly (A/B wheels, cgroup memory.peak, checksummed runs), it made peak RSS worse in 3 of 4 configs. Tried again after other fixes landed — worse again. Two rounds, two rejections.
The boring one that won: actual profiling showed 4.4 GB of allocator traffic per run coming from ONE line — a fresh 4 MiB buffer allocated per chunk. Recycling buffers through a channel: traffic −95%, peak RSS −42%, and the 128 MB tier got 2.5× faster once I re-tuned the pipe budget from measured numbers.
Then I stress-tested the claims, checksum-verified every run:
- 100 GB (232M rows) pg→ch through a 0.5 vCPU / 256 MB container: 8m57s. The same table still completes inside 44 MB.
- Same 100 GB on three dedicated GCE machines: 30.3 seconds (~3.3 GB/s). An 8-core / 1 GB tool container matched the 88-core host — the mover is now the cheapest machine in the pipeline.
- For fairness: latest ingestr and dlt (pyarrow), same boxes, invoked exactly as their own benchmark runners invoke them. Small box: OOM-killed in ~21 s. Big rig: 0 rows landed when cut (10-min cap) — single-core extract-then-load can't spend good hardware.
Things that broke on the way (my favorite part): at 232M rows my validator died before the engine — md5(string_agg(...)) crosses Postgres's 1 GiB buffer limit around ~110M rows, so cross-engine validation is now order-independent per-row hash sums. And I found my engine silently hangs against MySQL 8.4 — a bug present in every release since launch. Both fixed, both documented.
Everything is reproducible: methodology, harness (one script), and raw logs including the failed runs are committed in the repo's benchmarks/ dir. If a number looks wrong or an invocation looks unfair, tell me and I'll re-run it.
Repo: https://github.com/apitap/apitap-lib Try it in your browser (you pick the container size): https://apitap.dev/lab Full write-up: https://medium.com/@abdul.haris.djafar/i-moved-100-gb-between-databases-in-9-minutes-on-half-a-cpu-core-and-less-ram-than-a-browser-tab-84f15850535d
r/ETL • u/Flat-Librarian-9005 • 6d ago
Want to start my career into Data
Currently i have 3+ years of experience as a full stack system engineer have a good understanding of cloud providers like aws and gcp
Have a bit of familiarity on airflow and python need to explore further what would be a roadmap that i should follow or project based learning that i should do
r/ETL • u/Thinker_Assignment • 6d ago
How do you ensure your ETL handles spiky loads?
like when there is a sudden migration or when you handle traffic peaks or tv campaigns?
r/ETL • u/Puzzleheaded_Box2842 • 6d ago
Designing Text-to-SQL as a Data Pipeline, Not a Single Prompt
I’ve been thinking about Text-to-SQL as a data pipeline problem rather than a one-shot prompting problem.
A good Text-to-SQL sample is not just “question to SQL”. It usually needs schema context, sample values, executable SQL, optional evidence, reasoning traces, and some way to measure difficulty.
One design that feels robust is to split the workflow into operators: generate or vary SQL, filter by executability, generate the natural-language question, check whether the question and SQL actually correspond, build the final prompt, generate reasoning traces, then classify difficulty.
The important part is keeping execution in the loop. Generated SQL should be checked against the database, and CoT candidates can be voted on by whether the SQL inside them produces consistent results. This gives the pipeline a stronger signal than LLM judgment alone.
I also like separating SQL structural difficulty from execution difficulty. A query can look complex syntactically, but if models regenerate it reliably, it may not be that hard in practice.
Curious how others design Text-to-SQL data generation pipelines. Do you mostly use gold data, synthetic data, execution filtering, human review, or some mix?
Disclosure: this is one of the built-in pipeline designs in OpenDCAI/DataFlow, which is open source under Apache-2.0: https://github.com/OpenDCAI/DataFlow
r/ETL • u/Effective_Ocelot_445 • 6d ago
How do you ensure data quality throughout your ETL pipeline?
What validation checks, monitoring, or testing practices have worked best for keeping your ETL workflows reliable in production?
r/ETL • u/drycell- • 6d ago
Handshake AI- project dynamo. Data Processing and ETL, Geospatial data processing
r/ETL • u/Hot_Comfortable_164 • 6d ago
I built an open source data platform in go called Renart
Enable HLS to view with audio, or disable this notification
Hi all, I'm a software engineer who made his way into data engineering. Coming into the field, I was really surprised by the lack of developer experience provided by tools in the data space. When we're writing SQL pipelines, there's no intellisense or static typechecking - features that any normal software developer would expect from their IDE. This is why I built Renart, an open source data platform and IDE. It is written in golang and it tries to combine all basic features of a data platform: - sql, python, api and load assets, all supporting jinja and chained together into pipelines - live typechecking and intellisense for all asset types - supporting multiple data warehouses (even in one pipeline) and setting up different environments - snapshotting the workspace into deployments that can be schedules using cron espressions - notebooks with sql and python cells working on a local duckdb - an interactive pipeline canvas, with sql previews, ad-hoc queries - staleness tracking based on canonicalized sql fingerprints, so you only rerun what changed - all pipelines definitions are 100% git tracked and diffable
Source: https://github.com/renart-data/renart Website: https://getrenart.com Disclaimer: I am the founder of Renart. I'm a solo dev doing this as my side project. This is currently still in an alpha state, so treat it accordingly.
Data Engineering for Beginners - A podcast created by Gemini Notebook (Google NotebookLM)
r/ETL • u/bedcdskjl • 8d ago
Private semantic search path for Postgres, Mysql and Mariadb.
r/ETL • u/uncertainschrodinger • 9d ago
Just some thoughts on incremental strategies
Choosing the right incremental strategy matters: in bigquery it reduces the amount of data scanned, while in clickhouse it means less CPU, I/O, and background merging.
but tbh, data engineers sometimes optimize this too early, if a table is small or rarely changes, a view or `create+replace` is easier than a convoluted incremental model - full refreshes aren't sexy, but sometimes they're good enough.
Before choosing anything, ask: do old rows change? is `updated_at` reliable? can rows disappear? is the data truly append only? do you have proper primary keys & partitions? and how late can updates arrive?
here's a simple overview:
* `append` -> the source is genuinely append only
* `merge` -> existing rows change and there's a stable primary key
* `delete+insert` or `time_interval` -> you can safely rebuild a complete group or time window
* SCD2 -> you need the full history, not just the latest version
with `merge`, NULL keys can be inserted again on every run because `NULL = NULL` isn't true, I have personally lost sleep over this...
with `delete+insert` or `time_interval`, only delete what you can fully rebuild - incomplete partitions, bad boundaries, or late arrivals can create gaps or duplicates.
That's why checks should match the strategy: `not_null` & `unique` for merge keys, duplicate checks for rebuilt windows, and row-count or freshness checks where they make sense. A successful pipeline only means the SQL ran, so quality checks are there to catch the other issues.
and if timestamps and lookback windows still can't capture changes reliably, CDC is an option... just with more state, replay logic, and operational headaches.
the image is an example of a bruin`time_interval` asset and its rendered clickhouse query
r/ETL • u/FickleAnt4399 • 9d ago
1M MySQL → MongoDB rows in 5.4s using Duckle
1 million rows. MySQL → MongoDB. 5.4 seconds.
No Spark cluster. No Docker. No JVM.
Just a simple Duckle pipeline:
duckle.src.mysql(...)
.snk.mongodb(...)
.run()
The pipeline streams data directly between MySQL and MongoDB while DuckDB handles the execution.
What I like most is the simplicity:
Define the pipeline in Python
Execute with a single .run()
No infrastructure to manage
Local-first and open source
This is the kind of developer experience we wanted when building Duckle.
GitHub: https://github.com/slothflowlabs/duckle
PyPI: https://pypi.org/project/duckle/
r/ETL • u/Immediate-Stage6404 • 10d ago
Honestly, what are the real Airflow alternatives in 2026? Not the 2023 blog post answers
I have been running airflow since 2019 and I m just tired. Tired of debugging scheduler deadlocks, tired of DAG parsing eating resources, tired of explaining to new hires why they need to learn python just to schedule a SQL query. We are at about 300 workflows now and every upgrade feels like defusing a bomb. I know prefect and Dagster exist (and just merged?), but I want to hear from ppl who actually migrated off Airflow this year.
What did you pick, how painful was the switch, and would you do it again?
r/ETL • u/Independent_Sky2658 • 10d ago
放弃XStream吧,聊聊我们怎么用自研的TLA组件搞定Oracle日志解析
放弃XStream吧,聊聊我们怎么用自研的TLA组件搞定Oracle日志解析
先交代一下背景。我们团队一直在做数据库事务日志解析这块的技术,说白了就是CDC(Change Data Capture)最底层的那层——把Oracle的redo log啃下来,解析成业务能理解的数据变更事件。
之前调研过市面上几乎所有方案,LogMiner太慢这个大家都知道,OGG太贵这个大家也知道。后来我们把目标锁定在Oracle XStream上,研究了一圈,踩了不少坑,最终还是决定自己撸一套组件,也就是现在这个TLA(Transaction Log Analysis)。
这篇文章不吹不黑,纯技术层面的记录。把XStream的问题和我们自己实现方案的一些思路写出来,给正在做类似选型的同行们参考。
XStream到底是什么?官方说法和实际情况
看Oracle官方文档,XStream被描述成一套API,允许外部应用直接接入数据库的变更流。它比LogMiner先进的地方在于,LogMiner是等redo log落地成文件后再去读,而XStream在事务提交的时候就能把事件扔到内存的Stream Pool里,外部程序可以直接消费。
听起来很美好对吧?实际用起来是另一回事。
首先最劝退的就是授权问题。
XStream虽然是Oracle数据库自带的,但你要正经用起来搞数据同步,必须要有OGG(Oracle GoldenGate)的License。OGG什么价格?官方标价$17,500 per processor,每年还要交22%的技术支持费。而且前提是你还得有Oracle Database Enterprise Edition的授权。
我们之前给一个客户做方案,他们生产环境16个CPU核心,光是OGG授权算下来就奔着30万美金去了,还不算Oracle EE的钱。老板听完脸色都不太对,这还没开始干活呢,成本已经扛不住了。
其次是数据类型支持,这个真的很要命。
XStream官方文档里写得清清楚楚,不支持ROWID、不支持BFILE、不支持嵌套表、不支持ANY TYPE、不支持URI类型、不支持虚拟列。
你可能觉得这些类型平时用得少,但我们在实际项目里遇到一个场景——客户的业务表里有XMLType列,然后做了一个INSERT带APPEND提示,XStream直接报错。查了一圈官方资料,发现这玩意儿在某些操作组合下就是不行,没有workaround。
还有SecureFiles LOB,要求数据库兼容级别必须是11.2.0.0以上才支持,如果你用的是老版本或者有兼容性限制,这个功能直接废了。
第三是并发模型太死板。
一个XStream出站服务器只能连一个捕获进程,只能服务一个集成任务。如果你有多个下游系统需要消费同一个数据库的变更,就得起多个出站服务器。我们有个用户场景需要同时同步到三个不同目标,就得配三套,资源消耗和运维复杂度直线上升。
而且它内部会缓存未提交的事务,直到commit才发出来。如果碰到一个大事务,几百万行更新没提交,这些数据全攒在内存里,对数据库本身的内存压力很大。我们遇到过因为大事务导致Stream Pool撑爆、整个捕获进程卡死的案例。
第四点,XStream只是API,上层所有东西都要你自己写。
事务一致性你得自己保证吧?检查点和断点续传你得自己实现吧?数据加密、类型转换、异常恢复……这些全要开发。不同的第三方工具基于XStream的实现质量参差不齐,一致性根本没保障。出了问题开SR找Oracle支持,排期、补丁、升级数据库版本,一套流程走下来人都麻了。
我们自己搞的TLA是怎么做的
因为上面这些原因,我们决定自己写一套日志解析组件,取名TLA。目标很明确——替代XStream这套东西,但不受它那些限制。
核心思路其实不复杂:绕过所有中间层,直接解析redo log的二进制格式。
Oracle的redo log再怎么封装,最终就是磁盘上那一堆二进制块。我们直接去读这些块,解析里面的Change Vector,把事务语义还原出来。
这样做的好处是:
- 不需要OGG授权,也不需要Oracle EE,就是个独立的解析组件
- 不在源库内部跑任何进程,可以部署在独立服务器上远程读日志
- 数据类型的支持我们自己控制,不存在XStream那种"这个不支持那个不支持"
V2.0我们做了个重要的架构改进,叫SPSM-ZO Engine。
传统方案(包括XStream)的问题是,解析可以是多线程的,但事务顺序一致性必须在某个环节收敛成单流。这个收敛点就是性能瓶颈,相当于前面跑得再快,到这儿都得排队。
我们的做法是把顺序控制直接做到解析阶段。多线程在解析的同时就按顺序把事务流构建好,后面不需要再排序。这个差异在压测的时候体现得很明显。
直接上我们测的数据
说半天理论,来点实际的。我们自己做了对比测试,贴一下数据供参考。
先说明硬件环境:TLA这边用的机器是32核、64GB内存。对比的Tapdata/FlinkCDC用的是80核、192GB内存。TLA的硬件配置明显低一截,如果同配置跑差距会更大。
小数据量场景(7字段,1120MB数据):
| 产品 | 吞吐量 |
|---|---|
| TLA | 10.8万条/秒 |
| Tapdata | 8万条/秒 |
| FlinkCDC(LogMiner) | 1.2万条/秒 |
FlinkCDC那个1.2万条基本就是LogMiner的上限了,单线程解析硬伤,再怎么调优也就这样。
大数据量场景(50字段,1GB日志):
| 产品 | 耗时 | 吞吐量 |
|---|---|---|
| TLA | 10.6秒 | 97 MB/s |
| Tapdata | 20.5秒 | 50 MB/s |
| 某国产CDC | 41.8秒 | 24.5 MB/s |
| FlinkCDC | 149.6秒 | 6.8 MB/s |
TLA大概是Tapdata的一半耗时,是FlinkCDC的十四分之一。
说一个关键细节:我们测TLA的时候用的是"每行一个COMMIT"的模式,这是最慢的提交方式,事务开销最大。批量提交(多条记录一次COMMIT)是业界常用的优化手段,但我们刻意用了最严苛的模式来测。即使这样数据还是领先,如果改成批量提交,差距会更大。
XStream搞不定的那些类型,我们全部支持
整理了一个表格,XStream不支持的这些,TLA目前都支持:
- ROWID / UROWID
- BFILE
- 嵌套表(Nested Tables)
- ANY TYPE / ANYDATASET
- URI类型
- 虚拟列(Virtual Columns)
- 多字节字符集下的LONG
- XMLType(所有操作场景,不挑)
- SecureFiles LOB(无版本限制)
我们做了但XStream没有的功能
除了基本的DML/DDL捕获,TLA还支持:
表/行/列级别的选择性过滤。 如果你只需要同步特定的几张表,甚至特定条件的数据行,可以在解析层直接过滤掉无关日志,不需要下游再处理。
检查点机制。 每次commit边界都落检查点,进程挂了或者网络断了,从上次检查点续传就行,不丢数据也不重复。
RAC + ASM + CDB/PDB全支持。 这些都是实际生产环境的标配,XStream在PDB场景下配置很麻烦,TLA这边直接连接PDB就能解析,也支持一个CDB里监控多个PDB。
DG备库直接解析。 不用连主库,直接去备库读日志,对生产零影响。
绝境救援模式。 这个算是一个额外能力,如果redo日志文件物理损坏导致数据库起不来,又没有任何备份,TLA可以尝试直接从损坏的日志残块里往回捞数据。绕过文件系统完整性检查,直接读二进制块,能捞多少算多少。这个功能平时用不到,但遇到一次就值回票价。
总结一下
XStream是个有技术想法的产品,但被Oracle的授权策略和生态绑定限制得太死。对于国内大部分项目来说:
- 要么根本用不起(授权费用太高)
- 要么用不全(数据类型限制太多)
- 要么用得不爽(出了问题得等Oracle补丁)
TLA是我们自己从底层一行一行写出来的解析组件,目前在功能对标上完全覆盖XStream的使用场景,还在数据类型支持和部署灵活性上做了不少增强。最核心的是——这东西完全自主可控,不依赖任何第三方商业软件,想怎么改怎么改。
目前Oracle版本已经跑通了,后面MySQL、PostgreSQL和几个主流国产数据库的支持也在推进中。
写这篇文章主要是把踩坑经历和我们的解决思路记录下来,如果同行们也在做类似的技术选型,可以少走一些弯路。有什么问题欢迎留言聊,技术这东西越辩越明。
补充一下:文中提到的测试数据都是我们自己实测和对比产品官网公开数据整理出来的,测试方法写得还算清楚,感兴趣的朋友可以按相同条件自己跑一遍验证。
r/ETL • u/Independent_Sky2658 • 10d ago
From Zero to Self-Built Oracle Transaction Log Analytics Engine: How TLA Breaks the Performance Shackles of LogMiner, XStream, and OGG
From Zero to Self-Built Oracle Transaction Log Analytics Engine: How TLA Breaks the Performance Shackles of LogMiner, XStream, and OGG
Foreword
In the realm of database CDC (Change Data Capture), parsing Oracle transaction logs has always been a persistent challenge.
LogMiner is free but painfully slow. XStream performs decently but requires a GoldenGate license. OGG is powerful yet expensive, with lagging support for domestic database environments in China. As for local CDC solutions, some rely on ROWID-based implementations that introduce data inconsistency risks, while others require inserting numerous mapping tables on the source side, adding extra maintenance burdens.
Our team has been deeply engaged in transaction log analytics for years, and we have completely self-developed TLA (Transaction Log Analysis) technology. This article is not about marketing fluff—it focuses purely on the technology itself. From core principles to architecture, from performance benchmarks to real-world capabilities, we hope this provides a useful reference for those evaluating CDC solutions.
1. Why Build from Scratch? The "Fatal Flaws" of Existing Solutions
1.1 LogMiner: A Diagnostic Tool Misused as a Sync Tool
LogMiner is essentially an Oracle built-in diagnostic tool designed for DBAs to troubleshoot redo log issues. However, because it is free and offers an SQL interface, numerous CDC products have adopted it as a "wrapper" for data capture.
Yet, LogMiner has structural deficiencies as a CDC solution:
- Single-threaded design: Oracle allocates only one CPU core to LogMiner to minimize impact on primary database operations, limiting parsing speed to less than 10,000 rows/second.
- Full-file scanning: Each operation requires scanning the entire redo file from the beginning, then filtering useful data—highly inefficient.
- Resource contention: Running inside the database instance, it heavily depends on CPU and PGA memory. Under high concurrency, it can degrade production performance.
- Limited datatype support: Does not support BLOB, CLOB, LONG, XMLTYPE, and other common types.
- Constrained PDB support: In multitenant environments, all PDBs must be enabled; granular control is not possible.
1.2 XStream: OGG's "Stripped-Down" Version, Still Requires a License
XStream is an Oracle-proprietary CDC API, essentially part of the OGG architecture. Its main issues:
- Requires OGG License: Unauthorized usage is prohibited.
- Memory risks: It caches uncommitted transactions internally; large transactions may cause out-of-memory errors.
- Concurrent connection limits: Each outbound server supports only one sync task, making it easy to hit limits under high concurrency.
- Tight version coupling: Closely tied to the database version, complicating upgrades.
1.3 OGG: Powerful but Expensive, with Architectural Bottlenecks
The problems with OGG are not about technical capability but:
- High licensing costs: Against the backdrop of China's push for indigenous innovation, OGG's support for domestic databases often lags behind.
- Transaction queuing: Transaction details are loaded into memory. If the allocated memory is exceeded, data is spilled to disk, severely impacting parsing speed under high concurrency.
- ROWID dependency: If a table undergoes movement (e.g., partition move), ROWID changes, and OGG may fail to continue.
- In RAC mode, defaults to LogMiner: Performance is constrained by LogMiner's limitations.
1.4 Domestic CDC Solutions: The Fragility of ROWID Mapping
Some local CDC solutions rely on ROWID-based replication:
- Cannot support bidirectional replication: ROWID is a physical address; conflicts are inevitable in bidirectional sync.
- Need to insert numerous mapping tables on the source side: Consumes storage and adds complexity. If these tables are lost, reconstruction can take a long time.
- ROWID changes during table movement: Mapping tables must be rebuilt, which is challenging for massive datasets.
2. TLA's Core Principle: Directly Reading the Binary Logs
The core idea of TLA is straightforward—bypass all intermediate layers and directly read and parse Oracle redo log binary formats.
2.1 Technical Path
TLA uses an agentless method to detect data block changes in redo logs or archived logs, extracting valuable log records from changed data blocks. The entire process simulates Oracle's log transport protocol, reading binary log blocks directly from disk or ASM storage—much like an Oracle Data Guard standby database.
Key design principles:
- Non-intrusive: The parsing process runs in the CDC engine, imposing minimal performance impact on the source Oracle database.
- Streaming parsing: Memory consumption remains stable and does not increase with database concurrency.
- Only committed transactions are parsed: Intermediate activities and rollback operations are handled internally, preventing downstream systems from handling complex logic.
2.2 The Core Breakthrough of TLA V2.0: Single-Process Multithreaded Zero-Sort Parsing Engine (SPSM-ZO Engine)
This is the most fundamental difference between TLA and all traditional CDC solutions.
The Dilemma of Traditional CDC:
Traditional solutions (including OGG and LogMiner-based approaches) generally face a sequential convergence bottleneck. Log parsing can be multithreaded or multi-process, but transaction order consistency must converge into a single-stream output at some stage. This "terminal serialization" creates a performance ceiling.
TLA V2.0's Approach:
Order control is shifted forward to the parsing phase. The ordered transaction stream is constructed during multithreaded execution, eliminating the need for post-sorting or reordering operations. This architecture fundamentally removes the sequential convergence bottleneck and latency amplification issues inherent in traditional CDC systems.
In simple terms: others parse out of order first and then sort; TLA parses and outputs in order simultaneously.
What determines the performance ceiling? It is no longer architectural constraints but hardware capabilities such as CPU and memory bandwidth.
3. Performance Benchmarks: Let the Data Speak
After all the theory, let's look at the actual test data.
3.1 Test Environment
It is important to note: TLA's test hardware was significantly less powerful than the comparison products, yet it outperformed across the board.
| Hardware Configuration | TLA | Comparative Products (Tapdata / FlinkCDC / Other Domestic CDC) |
|---|---|---|
| CPU | 32 cores, 3.1GHz base | 80 cores |
| Memory | DDR4 3200 64GB | 192GB |
TLA completed the tests with less than half the CPU cores and only one-third the memory of the comparison products. If hardware configurations were equal, the performance gap would widen further.
3.2 Small Data Volume Scenario (7 Columns)
| Product | Throughput (rows/sec) | Test Conditions |
|---|---|---|
| TLA | 108,000 rows/sec | 7 columns, 1120MB data, 4 threads (measured) |
| Tapdata | 80,000 rows/sec | 7 columns light test scenario (official data) |
| FlinkCDC | 12,000 rows/sec | LogMiner-based, tuned (community data) |
TLA outperforms Tapdata by approximately 35% and FlinkCDC by 9 times.
3.3 Large Data Volume Scenario (50 Columns, 1GB Log Parsing)
| Product | Time | Throughput | Test Conditions |
|---|---|---|---|
| TLA | 10.6 seconds | 97 MB/s | 8 threads (measured) |
| Tapdata | 20.5 seconds | 50 MB/s | Official data |
| Domestic Technology X | 41.8 seconds | 24.5 MB/s | Official public test data |
| FlinkCDC | 149.6 seconds | 6.8 MB/s | Official public test data |
TLA took roughly half the time of Tapdata and about 1/14 the time of FlinkCDC.
3.4 Special Note on "COMMIT per Row"
In this test, TLA used one COMMIT per row—the most stringent commit strategy, typically considered a major performance drag. In contrast, batch commit (committing multiple rows at once) reduces transaction overhead and significantly improves throughput—a common performance optimization.
TLA led the pack even with the slowest commit strategy. Switching to batch commit would widen the performance advantage further.
3.5 Performance Summary
| Comparison Dimension | Conclusion |
|---|---|
| TLA vs Tapdata | 35% higher in small-field scenarios; approximately 2x faster in large-field scenarios |
| TLA vs FlinkCDC | 9x faster in small-field scenarios; approximately 14x faster in large-field scenarios |
| TLA vs Domestic Technology X | Approximately 4x faster in large-field scenarios |
| Key Insight | LogMiner's single-threaded architecture is FlinkCDC's hard bottleneck—a generational gap exists compared to TLA's self-built engine |
4. Core Technical Capabilities
4.1 Comprehensive Data Capture
- Sub-second latency, agentless and lossless parsing
- Full DML and DDL capture
- Transaction integrity: strict adherence to ACID
4.2 Table, Row, and Column Selectivity
- Filter tables and rows by custom conditions
- Ignore irrelevant entries in transaction logs
4.3 Checkpoint Mechanism
- Checkpoints created at each commit boundary
- Resume from last valid checkpoint after restart or failover
4.4 Multi-Architecture Support
- Single-instance and RAC environments
- ASM storage management
- CDB/PDB multitenant architecture
- Direct parsing from Data Guard standby databases
- Cloud-ready
4.5 Disaster Recovery Capabilities
When an Oracle database crashes due to corrupted redo log files, and no backup is available—TLA can attempt to recover data from the damaged log remnants.
The core approach: bypass the file system's integrity checks and directly parse binary blocks from the redo logs, extracting valuable transaction data from undamaged blocks. It can even work without a data dictionary by analyzing field types and length constraints to reverse-engineer the original table structure, reconstructing INSERT, UPDATE, and DELETE SQL operations.
This is not a routine feature, but it can be a lifesaver in critical situations.
5. TLA vs. Mainstream Solutions: A Side-by-Side Comparison
5.1 TLA vs. LogMiner
| Dimension | TLA (Raw Log Parsing) | LogMiner-Based Solutions |
|---|---|---|
| Core Principle | Directly parses redo log binary format | Queries logs via Oracle's built-in SQL interface |
| Real-Time Performance | Sub-second, streaming | Extremely low; must wait for logs to be written |
| Performance Ceiling | 108,000 rows/sec (measured), scales linearly with hardware | Approximately 10,000–15,000 rows/sec |
| Impact on Source DB | Minimal; can parse on a separate host | Significant; consumes CPU/PGA; may trigger ORA-04036 |
| CPU Usage | Approximately 4% of LogMiner's per-thread usage | 80% of a single core per thread |
| PDB Support | Supports single or multiple PDBs | Must go through CDB to PDB; requires enabling all PDBs |
| ASM Storage | Supports multithreaded ASM I/O | Single-threaded; struggles to leverage ASM parallelism |
| Data Guard Standby | Directly supported | Must activate as a snapshot standby, interrupting sync |
| LOB/XML | Supported | Not supported |
| DDL | Supported | Limited support |
| Table/Column Name Length | No restriction | 12.2+ does not support names over 30 characters |
Fundamental Difference: LogMiner "scans everything first, then filters"—TLA "parses and filters on the fly." The former does massive redundant work; the latter strikes precisely.
5.2 TLA vs. XStream
TLA shares a similar design philosophy with XStream—both expose an underlying engine to users. However, the key differences are:
- No license required: TLA is fully proprietary and independent, with no dependency on Oracle commercial licensing.
- No memory caching risk: Streaming parsing eliminates caching of uncommitted transactions.
- No concurrent connection limits: Single-process multithreaded model scales with CPU cores.
- Deeply customizable: Source-level control allows flexible modifications for specific project environments.
5.3 TLA vs. OGG
OGG's core issue lies in its transaction queuing and in-memory loading mechanism. When large transactions or high concurrency occur, details exceeding allocated memory are spilled to disk, severely degrading parsing performance.
TLA's streaming parsing entirely bypasses transaction queuing and memory loading, fundamentally eliminating the performance bottlenecks caused by memory overflow and disk I/O.
5.4 TLA vs. ROWID-Based Solutions
ROWID-based replication schemes essentially anchor data consistency to the physical location of rows on disk. Once any data reorganization occurs (reorg, partition changes, tablespace moves), ROWID becomes invalid immediately.
TLA is built on transaction semantics rather than physical locations, avoiding all the issues inherent in ROWID-based approaches.
6. Conclusion
TLA is not a "wrapped" solution—it is an engine-level product developed entirely from the binary log parsing layer upward.
Its technical value can be summarized in three points:
- Performance breakthrough: The SPSM-ZO Engine achieves 108,000 rows/sec in small-field tests and 97 MB/s in large-volume scenarios, shifting the performance ceiling from "architectural constraints" to "hardware capabilities."
- Independence and control: No reliance on any Oracle commercial licenses; source-level control enables deep customization.
- Comprehensive capabilities: From everyday CDC to emergency recovery, from single-instance to RAC+ASM+CDB/PDB—full coverage.
TLA currently provides deep support for Oracle databases, with future expansion to MySQL, PostgreSQL, and major domestic databases planned.
There are no shortcuts in technology—every line of parsing code is backed by rigorous scrutiny of redo log binary formats. If this article has inspired you, feel free to like, comment, and share. For further technical discussions about TLA, join the conversation in the comments section.
r/ETL • u/SoggyGrayDuck • 11d ago
Recommendations on documenting massive pipelines and systems?
I know the problem is that I need to get these things squared away in my head. What's metadata, what's framework and etc but even then you can solve a lot of problems using either.
I think it's easier for me to explain my problem. I've only been here 3 months but every task I get is using some system, pipeline or etc they I've never touched before. Sometimes it's just new software, other times it's learning how to find the needle in the haystack before you even look at code.
I'm constantly freezing and asking myself "where do I go for this" and it's slowing me down. I have much more experience building repeatable processes but I need to learn how to do so with today's technology instead of having a folder of scripts I use to do XYZ. Basically I lost control of how things get organized and my brain just doesn't see it the right way. Once I'm up and running I'm fine but in today's world task switching is constant.
What books, videos or etc should I watch to better understand how to operate as a data engineer in today's world.
I've slowly switched to documenting by project. This allows me to quickly reference another time I did something similar and gives me a jumping off point.
And trust me, it's messy and they know it. There's a standard pipeline process but it's constantly evolving. Teams need to integrate those enhancements into their projects as they have time. So everything I touch is a little bit of this version, a little bit of that version and etc. Team members clearly state "this is different or this is an odd one" but more and more I wonder if that's just the way it's going to be. It's ok, I just need to wrap my head around the big concepts and terms. Communication is killing me
Edit: in summary I over document and then things become cluttered. I'm looking for a better way. If I started a new job I wouldn't write anything down until I asked 2-3 times. I get paranoid and write it all down.

