windymelt / p2p2ch

2ch like p2p bbs by Scala
BSD 3-Clause "New" or "Revised" License
11 stars 1 forks source link

しばらく運用するとキャッシュの更新に失敗する #1

Closed hangingman closed 10 years ago

hangingman commented 10 years ago

しばらく運用するとupdateCacheメソッド内で例外が発生した。 とりあえずログを貼っときます。

[debug] application - searching thread built since 0 or more
[ERROR] [12/01/2013 23:37:45.637] [ChordCore-DHT-akka.actor.default-dispatcher-19] [akka://ChordCore-DHT/user/ChordCore2ch] テーブル "THREAD_CACHE" が見つかりません
Table "THREAD_CACHE" not found; SQL statement:
SELECT THREAD, MODIFIED FROM THREAD_CACHE WHERE MODIFIED >= ? [42102-172]
org.h2.jdbc.JdbcSQLException: テーブル "THREAD_CACHE" が見つかりません
Table "THREAD_CACHE" not found; SQL statement:
SELECT THREAD, MODIFIED FROM THREAD_CACHE WHERE MODIFIED >= ? [42102-172]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
    at org.h2.message.DbException.get(DbException.java:169)
    at org.h2.message.DbException.get(DbException.java:146)
    at org.h2.command.Parser.readTableOrView(Parser.java:4824)
    at org.h2.command.Parser.readTableFilter(Parser.java:1099)
    at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1705)
    at org.h2.command.Parser.parseSelectSimple(Parser.java:1813)
    at org.h2.command.Parser.parseSelectSub(Parser.java:1699)
    at org.h2.command.Parser.parseSelectUnion(Parser.java:1542)
    at org.h2.command.Parser.parseSelect(Parser.java:1530)
    at org.h2.command.Parser.parsePrepared(Parser.java:405)
    at org.h2.command.Parser.parse(Parser.java:279)
    at org.h2.command.Parser.parse(Parser.java:251)
    at org.h2.command.Parser.prepareCommand(Parser.java:218)
    at org.h2.engine.Session.prepareLocal(Session.java:425)
    at org.h2.engine.Session.prepareCommand(Session.java:374)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1138)
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:70)
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:267)
    at com.jolbox.bonecp.ConnectionHandle.prepareStatement(ConnectionHandle.java:1024)
    at play.api.db.AutoCleanConnection$$anonfun$prepareStatement$1.apply(DB.scala:469)
    at play.api.db.AutoCleanConnection$$anonfun$prepareStatement$1.apply(DB.scala:469)
    at play.api.db.AutoCleanConnection.registering(DB.scala:448)
    at play.api.db.AutoCleanConnection.prepareStatement(DB.scala:469)
    at anorm.SimpleSql.getFilledStatement(Anorm.scala:391)
    at anorm.Sql$class.resultSet(Anorm.scala:451)
    at anorm.SimpleSql.resultSet(Anorm.scala:372)
    at anorm.Sql$class.apply(Anorm.scala:449)
    at anorm.SimpleSql.apply(Anorm.scala:372)
    at controllers.Application$$anonfun$searchThreadSince$2.apply(Application.scala:278)
    at controllers.Application$$anonfun$searchThreadSince$2.apply(Application.scala:277)
    at play.api.db.DBApi$class.withConnection(DB.scala:82)
    at play.api.db.BoneCPApi.withConnection(DB.scala:276)
    at play.api.db.DB$$anonfun$withConnection$3.apply(DB.scala:162)
    at play.api.db.DB$$anonfun$withConnection$3.apply(DB.scala:162)
    at scala.Option.map(Option.scala:145)
    at play.api.db.DB$.withConnection(DB.scala:162)
    at controllers.Application$.searchThreadSince(Application.scala:276)
    at controllers.ChordCore2ch.receiveExtension(ChordCore2ch.scala:16)
    at momijikawa.p2pscalaproto.ChordCore$$anonfun$receive$1.applyOrElse(ChordCore.scala:85)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
    at akka.actor.ActorCell.invoke(ActorCell.scala:456)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
hangingman commented 10 years ago

DBの形式がわからないが、メモリに貯める方式だとどんどんメモリを食いつぶすので データベースファイルとしてファイルに貯められるものがいいと思う。

windymelt commented 10 years ago

DBはPlay framework標準のH2 インメモリデータベースを利用しています。 ファイルを利用するものといえば、SQLiteを利用するのがいいかもしれません。 ただ、キャッシュDBの読み書きが頻繁である都合上、全ての読み書きにディスクI/Oが発生するのは不都合なので、キャッシュのような機構があるかどうかSQLiteのドキュメントを漁る必要がありそうです。 また、SQLiteはAUTO_INCREMENTなどが使用できないなど、SQL上の様々な差がH2との間にあります。 これらを総合的に考慮する必要がありそうです。

windymelt commented 10 years ago

追記。 h2データベースの設定により、コネクションが切れるとデータベースがリセットされる状態になっていたようです。 次回のコミットで修正します。 また、次回のコミットより、インメモリデータベースからファイルデータベースへの移行を行う予定です。

そこでですが、データベースファイルを作成する場所が問題になりそうです。プロジェクトのルートで問題無いと思いますが。

hangingman commented 10 years ago

P2P2ch-1.03.zipを使用していますが同じ現象は再現していません ご苦労様です