
1. 为什么还要在 Linux 上折腾 FastExport 这种老古董FastExport 是 Teradata 生态里专门用来做大批量数据导出的并行工具走的是 FastLoad 那条底层通道跟普通的 BTEQ 导出完全不是一个量级。BTEQ 导出几千万行数据你可能得泡杯茶等半小时FastExport 在同样硬件上几分钟就能把数据落到文件里差距就是这么直接。它最适合的场景是数据仓库里几百 GB 的事实表要定期卸到文件系统再喂给下游的 Hadoop、对象存储或者别的分析平台。但问题也很现实——FastExport 的版本迭代早就停了1.7 这个版本号在官方文档里都属于考古级。你在 Linux 上装它官方不会给你一个 yum 源或者 apt 包全靠手动解压、配环境变量、调库依赖。我前后在三四个不同发行版上装过这东西踩的坑足够写一篇避雷指南。这篇就把整个流程拆开讲清楚从包结构、依赖判断、环境变量配置到实际跑通一个导出任务再到常见报错怎么排查。适合谁看如果你手头有一台 Linux 服务器需要跟 Teradata 打交道又不想被 BTEQ 的龟速折磨那这篇就是给你准备的。哪怕你之前没碰过 Teradata 客户端工具跟着走也能装起来。我会尽量把为什么这么做讲透而不是甩一堆命令让你照抄。2. 装之前先搞清楚 FastExport 到底由哪些东西组成2.1 安装包里的目录结构长什么样FastExport 1.7 的 Linux 安装包通常是一个压缩归档解压后你会看到类似这样的结构fastexport/ ├── bin/ # 可执行文件核心是 fexp 和 fexp主程序 ├── lib/ # 依赖的共享库比如 libfexp.so、libcli.so ├── msg/ # 错误消息文件报错时靠它翻译成人话 ├── samples/ # 示例脚本新手照着改最快 └── scripts/ # 一些辅助脚本比如环境初始化这里有个关键点FastExport 不是单个二进制文件就能跑的。它依赖 Teradata 的 CLICall Level Interface库也就是libcli.so这一套。如果你机器上已经装了 Teradata 的其他客户端比如 BTEQ、TPT那 CLI 库可能已经存在你只需要把 FastExport 自己的库路径加进去就行。如果啥都没有那就得先把 CLI 运行时装好否则fexp一启动就报 cannot open shared object file。2.2 版本匹配这件事比你想的重要FastExport 1.7 对应的 CLI 库版本、TTUTeradata Tools and Utilities版本是有对应关系的。我见过有人拿一个很新的 CLI 库去配老版 FastExport结果连会话都建不起来报错信息还特别含糊就一句 CLI error。后来查了半天才发现是版本不兼容。判断方法很简单看安装包里有没有README或者release notes里面会写明依赖的 CLI 最低版本。如果没有那就用ldd命令看fexp依赖哪些库ldd /opt/teradata/client/17.00/bin/fexp输出里会列出所有.so文件。你对照一下系统里现有的库版本差太多就得考虑换包。经验之谈宁可 FastExport 版本略低于 CLI 版本也不要反过来。老工具配新库通常还能跑新工具配老库基本必挂。2.3 系统层面的前置条件Linux 发行版这块FastExport 1.7 对 glibc 版本有要求。太新的发行版比如某些滚动更新的可能因为 glibc 太新导致老二进制跑不起来报GLIBC_2.xx not found。这种情况要么找兼容包要么用容器跑一个老一点的 base image。另外确认几件事磁盘空间FastExport 本身不大几十 MB但导出数据可能很大/tmp和输出目录要留够。文件句柄数并行导出会开很多文件句柄ulimit -n建议调到 65535。网络连通性能 telnet 通 Teradata 的 1025 端口数据库服务端口这是最基本的。提示装之前先用uname -a和cat /etc/os-release把系统信息记下来后面排查问题时这是第一手资料。3. 手把手完成 FastExport 1.7 的安装与配置3.1 解压与目录规划我习惯把 Teradata 客户端统一放在/opt/teradata/client/下面版本号单独建目录方便以后多版本共存sudo mkdir -p /opt/teradata/client/17.00 sudo tar -zxvf fastexport_1.7_linux.tar.gz -C /opt/teradata/client/17.00/解压完检查一下权限bin目录下的可执行文件必须有x权限chmod -R 755 /opt/teradata/client/17.00/fastexport/bin这一步看着简单但我真遇到过解压后权限丢失的情况fexp死活执行不了查了半天才发现是权限问题。所以养成习惯解压后先ls -l看一眼。3.2 环境变量的正确配法FastExport 靠几个环境变量找库和消息文件配错了就是各种 not found。核心是这几个环境变量作用示例值PATH找到 fexp 可执行文件/opt/teradata/client/17.00/fastexport/binLD_LIBRARY_PATH找到共享库/opt/teradata/client/17.00/fastexport/libNLSPATH找到消息文件/opt/teradata/client/17.00/fastexport/msg/%NCOPLIB字符集相关库路径/opt/teradata/client/17.00/fastexport/lib写进/etc/profile.d/teradata.sh里这样所有用户登录都能生效export PATH/opt/teradata/client/17.00/fastexport/bin:$PATH export LD_LIBRARY_PATH/opt/teradata/client/17.00/fastexport/lib:$LD_LIBRARY_PATH export NLSPATH/opt/teradata/client/17.00/fastexport/msg/%N export COPLIB/opt/teradata/client/17.00/fastexport/lib配完source /etc/profile.d/teradata.sh然后验证which fexp fexp -v如果fexp -v能打印出版本号说明基本环境通了。注意LD_LIBRARY_PATH的顺序如果你系统里已经有别的 Teradata 库把 FastExport 的路径放前面避免加载到旧版本。3.3 验证 CLI 库依赖是否满足前面说过 FastExport 依赖 CLI 库。用ldd再确认一遍ldd $(which fexp) | grep -i not found如果输出为空恭喜依赖全齐。如果有 not found就得把缺失的库补上。常见的缺失是libcli.so和libcops.so这两个通常在 Teradata 的 CLI 运行时包里。找到对应版本的.so文件拷到lib目录或者加到LD_LIBRARY_PATH里。注意不要随便从网上下一个libcli.so就塞进去版本不匹配会导致运行时崩溃而且报错信息极难定位。优先用同一套安装介质里的库。3.4 配置 Teradata 连接信息FastExport 连接数据库靠的是fexp脚本里的登录信息或者用.tdconnect之类的配置文件。最直接的方式是在脚本里写.LOGON 数据库地址/用户名,密码;但这样密码明文暴露不安全。更好的做法是用 Teradata 的tdwallet或者环境变量传密码。我一般用环境变量export TD_USERmyuser export TD_PASSmypassword然后在脚本里引用。虽然也不是绝对安全但至少不会硬编码在文件里。4. 跑通第一个导出任务从建脚本到出数据4.1 写一个最小可用的 FastExport 脚本FastExport 的脚本语法跟 BTEQ 有点像但有自己的关键字。下面是一个导出单表的例子.LOGON 192.168.1.100/dbc,dbc; DATABASE mydb; .BEGIN EXPORT SESSIONS 4; .EXPORT OUTFILE /data/export/customer_data.txt FORMAT TEXT; SELECT * FROM customer WHERE create_date 2024-01-01; .END EXPORT; .LOGOFF;几个关键点解释一下.BEGIN EXPORT SESSIONS 4开 4 个并行会话。这个数字不是越大越好一般跟 Teradata 的 AMP 数量挂钩通常是 AMP 数的 1/4 到 1/2。开太多反而会因为资源争抢变慢。.EXPORT OUTFILE指定输出文件路径。注意这个路径是数据库服务器端还是客户端取决于配置FastExport 默认是客户端本地路径。FORMAT TEXT文本格式还有FORMAT FASTLOAD等选项按下游需求选。4.2 执行脚本并观察输出fexp export_customer.sql fexp.log 21执行过程中fexp.log里会打印会话建立、数据行数、耗时等信息。重点看几个指标Sessions established会话数是否跟预期一致。Rows exported导出的行数跟源表 count 对一下。Elapsed time总耗时。如果行数对不上先别急着怀疑工具检查一下 WHERE 条件是不是把数据过滤掉了或者字符集问题导致某些行被跳过。4.3 参数调优的实战经验FastExport 的性能主要受这几个参数影响参数作用调优建议SESSIONS并行会话数从 4 开始试逐步加到 8、16观察耗时曲线PACK每次网络传输的打包行数默认 1000大行宽可降到 500BUFFERSIZE缓冲区大小默认 64K可加到 256KTENACITY出错重试策略网络不稳时设成TENACITY 5我实测下来SESSIONS 从 4 加到 8 通常有 30% 左右的提升但加到 16 之后收益就很小了甚至因为上下文切换变慢。所以别盲目堆会话数找到那个拐点就行。5. 常见报错与排查速查表装和跑的过程中报错是家常便饭。我把踩过的坑整理成一张表遇到问题先对号入座报错信息可能原因解决方向cannot open shared object file库路径没配或库缺失检查LD_LIBRARY_PATH用ldd定位CLI error 2连接信息错误或网络不通telnet 测试端口核对地址用户名GLIBC_2.xx not found系统 glibc 版本不匹配换兼容包或用容器No more room in database导出目标空间不足清理空间或换输出路径FEXP: fatal error无详细信息消息文件路径错检查NLSPATH配置导出中途卡住不动会话死锁或网络抖动加TENACITY检查数据库锁中文乱码字符集不匹配设置COPLIB和会话字符集5.1 一个特别隐蔽的坑消息文件路径NLSPATH配错的时候FastExport 不会直接告诉你消息文件找不到而是抛一个没有任何上下文的 fatal error。我第一次遇到时完全懵后来用strace跟踪才发现它在找msg目录下的文件。所以如果报错信息特别含糊第一反应就是检查NLSPATH。5.2 权限问题导致的假死有时候fexp启动了会话也建了但就是不出数据日志也不更新。这种情况十有八九是输出目录没写权限。FastExport 在写文件失败时某些版本不会立即报错而是默默重试看起来就像卡住了。解决办法很简单touch一下输出文件看能不能创建。提示排查任何卡住的问题先看ps -ef | grep fexp进程状态再用lsof -p 进程号看它在等什么资源比瞎猜快得多。6. 几个让 FastExport 跑得更稳的实操心得6.1 用 nohup 和日志轮转保护长任务FastExport 导出大表可能跑几个小时SSH 一断任务就没了。所以一定要用nohupnohup fexp export.sql fexp_$(date %Y%m%d).log 21 日志按日期命名方便回溯。如果任务特别长再加个logrotate规则避免日志把磁盘撑爆。6.2 导出前先做小批量验证别一上来就导全表。先用SAMPLE或者WHERE ROWNUM 1000导一小批确认格式、字符集、字段分隔符都符合下游要求再放开跑全量。我吃过这个亏——全量导了三个小时结果下游说分隔符不对全部重来。6.3 监控会话资源占用FastExport 开多个会话时数据库端的资源消耗要盯着。用 Teradata 的PMON或者dbc.SessionInfo视图看会话状态避免因为单个任务把数据库拖垮影响其他业务。生产环境跑之前最好跟 DBA 打个招呼约定好会话数上限。6.4 版本升级的取舍FastExport 1.7 确实老但如果你的 Teradata 数据库版本也不新强行升级客户端反而可能引入兼容问题。我的建议是只要当前版本能稳定跑通业务就别轻易动。真要升级先在测试环境完整验证一遍导出流程包括字符集、大字段、NULL 值处理这些边界情况。7. 关于字符集和 NULL 值处理的补充字符集这块值得单独拎出来说。FastExport 导出时如果数据库用的是 UTF-8而客户端COPLIB指向的是别的字符集中文就会变成问号或者乱码。确认方法是在脚本里显式指定.SET SESSION CHARSET UTF8;NULL 值的处理也容易出问题。默认情况下NULL 在文本格式里可能导出成空字符串也可能导出成特定标记取决于FORMAT选项。如果下游系统对 NULL 敏感最好在 SELECT 里用COALESCE显式转换别指望 FastExport 的默认行为。SELECT COALESCE(name, N/A), COALESCE(amount, 0) FROM customer;这样导出来的数据干净下游不用再做二次清洗。虽然多写几个函数但省下的排查时间远超这点成本。8. 最后聊聊这套流程的适用边界FastExport 适合的是大批量、结构化、定期的导出场景。如果你的需求是实时同步、增量捕获那它不合适得看 CDC 或者消息队列那套方案。如果数据量不大几万行级别那 BTEQ 甚至普通的 JDBC 查询就够了没必要上 FastExport 这套重装备。我在实际项目里的做法是日常小批量用 BTEQ月度全量卸数用 FastExport两者配合。FastExport 的脚本模板化之后改改表名和日期参数就能复用维护成本并不高。真正花时间的是第一次装环境和调通流程一旦跑顺了后面就是例行公事。装 FastExport 1.7 这件事难点不在命令本身而在那些文档里不写的细节——库版本匹配、消息文件路径、权限和字符集。把这些坑提前填了剩下的就是体力活。希望这篇能帮你少走点弯路一次装通。