伯克利数据库:我在这里做错了什么?
我编写了一个小程序来探索使用 C# 来使用 Berkeley DB。
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BerkeleyDB;
namespace bdbtest {
class Program {
const string dbfile = @"c:\tmp\test.db";
const int nIndexes = 5, nRecords = 500;
static SecondaryKeyGenDelegate MakeKeyGen(int idx) {
return (k, v) => new DatabaseEntry(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(v.Data) + string.Format("_{0}", idx)));
}
static void Main(string[] args) {
File.Delete(dbfile);
var environment = DatabaseEnvironment.Open(null,
new DatabaseEnvironmentConfig() {
Create = true,
Private = true,
UseMPool = true,
ErrorPrefix = "Env: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
});
var table = RecnoDatabase.Open(dbfile, "table",
new RecnoDatabaseConfig() {
Env = environment,
Creation = CreatePolicy.IF_NEEDED,
ErrorPrefix = "Table: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
});
var indexes = new List<SecondaryBTreeDatabase>();
for (int idx = 0; idx < nIndexes; ++idx)
indexes.Add(SecondaryBTreeDatabase.Open(dbfile, string.Format("index_{0}", idx),
new SecondaryBTreeDatabaseConfig(table, MakeKeyGen(idx)) {
Env = environment,
Creation = CreatePolicy.IF_NEEDED,
Compare = (k1, k2) => string.Compare(Encoding.UTF8.GetString(k1.Data), Encoding.UTF8.GetString(k2.Data)),
ErrorPrefix = "Index: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
}));
for (int rn = 0; rn < nRecords; ++rn) {
string s = string.Format("rec{0}", rn);
table.Append(new DatabaseEntry(Encoding.UTF8.GetBytes(s)));
Console.WriteLine(s);
}
foreach (var index in indexes)
index.Close();
indexes.Clear();
table.Close();
environment.Close();
}
}
}
它创建一个用作表的数据库,并创建多个辅助数据库作为该表的索引。问题是崩溃并出现以下错误:
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at BerkeleyDB.Internal.libdb_csharpPINVOKE.DB_put(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, UInt32 jarg5) at BerkeleyDB.Internal.DB.put(DB_TXN txn, DatabaseEntry key, DatabaseEntry data, UInt32 flags) at BerkeleyDB.Database.Put(DatabaseEntry key, DatabaseEntry data, Transaction txn, UInt32 flags) at BerkeleyDB.RecnoDatabase.Append(DatabaseEntry data, Transaction txn) at BerkeleyDB.RecnoDatabase.Append(DatabaseEntry data) at bdbtest.Program.Main(String[] args) in C:\Users\fgb\Documents\Visual Studio 2008\Projects\bdbtest\bdbtest\Program.cs:line 53
将一定数量的记录写入表后,它总是崩溃。此外,当我增加 nIndexes 的值时,崩溃之前写入的记录数会下降。如果值足够低(例如 nIndexes = 5、nRecords = 50),程序将顺利完成。这让我觉得我正在耗尽有限的资源,但我就是看不出问题出在哪里。
I wrote a small program to explore using Berkeley DB with C#.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BerkeleyDB;
namespace bdbtest {
class Program {
const string dbfile = @"c:\tmp\test.db";
const int nIndexes = 5, nRecords = 500;
static SecondaryKeyGenDelegate MakeKeyGen(int idx) {
return (k, v) => new DatabaseEntry(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(v.Data) + string.Format("_{0}", idx)));
}
static void Main(string[] args) {
File.Delete(dbfile);
var environment = DatabaseEnvironment.Open(null,
new DatabaseEnvironmentConfig() {
Create = true,
Private = true,
UseMPool = true,
ErrorPrefix = "Env: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
});
var table = RecnoDatabase.Open(dbfile, "table",
new RecnoDatabaseConfig() {
Env = environment,
Creation = CreatePolicy.IF_NEEDED,
ErrorPrefix = "Table: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
});
var indexes = new List<SecondaryBTreeDatabase>();
for (int idx = 0; idx < nIndexes; ++idx)
indexes.Add(SecondaryBTreeDatabase.Open(dbfile, string.Format("index_{0}", idx),
new SecondaryBTreeDatabaseConfig(table, MakeKeyGen(idx)) {
Env = environment,
Creation = CreatePolicy.IF_NEEDED,
Compare = (k1, k2) => string.Compare(Encoding.UTF8.GetString(k1.Data), Encoding.UTF8.GetString(k2.Data)),
ErrorPrefix = "Index: ",
ErrorFeedback = (pfx, msg) => Console.WriteLine(pfx + msg),
}));
for (int rn = 0; rn < nRecords; ++rn) {
string s = string.Format("rec{0}", rn);
table.Append(new DatabaseEntry(Encoding.UTF8.GetBytes(s)));
Console.WriteLine(s);
}
foreach (var index in indexes)
index.Close();
indexes.Clear();
table.Close();
environment.Close();
}
}
}
It creates a database for use as table and a number of secondary databases as indexes for that table. The problem is that is crashes with the following error:
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at BerkeleyDB.Internal.libdb_csharpPINVOKE.DB_put(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, UInt32 jarg5) at BerkeleyDB.Internal.DB.put(DB_TXN txn, DatabaseEntry key, DatabaseEntry data, UInt32 flags) at BerkeleyDB.Database.Put(DatabaseEntry key, DatabaseEntry data, Transaction txn, UInt32 flags) at BerkeleyDB.RecnoDatabase.Append(DatabaseEntry data, Transaction txn) at BerkeleyDB.RecnoDatabase.Append(DatabaseEntry data) at bdbtest.Program.Main(String[] args) in C:\Users\fgb\Documents\Visual Studio 2008\Projects\bdbtest\bdbtest\Program.cs:line 53
It always crashes after a certain number of records are written to table. Furthermore, as I increase the value of nIndexes, the number of records written before it crashes goes down. If the values are low enough (such as nIndexes = 5, nRecords = 50), the program completes without issues. This makes me think that I'm using up a finite resource, but I just can't see where the problem is.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论