You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell连接MariaDB脚本隔次运行报错:Out of sync with server

解决PowerShell连接MariaDB隔次运行"Out of sync with server"错误

这个问题我之前也碰到过,核心原因是连接资源没有被完全释放,或者存在未处理的结果集残留,导致第二次创建连接时,服务器端认为之前的连接还有未处理的请求,从而抛出状态不一致的错误。咱们一步步来修复:

问题根源分析

你当前的代码里,虽然调用了$connection.close(),但没有对$connection执行Dispose()。在PowerShell里,.NET对象的垃圾回收机制可能不会立刻清理未释放的连接资源,第一次运行后残留的状态会干扰第二次连接。另外,MySqlCommand和MySqlDataAdapter这些实现了IDisposable的对象,若没有正确释放,也可能留下未处理的结果集痕迹。

修复后的完整代码

我调整了你的代码,重点优化了资源管理逻辑,确保所有资源都能被彻底清理:

$error.Clear()
$sqlQuery = Get-Content -Path "C:\querytext.sql" -Raw
$sqlUser = "myuser"
$sqlPass = "mypass"
$sqlHost = "myserver"
$sqlDB = "dbname"
$connectionString = "server= $sqlHost;port=3306;uid=$sqlUser;pwd=$sqlPass;database=$sqlDB"

$sqlResults = $null
try {
    # 使用using语句自动管理可释放对象(PowerShell 5.1及以上版本支持)
    using ($connection = New-Object MySql.Data.MySqlClient.MySqlConnection($connectionString)) {
        $connection.Open()
        using ($command = New-Object MySql.Data.MySqlClient.MySqlCommand($sqlQuery, $connection)) {
            using ($dataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($command)) {
                $dataSet = New-Object System.Data.DataSet
                $dataAdapter.Fill($dataSet, "data") | Out-Null
                # 复制结果表,避免连接释放后无法访问原表数据
                $sqlResults = $dataSet.Tables["data"].Copy()
            }
        }
    }
}
catch {
    Write-Host "ERROR : Unable to run query `n$($Error[0].Exception.Message)"
}

# 输出处理后的结果
if ($sqlResults) {
    $sqlResults | Format-Table
    $sqlResults | ForEach-Object { Write-Host $_.fname }
}

关键修复点说明

  1. using语句的使用:PowerShell的using代码块会自动在执行结束时调用对象的Dispose()方法,不管是否发生异常,确保连接、命令、数据适配器这些资源被彻底释放,从根源避免状态残留。
  2. 复制结果表:原DataSet中的数据表依赖于连接资源,当连接被释放后直接访问可能出问题,用Copy()创建独立的DataTable副本,保证后续结果访问不受影响。
  3. 错误信息优化:在catch块里直接输出异常的具体消息,比$Error[0]更清晰直观。

额外排查建议

如果修复后仍有问题,可以检查这几点:

  • 确保你的MySQL .NET Connector是最新版本,旧版本可能存在连接池相关的bug
  • 检查querytext.sql中的查询是否包含多个结果集(比如多个SELECT语句),虽然MySqlDataAdapter.Fill()会处理多结果集,但如果是用ExecuteReader()则需要手动读取所有结果
  • 可以临时在连接字符串中添加Pooling=false禁用连接池,排查是否是连接池导致的状态残留(不建议长期禁用,仅用于排查)

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:40:47