【发布时间】:2015-06-02 03:40:00
【问题描述】:
这是我正在尝试做的事情的要点。我将文件存储在 SQL 表中。该表很大,有 400 条记录,但每条记录都存储文件存档,每个记录的大小约为 100MB。最近,我们不得不更改我们的加密密钥。所以我正在编写一个线程(5 个线程)代码来使用旧密钥解密,然后使用新密钥进行加密。这是每个线程所做的
struct DataToReencrypt
{
int id;
string data;
}
vector<DataToReencrypt> results;
// database open
SELECT ID,FileData From Files WHERE ID BETWEEN 1 AND 80 // 81-160 and so on.
// database connection close
// database connection open
for(int i=0;i<results.size();i++ ) // results contain the result of the above query.
{
string decrypted = LegacyDecryption(results[i].FileData);
string encrypted = NewEncryption(decrypted);
UPDATE Files SET FileData = encrypted WHERE ID = results[i].ID;
}
// database connection close
问题是当我尝试这样做时,我得到了这个 C++ bad_memory 分配异常和 SQL 内存分配异常。当我阅读 bad_memory 分配异常时,我读到 C++ 在编译器无法分配新内存时抛出它。以防万一,如果这有帮助,我在具有 6GB RAM 的系统上运行它(我必须使它在 6GB RAM 中工作,因为它是我们的产品支持的最低限度)并且当这个进程运行时 sqlserver.exe 进程几乎需要 4GB RAM 空间。请帮助解决此方法的任何问题或任何可以改进的问题。
【问题讨论】:
-
我不确定这里有很多内容,您的内存不足。通常解决方案是使用更少的内存。
-
要明确一点 - 每条记录是 100MB,而您正在将其中的 80 条读入内存?这不适合 6GB
-
@TheDark 你是对的。最大文件大小为 100MB。至少有一半的文件更少。但我不想为未来的证明做假设。此外,这在 2 或 3 次中正确运行一次。所以我认为这是内存问题。无论如何要改进这里的流程?
-
我会说最好让每个线程一次读取一个项目并处理它。这样每个线程将使用最多 200MB 的内存(大约)。因此,只需将 select 语句放入循环中,一次只选择一项。如果 ID 不总是连续的,您仍然可以使用外部选择来获取 ID。
-
@TheDark 感谢您的建议。这种方法的问题是 ID 字段应该是连续的。一般情况下,如果ID不连续怎么修改呢?
标签: c++ sql multithreading performance exception