资讯动态

C++连接MySQL实战:ODBC驱动安装与DSN配置避坑指南

发布时间:2026/10/20 11:36:45 来源:尧图企业网站定制
简介面向C初学者的MySQL ODBC连接示例工程演示在Visual Studio环境中通过ODBC API访问MySQL数据库解决从环境配置到增删改查的完整链路问题。资源共26个文件核心为8个.h头文件和7个.cpp源文件完整覆盖ODBC接口封装、MFC对话框界面、自定义列表控件、记录添加与编辑等模块另有.dsp/.dsw工程文件、图标及预编译头等辅助文件压缩包仅38KB轻量易编译。已有1024人学习适合正在学习数据库编程或需要快速搭建MySQL连接原型的开发者。通过阅读源码可系统掌握SQLAllocHandle分配环境与连接句柄、SQLConnect建立DSN连接、SQLExecDirect执行SQL语句、SQLFetch遍历结果集等关键流程同时理解ODBC句柄管理、错误处理与资源释放逻辑。工程以对话框程序直观展示查询结果便于对照学习MFC与ODBC结合方式也可直接作为C项目接入MySQL的起步模板节省环境调试时间。1. 装 C 连 MySQL 之前先看懂 ODBC 这套桥用 C 连 MySQL说简单也简单说麻烦真能卡住人一整天。很多人上来就照着网上旧教程装一个 5.x 的老驱动写两行代码去连 8.0 的 MySQL结果报错报得莫名其妙。这里先说清楚C 程序本身没法直接跟 MySQL 服务器对话中间必须过一层「桥」。ODBCOpen Database Connectivity就是微软定的一套统一数据库访问接口MySQL 官方也提供了对应的 ODBC 驱动。装上驱动、配好数据源DSN你的 C 代码就能用一套标准 API 去操作 MySQL。这篇文章面向两类人一类是刚接触 ODBC 的新手想知道从哪下载、装哪个版本、代码怎么写另一类是被版本不匹配、DSN 找不到、驱动位数不对坑过的老手想看看我踩过哪些雷、最后怎么绕过去的。这套方案我在 Windows 和 Linux 上都跑通过跟着章节走先把环境理清楚再一步步装最后能跑通一个完整的增删改查示例。装不好会怎样最常见的就是程序编译过了、跑起来直接崩或者报Data source name not found、Driver not found这种让人摸不着头脑的错误。别急后面每一章都对应一个坑。2. 安装环境准备MySQL、ODBC 驱动和开发库的版本取舍2.1 MySQL 服务器版本与 ODBC 驱动的匹配原则先强调一个我反复踩了多次的教训MySQL 服务器版本和 ODBC 驱动版本不需要严格一致但驱动不能比服务器旧太多。我用 MySQL 8.0.33 配合 MySQL ODBC 8.0.32 驱动跑得很顺但如果你把服务器升到 8.4还在用 5.3 的驱动大概率会撞上认证插件不兼容的问题。MySQL 8.0 默认的认证插件是caching_sha2_password老驱动只认识mysql_native_password连接时直接报认证失败。版本选择的建议服务器是 MySQL 5.7装 MySQL ODBC 5.3 或 8.0 都行推荐 8.0 系列因为 5.3 已经停止维护很久了。服务器是 MySQL 8.0 / 8.4装 MySQL ODBC 8.0 系列建议 8.0.32 以上版本对caching_sha2_password支持最完整。操作系统是 Windows Server / Windows 10/11优先选 MSI 安装包官方提供的安装向导会同时帮你注册驱动。操作系统是 Linux需要另外装unixODBC开发库这个是 Linux 下 ODBC 的管理器没有它驱动装上也白搭。我自己一般会把驱动和服务器的小版本差控制在两年以内。驱动官方发布页写得明白8.0.33 驱动支持 MySQL 8.0 全系列和 8.4 的部分功能反过来用老驱动连新服务器除非你愿意改服务器端的认证插件否则别轻易尝试。2.2 驱动安装Windows 下 MSI 安装与静默安装参数Windows 下装 MySQL ODBC 驱动是最省事的。到 MySQL 官网的下载页找到 MySQL Connector/ODBC选 64 位 MSI 安装包。注意别选错成 32 位现在开发机基本都是 64 位你后面 C 工程如果是 x64 平台就必须要 64 位驱动。MSI 安装过程很简单一路 Next 就行。但我通常会多做一个操作安装完成后打开「ODBC 数据源管理器」确认一下驱动是否真的注册进去了。控制面板里搜「ODBC」打开后切到「驱动程序」选项卡能看到 MySQL ODBC 8.0 Unicode Driver 和 MySQL ODBC 8.0 ANSI Driver 两条记录说明驱动装好了。如果是给多台机器批量部署用静默安装参数更省事在管理员命令行里执行msiexec /i mysql-connector-odbc-8.0.33-win64.msi /quiet /norestart这条命令里/i表示安装/quiet表示静默模式不弹界面/norestart是装完不自动重启。装完同样可以通过注册表检查HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers里有没有新增键值。MSI 静默安装的注意事项是如果目标机器上已经装过旧版驱动最好先卸载再装新的否则容易残留注册表项导致驱动列表里出现两个同名驱动。2.3 Linux 下 unixODBC 与驱动库的安装路径Linux 下的安装流程和 Windows 差别很大。Windows 用 DSN 管理工具图形化配Linux 全靠改.ini文件。我先装 unixODBC因为 MySQL 官方驱动在 Linux 上依赖它来管理数据源sudo apt update sudo apt install unixodbc unixodbc-dev odbcinstunixodbc-dev这个包很多人会漏掉它的作用是把头文件和库文件放到/usr/include和/usr/lib下你的 C 程序才能引用到sql.h、sqlext.h这些头文件。接着下载 MySQL ODBC 驱动的 Linux 二进制包官方提供的是.tar.gz格式解压后里面有libmyodbc8a.so和libmyodbc8w.so两个文件a 是 ANSI 版w 是 Unicode 版。解压后把库文件放到/usr/lib/x86_64-linux-gnu/odbc/目录然后编辑/etc/odbcinst.ini注册驱动[MySQL ODBC 8.0 Unicode Driver] Description MySQL ODBC 8.0 Unicode Driver Driver /usr/lib/x86_64-linux-gnu/odbc/libmyodbc8w.so FileUsage 1写完后用odbcinst -q -d命令查询驱动是否被识别能看到MySQL ODBC 8.0 Unicode Driver这一条就算注册成功。这里容易被忽略的是FileUsage参数它告诉 ODBC 管理器这个驱动的文件使用方式写1表示 Driver 行指向的是共享库文件而不是二进制程序写错可能导致驱动加载失败。3. 配置数据源 DSN三分钟跑通系统级与无 DSN 连接3.1 Windows 系统 DSN 配置用户级与系统级的差异驱动装好只是第一步要让 C 程序能通过 ODBC 找到 MySQL还得配数据源 DSN。ODBC 数据源分三种用户 DSN、系统 DSN、文件 DSN。开发调试阶段我一般用系统 DSN因为它对当前机器上的所有用户可见服务型程序比如做成 Windows 服务跑的 C 后端也能正常读取。在「ODBC 数据源管理器」里切到「系统 DSN」选项卡点「添加」选 MySQL ODBC 8.0 Unicode Driver然后填配置项Data Source Name填mysql_dsn这是你后面代码里要引用的名字。Description可填可不填我习惯填个注释。TCP/IP Server填127.0.0.1连远程机器就填对应 IP。Port默认3306如果改过端口要对应填。User / Password填有权限的数据库账号。填完可以点「Test」按钮测试连接弹出 Connection successful 就说明 DSN 本身没毛病。这里有个小坑如果你在 64 位机器上装了 64 位驱动但用的是 32 位的 ODBC 管理器C:\Windows\SysWOW64\odbcad32.exe那你在里面配的 DSN 和 64 位的 DSN 是不互通的。我一开始没注意在 32 位管理器里配完程序跑起来照样报找不到 DSN。3.2 无 DSN 连接字符串摆脱图形界面依赖配置 DSN 虽然直观但它有个麻烦程序换了台机器或者部署到 Linux 上DSN 就失效了。所以我现在生产环境更倾向于「无 DSN 连接」DSN-less把所有连接信息直接写进连接字符串里代码里一行搞定部署时只需要确保目标机器装有对应的 ODBC 驱动。无 DSN 连接字符串长这样SQLCHAR connStr[] DRIVER{MySQL ODBC 8.0 Unicode Driver}; SERVER127.0.0.1;PORT3306; DATABASEtest_db; USERroot;PASSWORDyour_password; OPTION67108864;;这段配置里DRIVER必须和odbcinst.iniLinux或驱动管理器里的名字完全一致大小写和空格都不能错。OPTION67108864是个位掩码参数含义是启用CLIENT_MULTI_STATEMENTS允许一次执行多条 SQL如果你只是单条语句执行这项可以去掉。无 DSN 的好处是配置不落盘不会出现 DSN 权限或者注册表残留的问题坏处是密码明文写在代码里有安全要求的项目建议用配置文件加密或者环境变量注入。3.3 Linux 下 ODBC.INI 文件的手写配置方法Linux 下配置系统 DSN 要手写/etc/odbc.ini文件。我通常按下面这个模板来写[mysql_dsn] Description MySQL DSN for C app Driver MySQL ODBC 8.0 Unicode Driver Server 127.0.0.1 Port 3306 Database test_db注意方括号里的mysql_dsn是 DSN 名称Driver行的值必须与/etc/odbcinst.ini里注册的名称一致。写完后可以用命令验证isql mysql_dsn root your_password如果输出里出现---------------------和 SQL 执行结果说明 DSN 通了。用isql测通后再去写 C 代码可以帮你把「DSN 问题」和「代码问题」分开排查少走很多弯路。4. 用 C 集成 ODBC 的完整实现从连接、查询到事务处理4.1 初始化环境句柄与连接 MySQLC 使用 ODBC 的核心是调用微软或 unixODBC 提供的 API。写代码之前先理清四个句柄的层级关系环境句柄SQLHENV→ 连接句柄SQLHDBC→ 语句句柄SQLHSTMT。环境句柄是全局的一个程序只需要一个连接句柄代表一次数据库连接语句句柄代表一条 SQL 的执行上下文。初学者最容易犯的错是跳过环境句柄直接分配连接句柄结果函数返回SQL_ERROR。先看一段最小可运行的连接代码#include windows.h #include sql.h #include sqlext.h #include stdio.h int main() { SQLHENV hEnv; SQLHDBC hDbc; SQLRETURN ret; // 分配环境句柄 ret SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, hEnv); if (!SQL_SUCCEEDED(ret)) { printf(Failed to allocate environment handle\n); return -1; } // 设置 ODBC 版本为 3.x ret SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); if (!SQL_SUCCEEDED(ret)) { printf(Failed to set ODBC version\n); return -1; } // 分配连接句柄 ret SQLAllocHandle(SQL_HANDLE_DBC, hEnv, hDbc); if (!SQL_SUCCEEDED(ret)) { printf(Failed to allocate connection handle\n); return -1; } // 通过 DSN 连接 ret SQLConnect(hDbc, (SQLCHAR*)mysql_dsn, SQL_NTS, (SQLCHAR*)root, SQL_NTS, (SQLCHAR*)your_password, SQL_NTS); if (!SQL_SUCCEEDED(ret)) { printf(Failed to connect to MySQL\n); SQLFreeHandle(SQL_HANDLE_DBC, hDbc); SQLFreeHandle(SQL_HANDLE_ENV, hEnv); return -1; } printf(Connected to MySQL successfully!\n); // 清理资源 SQLDisconnect(hDbc); SQLFreeHandle(SQL_HANDLE_DBC, hDbc); SQLFreeHandle(SQL_HANDLE_ENV, hEnv); return 0; }代码里的SQLSetEnvAttr这一步非常关键它告诉 ODBC 管理器程序遵循哪个版本的规范。填SQL_OV_ODBC3表示用 ODBC 3.x 的 API 语义如果漏了这一句连接时可能表现正常但后续某些查询行为会变得不可预测。SQL_NTS是 Null-Terminated String 的缩写意思是传入的字符串以\0结尾让驱动自己去算长度。如果你想用前面提到的无 DSN 连接方式把SQLConnect换成SQLDriverConnect即可ret SQLDriverConnect(hDbc, NULL, connStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);SQL_DRIVER_NOPROMPT表示连接过程不弹出对话框程序自动用连接字符串里的信息去连。如果改成SQL_DRIVER_PROMPT驱动会弹窗让你手动输入账号密码调试排查问题时偶尔会用但生产环境绝对不要这么做。4.2 执行 SQL 查询并处理结果集连接上了接下来就是执行 SQL。这里最常用的是SQLExecDirect直接执行一条 SQL然后通过SQLBindCol把结果集的列绑定到程序变量里。我写了一个典型查询示例SQLHSTMT hStmt; SQLRETURN ret; SQLINTEGER id; SQLCHAR name[64]; SQLLEN nameLen; // 分配语句句柄 ret SQLAllocHandle(SQL_HANDLE_STMT, hDbc, hStmt); if (!SQL_SUCCEEDED(ret)) { printf(Failed to allocate statement handle\n); return -1; } // 执行查询 ret SQLExecDirect(hStmt, (SQLCHAR*)SELECT id, name FROM users LIMIT 10, SQL_NTS); if (!SQL_SUCCEEDED(ret)) { printf(Failed to execute query\n); SQLFreeHandle(SQL_HANDLE_STMT, hStmt); return -1; } // 绑定列到 C 变量 SQLBindCol(hStmt, 1, SQL_C_LONG, id, 0, NULL); SQLBindCol(hStmt, 2, SQL_C_CHAR, name, sizeof(name), nameLen); // 遍历结果集 while (SQLFetch(hStmt) SQL_SUCCESS) { printf(id%d, name%s\n, id, name); } // 释放语句句柄 SQLFreeHandle(SQL_HANDLE_STMT, hStmt);SQLBindCol的第二个参数是列序号从1开始计第三参数指定 C 语言这边的数据类型SQL_C_LONG对应intSQL_C_CHAR对应字符数组。这种绑定方式的好处是SQLFetch每次把当前行的值直接写进你给的变量里省去手动转换的麻烦。有一个容易忽略的细节字符类型的长度参数。SQLBindCol第五个参数BufferLength传的是sizeof(name)驱动最多往缓冲里写这么多字节第六个参数nameLen返回的是实际取到的字符串长度。如果你把缓冲长度填错比如填成0驱动会返回SQL_SUCCESS_WITH_INFO并且截断数据不是直接报错但日志会像玄学一样飘出来。4.3 预编译语句与事务提交回滚的 C 实现生产环境里频繁执行的 SQL 建议用预处理语句Prepared Statement好处有两个一是 SQL 解析只做一次性能比直接执行好二是参数与 SQL 文本分离从根上规避 SQL 注入。ODBC 里对应的 API 是SQLPrepare加SQLBindParameterSQLHSTMT hStmt; SQLRETURN ret; SQLAllocHandle(SQL_HANDLE_STMT, hDbc, hStmt); // 准备一条带参数占位符的 INSERT SQLPrepare(hStmt, (SQLCHAR*)INSERT INTO users(name, age) VALUES(?, ?), SQL_NTS); // 绑定参数 SQLCHAR name[32] Alice; SQLINTEGER age 25; SQLINTEGER nameLen 5; SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 32, 0, name, sizeof(name), nameLen); SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, age, 0, NULL); // 执行 ret SQLExecute(hStmt); if (!SQL_SUCCEEDED(ret)) { printf(Insert failed\n); }SQLBindParameter声明项很多容易看晕。关键几个参数第 2 个参数是参数序号从1开始第 3 个SQL_PARAM_INPUT表示是输入参数第 4、5 个分别描述 C 语言类型和 SQL 类型第 6 个是列宽字符串类型填最大长度最后三个是缓冲区指针。参数类型填错不一定会立刻报错但数据可能被截断或乱码。事务处理方面ODBC 默认是自动提交模式每条 SQL 执行完立即提交。要自己控制事务先关闭自动提交// 关闭自动提交, 开启手动事务 SQLSetConnectAttr(hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); // 执行一组操作 SQLExecDirect(hStmt, (SQLCHAR*)UPDATE accounts SET balance balance - 100 WHERE id 1, SQL_NTS); SQLExecDirect(hStmt, (SQLCHAR*)UPDATE accounts SET balance balance 100 WHERE id 2, SQL_NTS); // 成功则提交 SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_COMMIT); // 出错则回滚 // SQLEndTran(SQL_HANDLE_DBC, hDbc, SQL_ROLLBACK);SQLEndTran的第一参数填SQL_HANDLE_DBC表示事务范围是整个连接不是单条语句第二参数传SQL_COMMIT或SQL_ROLLBACK。顺手提个坑事务期间连接断开驱动会自动回滚未提交的事务但日志里通常不显示你会看到数据「神秘丢失」其实是被回滚了。4.4 错误处理用 SQLGetDiagRec 捕获具体报错信息新手写 ODBC 程序最常见的问题是不管返回值以为只要编译过了程序就一定能跑通。ODBC 的每个函数都有返回值连接失败、SQL 语法错误、约束冲突都会返回SQL_ERROR或SQL_SUCCESS_WITH_INFO。看到错误之后怎么办调用SQLGetDiagRec拿到详细信息void showError(SQLSMALLINT handleType, SQLHANDLE handle) { SQLCHAR sqlState[6]; SQLINTEGER nativeError; SQLCHAR message[1024]; SQLSMALLINT msgLen; SQLRETURN ret; ret SQLGetDiagRec(handleType, handle, 1, sqlState, nativeError, message, sizeof(message), msgLen); if (SQL_SUCCEEDED(ret)) { printf(SQLState: %s, NativeError: %d, Message: %s\n, sqlState, nativeError, message); } }调用时机很讲究必须在函数返回SQL_ERROR后立刻调用并且传入对应句柄。比如SQLConnect失败了就传SQL_HANDLE_DBC和hDbcSQLExecDirect失败了就传SQL_HANDLE_STMT和hStmt。sqlState是五字符的标准状态码常见的有SQLState含义08001客户端无法建立连接28000用户认证失败42S02表不存在HY000通用错误需结合 Message 判断拿到 SQLState 只是第一步一定要结合Message字段看。MySQL 驱动返回的信息通常会带上具体的 MySQL 错误码和提示比如Access denied for user rootlocalhost看到这个就知道是账号权限或密码的问题。5. 排错与避坑五个高频故障的排查思路和解决办法5.1 报错 Data source name not foundDSN 没找到或位数不匹配这个报错是我见过频率最高的。现象程序一跑就报Data source name not found and no default driver specified但你在 ODBC 管理器里明明能看到 DSN 配得好好的。原因排查路径基本是三条第一DSN 配置在用户级而程序以服务方式运行读取不到用户 DSN第二32 位程序读 64 位 DSN 或反过来DSN 列表不互通第三Linux 下/etc/odbc.ini里的 DSN 名和代码里SQLConnect传入的名字对不上差一个空格都算不匹配。解决办法先写个 5 行的测试程序用SQLDrivers枚举一下当前进程能看到的驱动列表确认位数再在 ODBC 管理器里切到对应的 32/64 位视图检查 DSN 是否存在。最稳的方案是改用无 DSN 连接字符串彻底绕开 DSN 的查找逻辑。5.2 报错 Access denied for user认证插件与密码策略问题现象连接时明明密码正确却报Access denied for user rootlocalhost。这个坑在 MySQL 8.0 上特别典型因为默认认证插件换成了caching_sha2_password而老版本 ODBC 驱动不认识这个插件。原因ODBC 驱动版本太旧只支持mysql_native_password。解决思路有两个优先升级驱动到 8.0 系列新驱动完整支持caching_sha2_password如果因为某种原因驱动升不了只能改用户的认证插件ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password;注意这句 SQL 的作用范围仅限指定账号不影响其他用户。另外还有一种隐蔽情况Access denied不是密码错而是账号的 host 匹配到了错误条目。比如你从192.168.1.100连MySQL 可能匹配到root%而不是rootlocalhost两个条目的密码不同导致认证失败。排查时先用SELECT user, host, plugin FROM mysql.user;看清楚账号对应的 host。5.3 编译时找不到 sql.h 或连接时找不到 libodbc现象Windows 下编译报fatal error C1083: Cannot open include file: sql.h: No such file or directoryLinux 下编译报cannot find -lodbc。原因没装 ODBC 开发库。Windows 的sql.h和sqlext.h是 Windows SDK 自带的正常情况下不会被弄丢如果你用的自定义安装的 SDK可能没勾选「软件开发工具包」。Linux 下则是漏装了unixodbc-dev包。解决Windows 重新安装或修复 Windows SDKLinux 执行sudo apt install unixodbc-dev。装完头文件在/usr/include/sql.h和/usr/include/sqlext.h库文件在/usr/lib/x86_64-linux-gnu/libodbc.so。编译命令参考g main.cpp -o app -lodbc5.4 连接超时或 Cant connect to MySQL server网络与端口排查现象程序卡顿几秒后报Cant connect to MySQL server on 192.168.1.20 (110)。原因网络不通、端口被防火墙挡住、MySQL 的bind-address限制了监听地址、或者skip-networking被开启。不要一上来就怀疑代码先在外面用工具验证网络层。排查步骤先用telnet或nc测端口再确认 MySQL 监听地址SHOW VARIABLES LIKE bind_address; SHOW VARIABLES LIKE port;如果bind_address是127.0.0.1那只能本机连外部机器永远连不上。改配置文件/etc/mysql/mysql.conf.d/mysqld.cnf把它改成0.0.0.0重启 MySQL 服务。另外确认防火墙有没有放行 3306 端口Windows 防火墙和 Linux 的 iptables 都要查。5.5 MySQL 8.0 认证插件报 Authentication plugin caching_sha2_password cannot be loaded 的具体处理现象驱动是 5.3数据库是 8.0连接时报Authentication plugin caching_sha2_password cannot be loaded。原因5.3 驱动编译时没有包含对caching_sha2_password的支持这个问题不是改配置能绕开的只能升级驱动的二进制文件。解决把 ODBC 驱动升级到 8.0 系列。在 Windows 上直接卸载旧的 5.3 驱动再装 8.0 的 MSILinux 上更新/etc/odbcinst.ini指向新下载的.so文件。装完再用isql测一遍能通就说明驱动加载和认证都正常了。如果你连数据库版本都没法换、驱动也没法升那唯一的路子就是改用户认证插件为mysql_native_password但这一步治标不治本后续再升级 MySQL 版本时还会再撞一次。6. 装完怎么验证跑通从命令行探测到 C 端到端检查环境装好、代码写完怎么确定这套链路是真正通的我自己的验证方法是分层来每层都过了才算数顺序固定为「驱动探测 → DSN 连通 → C 连接 → 数据读写 → 反复断连重连」。这套流程能帮你把「驱动问题」「配置问题」「代码问题」三块彻底分开避免一次排查牵动全身。先做驱动的静态检查。Windows 上打开 ODBC 数据源管理器确认MySQL ODBC 8.0 Unicode Driver在「驱动程序」列表里Linux 上执行odbcinst -q -d输出里必须有一行MySQL ODBC 8.0 Unicode Driver没有的话回到第 2 章重新注册驱动。驱动层过了再测 DSN。Linux 下用isql测试Windows 下直接在 ODBC 管理器里点「Test」。这一步过了说明驱动和服务器之间的基本连通没有故障。接着把 C 程序跑起来先跑一个只做连接和断开的版本确认Connected to MySQL successfully!打出来。然后跑带查询的示例看能不能从users表查出数据。这里我额外做一件事故意把 SQL 里的表名改错让程序报错检查错误处理函数能否捕获到42S02状态码。为什么这么做因为错误处理代码平时根本不会走到等到真出事才发现它编译不过、或者输出空白那排查问题时会非常被动的。最后一项是压力验证。写一个循环连续执行 100 次「连接 → 查询 → 断开」观察程序是否稳定、有没有连接泄漏。这个过程中我会把 MySQL 的max_connections调低到 20再开几个连接占着看程序会不会优雅处理连接失败而不是崩溃。这个小技巧很实用因为生产环境最怕的就是连接数打满后程序直接崩而不是报错重试。从那以后我每次把 C 程序交付给测试之前都强制走一遍上述链路尤其是最后一轮连接数压力测试绝不省略因为曾经在线上吃过连接泄漏的亏教训很深。希望这篇笔记能帮你把 MySQL ODBC 的环境坑、代码坑一次性排干净。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