lealone / Lealone

比 MySQL 和 MongoDB 快10倍的 OLTP 关系数据库和文档数据库
Other
2.44k stars 514 forks source link

部分数据查询出错 #194

Closed cbqqkcel closed 1 year ago

cbqqkcel commented 1 year ago
ZHDC_PA.PUBLIC> select * from Room  limit 1,10
[2023-07-26 11:57:06] 在 69 ms (execution: 42 ms, fetching: 27 ms) 内检索到从 1 开始的 10 行
ZHDC_PA.PUBLIC> select * from Room  limit 10000,10
[2023-07-26 11:57:06] [HY000][50000] General error: "java.lang.NullPointerException: Cannot invoke ""java.lang.Integer.intValue()"" because the return value of ""java.util.HashMap.get(Object)"" is null"; SQL statement:
[2023-07-26 11:57:06] select * from Room  limit 10000,10 [50000-2]

Room 总记录有 26309 条 select from Room limit 1,10 能查询出数据 select from Room limit 10000,10 就报错了,有可能是数据的问题,但是由于查询不出来也不知道是那写数据有问题

codefollower commented 1 year ago

我用最新的 lealone 5.2 重现不了问题。 还有更多异常堆栈吗?

codefollower commented 1 year ago

如果是不敏感的测试数据,发一份给我,我调试一下,我的邮箱: codefollower AT gmail.com

cbqqkcel commented 1 year ago
java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.concurrent.ConcurrentHashMap.get(Object)" is null
    at org.lealone.storage.aose.btree.chunk.Chunk.getPageLength(Chunk.java:96) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.storage.aose.btree.BTreeStorage.readPage(BTreeStorage.java:175) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.storage.aose.btree.BTreeStorage.readPage(BTreeStorage.java:162) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.storage.aose.btree.page.PageReference.getOrReadPage(PageReference.java:147) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.storage.aose.btree.page.NodePage.getChildPage(NodePage.java:50) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.storage.aose.btree.BTreeCursor.hasNext(BTreeCursor.java:64) ~[lealone-aose-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.transaction.aote.AOTransactionMap$3.hasNext(AOTransactionMap.java:487) ~[lealone-aote-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.db.index.standard.StandardPrimaryIndex$StandardPrimaryIndexCursor.next(StandardPrimaryIndex.java:504) ~[lealone-db-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.optimizer.IndexCursor.next(IndexCursor.java:262) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.optimizer.TableFilter.next(TableFilter.java:357) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.optimizer.TableIterator.next(TableIterator.java:48) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.query.QOperator.next(QOperator.java:84) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.query.QFlat.run(QFlat.java:35) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.query.YieldableSelect.executeInternal(YieldableSelect.java:93) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.executor.YieldableBase.run(YieldableBase.java:109) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.StatementBase.syncExecute(StatementBase.java:507) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.sql.StatementBase.executeQuery(StatementBase.java:527) ~[lealone-sql-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.client.jdbc.JdbcStatement.executeQuerySQLCommand(JdbcStatement.java:376) ~[lealone-client-5.2.0-SNAPSHOT.jar:na]
    at org.lealone.client.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:308) ~[lealone-client-5.2.0-SNAPSHOT.jar:na]
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) ~[mybatis-3.5.13.jar:3.5.13]
cbqqkcel commented 1 year ago

数据已发送到邮箱

codefollower commented 1 year ago

数据已发送到邮箱

有个 page 在 t_5_57\c_5_15.db 中找不到,应该是触发某个未知 bug 在刷脏页时数据损坏了。 我继续调试一下看看能不能在其他 chunk 文件中找到。

cbqqkcel commented 1 year ago

数据库是没有非正常停机过。

codefollower commented 1 year ago

数据库是没有非正常停机过。

大概率是之前用 lealone 5.1.2 时的代码 bug 引起的,t_5_57 那个表自动刷过几次脏页了,lealone 5.1.2 每次自动刷脏页都会生成一个新的 chunk 文件,如果数据损坏了基本上可以确定是在刷脏页的过程中存在 bug,lealone 5.2.0 每次自动刷脏页不会生成一个新的 chunk 文件,除非 chunk 文件的大小达到了一个阈值。

cbqqkcel commented 1 year ago

数据库是没有非正常停机过。

大概率是之前用 lealone 5.1.2 时的代码 bug 引起的,t_5_57 那个表自动刷过几次脏页了,lealone 5.1.2 每次自动刷脏页都会生成一个新的 chunk 文件,如果数据损坏了基本上可以确定是在刷脏页的过程中存在 bug,lealone 5.2.0 每次自动刷脏页不会生成一个新的 chunk 文件,除非 chunk 文件的大小达到了一个阈值。

有可能,那现在怎么办数据能恢复吗

codefollower commented 1 year ago

数据库是没有非正常停机过。

大概率是之前用 lealone 5.1.2 时的代码 bug 引起的,t_5_57 那个表自动刷过几次脏页了,lealone 5.1.2 每次自动刷脏页都会生成一个新的 chunk 文件,如果数据损坏了基本上可以确定是在刷脏页的过程中存在 bug,lealone 5.2.0 每次自动刷脏页不会生成一个新的 chunk 文件,除非 chunk 文件的大小达到了一个阈值。

有可能,那现在怎么办数据能恢复吗

捕获异常后我直接能查到26045条记录,我再看看 c_5_15 之前的 chunk 文件是否有老数据。

codefollower commented 1 year ago

@qqcbqqkcel 修复的数据给你邮件了,你试试看。

codefollower commented 1 year ago

最新的 lealone 5.2 现在可以通过 repair table my_table 语句修复表数据了。

cbqqkcel commented 1 year ago

最新的 lealone 5.2 现在可以通过 repair table my_table 语句修复表数据了。

用语句修复后是查询是可以的,但是我也不知道有没有丢数据。 之前的总记录是26309,现在是26132少了177条。

codefollower commented 1 year ago

26309 那个只是 select count() from Room 的统计信息,执行 select count() from Room 时并不会去遍历记录的,如果 chunk 的实际记录跟它不一致时,select count(*) from Room 就不准了。

cbqqkcel commented 1 year ago

好的,谢谢

codefollower commented 1 year ago

如果不确定具体有多少条记录,看看 redo log 还有没有。 lealone 5.1.2 不会归档 redo log,刷完脏页后就删除 redo log 了,如果是 lealone 5.2.0 就会归档 redo log,可以通过归档的 redo log 恢复数据。