我在 W2K12 R2(完全修补)上使用 powershell v4 将大量(100+ 百万)条记录插入 MySQL 数据库。我遇到了一个问题,尽管积极删除变量和垃圾收集,但内存使用量仍在继续增长。请注意,内存使用量在我运行脚本的机器上不断增加,而不是在数据库服务器上。
插入速度不错,作业运行良好。但是,我有内存泄漏问题,一个星期以来我一直在用头撞墙试图找出原因。我从测试中知道内存是在调用脚本的 MySQL 部分时累积的,而不是在其他任何地方。
我注意到每次插入后内存都会从 1MB 到 15MB 之间的任何地方增长。
这是流程的基本流程(代码在底部)。 -记录被添加到数组中,直到数组中有 1,000 条记录 -一旦有一千条记录,它们就会作为一批插入到数据库中 - 然后使用 .clear() 方法清空数组(我已经验证数组中保留了 0 条记录)。 -我在每次插入后都尝试过积极的垃圾收集(那里没有运气)。 - 还尝试删除变量然后进行垃圾收集。仍然没有运气。
为简洁起见,简化了以下代码。但是,它显示了我如何遍历记录并进行插入:
$reader = [IO.File]::OpenText($filetoread)
$lineCount = 1
while ($reader.Peek() -ge 0) {
if($lineCount -ge 1000-or $reader.Peek() -lt 0) {
insert_into_db
$lineCount = 0
}
$lineCount++
}
$reader.Close()
$reader.Dispose()
一次调用建立连接:
[void][system.reflection.Assembly]::LoadFrom("C:\Program Files (x86)\MySQL\MySQL Connector Net 6.8.3\Assemblies\v4.5\MySql.Data.dll")
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection($connectionString)
这里是调用 MySQL 为每 1,000 条记录执行实际插入操作:
function insert_into_db {
$command = $connection.CreateCommand() # Create command object
$command.CommandText = $query # Load query into object
$script:RowsInserted = $command.ExecuteNonQuery() # Execute command
$command.Dispose() # Dispose of command object
$command = $null
$query = $null
}
如果有人有任何想法或建议,我会洗耳恭听!
谢谢, 杰里米
最佳答案
我关于问题与 Powershell -join 运算符相关的初步结论似乎是错误的。
这是我正在做的。请注意,我将每一行都添加到一个数组中,稍后我将在形成 SQL 时取消滚动。 (附带说明,将项目添加到数组往往比连接字符串更高效)
$dataForInsertion = = New-Object System.Collections.Generic.List[String]
$reader = [IO.File]::OpenText($filetoread)
$lineCount = 1
while ($reader.Peek() -ge 0) {
$line = $reader.Readline()
$dataForInsertion.add($line)
if($lineCount -ge 1000-or $reader.Peek() -lt 0) {
insert_into_db -insertthis $dataForInsertion
$lineCount = 0
}
$lineCount++
}
$reader.Close()
$reader.Dispose()
调用插入函数:
sql_query -query "SET autocommit=0;INSERT INTO ``$table`` ($columns) VALUES $($dataForInsertion -join ',');COMMIT;"
改进后的插入函数现在看起来像这样:
function insert_into_db {
$command.CommandText = $query # Load query into object
$script:RowsInserted = $command.ExecuteNonQuery() # Execute command
$command.Dispose() # Dispose of command object
$query = $null
}
所以,事实证明我对问题根源的初步结论是错误的。 Powershell -join 运算符与该问题无关。
在我的 SQL 插入函数中,我在每次插入时重复调用 $connection.CreateCommand()。一旦我将其移动到处理建立连接的函数中(仅调用一次 - 或在需要时调用),内存泄漏就消失了。
关于mysql - 使用 Powershell v4 插入 MySQL 时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23317704/