Deadlock, mysql 5.5 with java application

Ask questions about dedicated servers here and we and other users will do our best to answer them. Please also refer to the self-help section for tutorials and answers to the most commonly asked questions.
Post Reply
Squiggles
New to forums
New to forums
Posts: 7
https://www.youtube.com/channel/UC40BgXanDqOYoVCYFDSTfHA
Joined: Tue Jul 26, 2011 9:55 pm

Deadlock, mysql 5.5 with java application

Post by Squiggles »

Here is the InnoDB result -
http://pastebin.com/RPccq2wy


Basically, I'm running a game server for an MMO - and unfortunately I can't recreate the deadlock myself, so I don't know what in-game action is causing the deadlock, but the last 3 deadlocks have all revolved around the same two tables - inventoryequipment and inventoryitems


I'm running java jdk update 26 with jre6, and have an average of 20 connections at a time every day. I'm renting the 4 core VDS, which has more than enough power to run this, and all installed applications are 64 bit (windows server 2008 r2).


When a deadlock occurs, the game server freezes up, disconnecting everybody and causing a rollback. This gets aggrivating as the game in question takes some hours of playtime to get anywhere.

I've been told this happens from the DB lagging, causing it to timeout the connection causing a deadlock, but it is setup locally. The server application has an allotted heap size of 1.5 gigs - but even setting it lower didn't fix it, and setting it higher didn't do anything.

I'll also post the function in which it saves the items to the DB. If you guys need anything else, please, tell me

Code: Select all

