我在W2K12 R2(完全修补)上使用powershell v4将大量(1亿多条)记录插入MySQL数据库。我遇到了一个问题,即尽管积极地删除变量和垃圾收集,但内存使用量仍在不断增长和增长。请注意,我正在运行脚本而不是数据库服务器的盒子上的内存使用量正在增长。
插入速度很快,工作正常。然而,我有一个记忆泄漏,并在一个星期以来一直在撞墙,试图找出原因。我从测试中知道,在调用脚本的MySQL部分而不是其他任何地方时,内存会累积。
我注意到每次插入后内存从1MB到15MB之间增长。
这是流程的基本流程(底部的代码)。 -records正被添加到数组中,直到阵列中有1,000条记录 -once有一千条记录,它们作为批处理插入到DB中 - 然后使用.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
}
如果有人有任何想法或建议,我会全力以赴!
谢谢, 杰里米
答案 0 :(得分:0)
我对与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()。一旦我将其移动到处理设置连接的函数(只需要调用一次 - 或者需要时),内存泄漏就消失了。