CoreNetwork / TradeCraft

Custom villager tiers, trades and rebalancing. [No longer updated]
MIT License
2 stars 6 forks source link

DB size #31

Closed riddle closed 10 years ago

riddle commented 10 years ago

Last time I checked (week ago?) DB’s size was ~ 135 MB. Today it’s 176 MB. I’m a bit worried about this trend. I’m not saying I don’t want big DB but it seems to get fatter and fatter with every day, like nothing was purged, ever.

What’s up with that?

eliadil commented 10 years ago

I think we agreed to delete records by hand, sometimes. I checked the file you uploaded - it has ~300k alive villagers and only around 4k dead villagers. Is it possible that there are 300k villagers alive on the server? Or does it signify that some records in db are created, but villager doesn't really spawn?

riddle commented 10 years ago

Infinite spawners maybe? They still try to spawn villagers, the entities are just not created.

eliadil commented 10 years ago

I'll have to test that. The event listener for creature spawn is set to ignoreCancelled events, but it wont hurt to double check.

matejdro commented 10 years ago

When you are checking, also check if it is MONITOR priority, otherwise something might cancel event after we check it.

eliadil commented 10 years ago

Infinite spawners are not a problem; the listener has MONITOR priority and ignores cancelled.

I think the problem is with regenerating villages - correct me if I'm wrong - when village regenerate, the villagers are deleted, and fresh batch of villies is spawned, right?

riddle commented 10 years ago

Yes.

5 villages regenerate every 15m, so every single one out of ~600 unclaimed will get swapped in a day (25h). There should be around 15-20 villies in a village.

The problem might be with kill events not firing on those villies then?

matejdro commented 10 years ago

I already recommended overriding villager tick and checking for .dead boolean. Bukkit events only trigger when entity is killed, where regeneration simply removes them (so they don't drop loot or perform any other dead-related actions).

eliadil commented 10 years ago

Mhm, I didn't really do anything with NMS classes (and I assume that is where its at), any hints how to get started and how is the class called?

matejdro commented 10 years ago

I think adding that to CustomVillager.java should do the trick (sorry I can't test it right now)

/**
     Entity update tick
*/
@Override
protected void bo() {
    super.bo();
    if (this.dead)
    {
        //Delete it here. It is probably also good idea to save deleted flag somewhere so you don't try to delete it multiple times (not sure how many times is this being called after entity dies)
    }
}
eliadil commented 10 years ago

Hm, the method is ok (it is the entity tick thingy) but it never goes into the if oO

matejdro commented 10 years ago

So even if you manually kill villager? I checked vanilla source a bit and it should go into if a least once.

riddle commented 10 years ago

BTW, can this solution also include some kind of code / command to purge villagers which don’t exist anymore? Or are we left with that big DB until the end of this map?

matejdro commented 10 years ago

I don't think so. Only way I see this being possible is stopping server and manually running script that would purge those since all chunks need to load.

eliadil commented 10 years ago

I killed villagers using lava, sword, and reloading villages with /mantle respawn - it didnt go into the if :[

Can it be connected to replacing villagers with custom villagers ?

matejdro commented 10 years ago

Yeah it definitely can be connected, but I think universal solution would be much better. I will check vanilla source tomorrow and see why is not working.

riddle commented 10 years ago

OK guys, this can be postponed. We just need to make sure that before new season starts, this is solved so we won’t end up with another 200-meg database.

riddle commented 10 years ago

Reopening because this DB size causes extreme slow down on server boot. I initially thought it was CommandHelper but no, after reducing it, removing TradeCraft sped the boot up. Then removing the DB from the plugin also caused the same result.

We need to take care of this. Even if it means maintenance and purging the DB from inexisting villies.

riddle commented 10 years ago

Oh and the DB is 270 MB now which means it got 70 MB more since three weeks ago! Anyone can work on this? I’m starting to think we might run out of disk space soon. It’s at 65% of SSD, because every plugins directory is ~170MB. Removing TradeCraft’s DB causes the size of backup to plummet to 54MB.

riddle commented 10 years ago

@eliadil @matejdro Can I get any update here, so I know what to expect? It’s worrying.

eliadil commented 10 years ago

I have no idea how to fix this reliably - from what I tested, the overrided methods (the one matejdro posted bo() or die()) never fired on our custom villager class. I also dont know how to remove the dead villagers from the db - I will test few ideas in the evening.

The only workaround I can think for now - mark the villager as to be saved to the db only when someone right click him for the first time. This would remove the need of saving villagers from freshly regenerated villages.

riddle commented 10 years ago

I also dont know how to remove the dead villagers from the db - I will test few ideas in the evening.

I’m open to rescanning the whole world locally (I can do it), chunk by chunk, saving IDs of alive villies and after all that is done, removing those all other IDs from the DB snapshot from production (skipping IDs generated after rescan timestamp to not delete any new villies used by players).

The only workaround I can think for now - mark the villager as to be saved to the db only when someone right click him for the first time.

This is a great idea!

matejdro commented 10 years ago

I'm working on solution for already dead villagers. So in worst case we can just run this periodically.

It needs server shut down though.

matejdro commented 10 years ago

Ok some crazy statistics:

on flatcore map from few months ago (you don't publish maps anymore), there are 16 336 villagers. In tradecraft database from latest plugins dump there are 654 646 villagers. How the hell did we get to that number?

riddle commented 10 years ago

Village regen. A village can hold up to 15 villies, 5 villages regen every 15 minutes: 300 per hour, 7200 per day, 216,000 per month.

matejdro commented 10 years ago

I'm starting to think we wasted all that time on optimizing database while this is so much more obvious solution.

riddle commented 10 years ago

No, it wasn’t a wasted time because my slowdowns during testing was with almost empty DB.

matejdro commented 10 years ago

OK nevermind then. Cleaner is almost ready.

matejdro commented 10 years ago

Here you go. https://github.com/CoreNetwork/VillagerCleaner

Similar to UUIDConverter, you need to put .jar into server file, shut down server and run it. Also don't forget to backup old db.

riddle commented 10 years ago

OK, any idea how long it will take? Is there any way for me to run it locally and copy the DB afterwards? I would announce to players that they would get X hours of villager rollback which is better than X hours of downtime.

matejdro commented 10 years ago

You can do it on any server with same world and db and then copy the db of course, but yeah it will be rollback.

I tested it on old map and it took around 30 minutes. Not that long, but not instant either. I recommend you do test run on your local server first to see how long it will take.

riddle commented 10 years ago

OK! Do you have an SSD btw?

riddle commented 10 years ago

BTW did you also load world_nether? There are villages there too.

riddle commented 10 years ago

Oh and sorry for triple posting, but do we have anything in current build of TradeCraft which would prevent this problem from reoccuring? Last commit was a month ago…

matejdro commented 10 years ago

Yes I have SSD, but server was on HDD.

Yes I load all 3 worlds (I know end has no villages, but just in case. It doesn't hurt).

Not yet, I will take a look at it later today.

matejdro commented 10 years ago

@eliadil This seems to work

    /**
     * Entity tick event
     */
    @Override
    public void h()
    {
        super.h();

        if (dead)
        {
            //Villager has died, delete it here
        }
    }

Will you do actual deletion since you know new DB system more than me?

eliadil commented 10 years ago

Sure.

eliadil commented 10 years ago

It catches the villagers being killed normally (wit a sword, for example) but not the /mantle respawn or just /butcher -n villie kills :[

riddle commented 10 years ago

Can’t Mantle just be modified to kill Villagers in a way that passes info to Mantle TradeCraft specifically?

matejdro commented 10 years ago

Yes it can be, but this is not very universal solution. Any other plugin or anything else could delete them without TC noticing.

riddle commented 10 years ago

Indeed. It’s puzzling to me how a plugin deleting mobs can’t fire any event that other plugins can pick up. But then I realized just now it’s why MobManager has those rescan loops if/when other plugins despawn mobs programatically, so that MM can update its limits and caps accordingly.

riddle commented 10 years ago

OK just updating that DB slimfast worked and it’s now at 8,4 MB down from 286 MB :D

I’d love to apply the patch today, maybe the Mantle idea is the best one for now?

eliadil commented 10 years ago

I think calling the tradecraft methods from mantle will work good for now, until we manage to find the better solution. The amount of villagers removed with other plugins is negligible.

Can you add it into mantle, @matejdro ? All that needs to be done on tradecraft side -

Villagers.getVillager(villager.getUniqueId().toString()).setDead(true);
matejdro commented 10 years ago

What if you override and I call die() method on CustomVillager? That way we don't have to add dependency to TradeCraft.

riddle commented 10 years ago

Where do we stand guys? I’d like to remove the issue once and for all, even if it’s a custom solution just for us, for now.

Ideas from the thread:

  1. Only save to DB when a villager is right-clicked or
  2. Add a Mantle call to TradeCraft asking it to delete villages removed during a village regen

I like the first idea way better because infinite spawners won’t be saving villagers if they weren’t interacted with in the first place.

eliadil commented 10 years ago

1st solution requires more work. Infinite spawners are not a problem, imo. With villagers-per-view-distance limits + good cleaning on normal death.

I'll test the thing matejdro mentioned, and if this doesnt work I'll add soft dependency + tradecraft call into mantle this evening.

Btw, mantle branch idiotfix doesnt require uuid conversions, right?

riddle commented 10 years ago

Btw, mantle branch idiotfix doesnt require uuid conversions, right?

Yes

matejdro commented 10 years ago

I can add to mantle if you want, you just add TC side.

riddle commented 10 years ago

Whatever is fastest to implement, guys. Right after this there will be UUID update and then new season development. Cannot spend two more weeks thinking about this issue, sorry.

matejdro commented 10 years ago

I can implement my side in few minutes. His side will probably take a while because he also needs to implement whole deleting thing.

eliadil commented 10 years ago

Wha.. No. Look few posts up. To mark villie for deletion all you have to call is :

Villagers.getVillager(uuid.toString()).setDead(true);

it will delete villie with next saving.