public synchronized void saveItems(List<Pair<IItem, MapleInventoryType>> items, int id) throws SQLException {
            PreparedStatement ps = null;
            PreparedStatement pse = null;
            try {
                StringBuilder query = new StringBuilder();
                query.append("DELETE FROM `inventoryitems` WHERE `type` = ? AND `");
                query.append(account ? "accountid" : "characterid").append("` = ?");
                Connection con = DatabaseConnection.getConnection();
                ps = con.prepareStatement(query.toString());
                ps.setInt(1, value);
                ps.setInt(2, id);
                ps.executeUpdate();
                ps.close();
                ps = con.prepareStatement("INSERT INTO `inventoryitems` VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
                pse = con.prepareStatement("INSERT INTO `inventoryequipment` VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

                for (Pair<IItem, MapleInventoryType> pair : items) {
                    IItem item = pair.getLeft();
                    MapleInventoryType mit = pair.getRight();
                    ps.setInt(1, value);
                    ps.setString(2, account ? null : String.valueOf(id));
                    ps.setString(3, account ? String.valueOf(id) : null);
                    ps.setInt(4, item.getItemId());
                    ps.setInt(5, mit.getType());
                    ps.setInt(6, item.getPosition());
                    ps.setInt(7, item.getQuantity());
                    ps.setString(8, item.getOwner());
                    ps.setInt(9, item.getPetId());
                    ps.setInt(10, item.getFlag());
                    ps.setLong(11, item.getExpiration());
                    ps.setString(12, item.getGiftFrom());
                    ps.executeUpdate();

                    if (mit.equals(MapleInventoryType.EQUIP) || mit.equals(MapleInventoryType.EQUIPPED)) {
                        ResultSet rs = ps.getGeneratedKeys();

                        if (!rs.next())
                            throw new RuntimeException("Inserting item failed.");

                        pse.setInt(1, rs.getInt(1));
                        rs.close();
                        IEquip equip = (IEquip) item;
                        pse.setInt(2, equip.getUpgradeSlots());
                        pse.setInt(3, equip.getLevel());
                        pse.setInt(4, equip.getStr());
                        pse.setInt(5, equip.getDex());
                        pse.setInt(6, equip.getInt());
                        pse.setInt(7, equip.getLuk());
                        pse.setInt(8, equip.getHp());
                        pse.setInt(9, equip.getMp());
                        pse.setInt(10, equip.getWatk());
                        pse.setInt(11, equip.getMatk());
			pse.setInt(12, equip.getWdef());
			pse.setInt(13, equip.getMdef());
			pse.setInt(14, equip.getAcc());
			pse.setInt(15, equip.getAvoid());
                        pse.setInt(16, equip.getHands());
                        pse.setInt(17, equip.getSpeed());
                        pse.setInt(18, equip.getJump());
                        pse.setInt(19, 0);
                	pse.setInt(20, equip.getVicious());
                        pse.setInt(21, equip.getItemLevel());
                        pse.setInt(22, equip.getItemExp());
                        pse.setInt(23, equip.getRingId());
                        pse.executeUpdate();
                    }
		}
                
		pse.close();
		ps.close();
            } finally {
                if (ps != null) ps.close();
		if (pse != null) pse.close();
            }
	}
Thank you for reading.
User avatar
Edge100x
Founder
Founder
Posts: 13121
Joined: Thu Apr 18, 2002 11:04 pm
Location: Seattle
Contact:

Re: Deadlock, mysql 5.5 with java application

Post by Edge100x »

Since this is so specific to an application that I'm not familiar with, I may not be very much help, but I'll try, with some general troubleshooting information.

On Linux, I'd recommend running "mytop" to see if a long-running query might be holding things up. On any platform, you should be able to see similar information by connecting to MySQL with a command-oriented tool and typing "show full processlist" -- this will tell you what each thread/client is doing.

You might also take a look at the application with Process Monitor, which is a Microsoft-sponsored tool that will give you a better idea of what your frozen process is doing. It might be trying to constantly reload a file or might be sending/receiving network traffic that would give you a hint as to what section of the code is causing problems.

Checking your Windows Event log and any MySQL logs could also potentially turn up an error that might help to explain the cause.
Squiggles
New to forums
New to forums
Posts: 7
Joined: Tue Jul 26, 2011 9:55 pm

Re: Deadlock, mysql 5.5 with java application

Post by Squiggles »

The application itself doesn't freeze - the connection does. The server freezes client sided, but the bat files (which you use to launch the server) run just fine, and are responding in taskmgr. They have no issues whatsoever - besides that of the deadlock.


"Lock wait timeout exceeded, try restarting the transaction"


Also, I changed the lock_wait_timeout settings in my ini files to 500 seconds with no avail.

I'm really not that experienced with either java or mysql, so I apologize if some data you need is lacking.


Also, I was told by a guy that is a helluva lot more experienced java & mysql than I am that this is my DB having a problem - not the source files.
User avatar
Edge100x
Founder
Founder
Posts: 13121
Joined: Thu Apr 18, 2002 11:04 pm
Location: Seattle
Contact:

Re: Deadlock, mysql 5.5 with java application

Post by Edge100x »

You could try different MySQL versions (newer and older) and look at the MySQL process list as I recommended in my last post, but I'm really stabbing in the dark here. The other person with experience with this software might be the best one to help you further.
Squiggles
New to forums
New to forums
Posts: 7
Joined: Tue Jul 26, 2011 9:55 pm

Re: Deadlock, mysql 5.5 with java application

Post by Squiggles »

He's lost as to what is causing the dead lock.

His only suggestion is that the database is lagging. I'll try upgrading to mysql 5.6.

Do you guys have any suggested versions that'll work best with windows server 2008 r2?

Also, do you think backing up the data I have now will cause any issues with the new one? Or perhaps splitting the thread I supplied (it saves both inventoryitems and inventoryequipment at the same time)
User avatar
Edge100x
Founder
Founder
Posts: 13121
Joined: Thu Apr 18, 2002 11:04 pm
Location: Seattle
Contact:

Re: Deadlock, mysql 5.5 with java application

Post by Edge100x »

Squiggles wrote:Do you guys have any suggested versions that'll work best with windows server 2008 r2?
On Linux, I use the latest 5.1 release, but that's mostly because Gentoo calls it the latest stable version. On Windows, I haven't done any experimentation with MySQL.
Also, do you think backing up the data I have now will cause any issues with the new one?
If you export all your databases before the upgrade, you can always uninstall the new version and reinstall the old, if the upgrade truly goes south.
Or perhaps splitting the thread I supplied (it saves both inventoryitems and inventoryequipment at the same time)
Maybe. I'm not very familiar with MySQL usage from Java or the locking needs of your code, so it's difficult to say.
Squiggles
New to forums
New to forums
Posts: 7
Joined: Tue Jul 26, 2011 9:55 pm

Re: Deadlock, mysql 5.5 with java application

Post by Squiggles »

Splitting it wouldn't work, since the two tables share a data and they both insert it, it was executing in a weird way causing it to lag out even on my test server at home. Seeing as it normally runs perfectly fine on my test server - and two months ago I had a 2 core using the same server program with the same applications without this issue - I'm thinking that I need to do a OS wipe, and I already wiped my players just the other day. I'll lose them if I do it again, but it seems unavoidable. The older source also uses RMI, which probably is causing an issue here, this one having all remote actions removed. I've talked with my sponsor and it seems we've decided on an OS wipe and a source downgrade. Which means time to spend a few hours working! Luckily waiting for the OS to finish wiping will take up most of the time. Thank you for your help John, and if i run into any problems I'll let you know. Hopefully RMI and an OS wipe is the fix!
User avatar
Edge100x
Founder
Founder
Posts: 13121
Joined: Thu Apr 18, 2002 11:04 pm
Location: Seattle
Contact:

Re: Deadlock, mysql 5.5 with java application

Post by Edge100x »

I hope those help. If the application is multi-threaded, you might also try reducing its thread count, to reduce contention.
Post Reply