Skip to content

Dynmap fails with large SQLite database using internal webserver or standalone - PARTIAL FIX INCLUDED #3720

@argon000s

Description

@argon000s

Issue Description: I have found 2 issues which I believe are related. I have a large world ~15GB and use SQLite database as storage ~25GB which has over one million tiles.

1. Using internal webserver, accessing the map fails completely, the page loads a few components but then stalls, refreshing the page causes it load no data and time-out. Shutting down the server causes multiple SQLException errors.

2. When using a standalone webserver with the SQLite database, tiles load extremely slowly, around one tile a second or even slower when there are empty regions on the map.

I have conducted my own research on the slow retrieval of tiles using an sqlite database browser. I ran a similar sql command found in SQLite_tiles.php.
example:

SELECT Tiles.Image,Tiles.Format,Tiles.HashCode,Tiles.LastUpdate,Tiles.ImageLen
FROM Maps JOIN Tiles WHERE Maps.WorldID='world' AND Maps.MapID='t' AND Maps.Variant='STANDARD'
AND Maps.ID=Tiles.MapID AND Tiles.x=-1114826 AND Tiles.y=1123189 AND Tiles.zoom=0;

Execution finished without errors.
Result: 1 rows returned in 804ms

That takes nearly a second!
And for a tile that does not exist:

Result: 0 rows returned in 1971ms

That's 2 seconds!
So the database is getting severely bogged down looking for tiles whether or not they exist. The automatic Index feature of SQLite prevents databases operations from taking this long even on extremely large databases. However it seems to be not using it as shown below when debugging the request.

EXPLAIN QUERY PLAN ... (the select query above)
Result:
SCAN TABLE Tiles
SEARCH TABLE Maps USING INTEGER PRIMARY KEY (rowid=?)

Notice: "SCAN TABLE Tiles". Its not using the index on the table but scanning the entire table (over 1 million rows), when using a table JOIN in the query. I don't know if this is a SQLite driver bug or some other issue.

However, you can force it to use the index by preceding join with cross in the select statement.

Using the new query:

SELECT (...) FROM Maps CROSS JOIN Tiles WHERE Maps.WorldID=(...)
Result: 1 rows returned in 6ms

EXPLAIN QUERY PLAN ... (new query)
Result:
SCAN TABLE Maps
SEARCH TABLE Tiles USING INDEX sqlite_autoindex_Tiles_1 (MapID=? AND x=? AND y=? AND zoom=?)

Much better, it's using the index like it's supposed to...

See https://www.sqlite.org/optoverview.html#manual_control_of_query_plans_using_cross_join for more info on sqlite index.

Im not 100% sure but I think something similar is happening inside the dynmap plugin causing it to completely stall

This may also be the cause for issue #3434
This may possibly also affect mySQL database, although I have not tested this.

  • Dynmap Version: dynmap v3.4-SNAPSHOT-768
  • Server Version: paper 1.18.1 build git-Paper-216
  • Pastebin of Configuration.txt: https://pastebin.com/Ne1HYuLE
  • Server Host (if applicable): Selfhosted
  • Pastebin of crashlogs or other relevant logs: https://pastebin.com/6uWDYpSX
  • Other Relevant Data/Screenshots: none?
  • Steps to Replicate: Have a large map with a large SQLite database

[x] I have looked at all other issues and this is not a duplicate
[x] I have been able to replicate this

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions