Java MySQL在同一个表上的多个更新超时

Java MySQL在同一个表上的多个更新超时,java,mysql,timeout,Java,Mysql,Timeout,我正在运行一个用Java编写的带有MySQL数据库的MMORPG服务器。几个月来,它运行得很好,但随着我们越来越受欢迎,数据库越来越大,我们开始遇到问题。这些查询都是在同样的线程中运行的,这些线程也处理数据包(是的,它的设计非常糟糕),这导致了严重的延迟-我们通过实现一个save-worker来伪造这一点,它在5个线程中周期性地保存10分钟内没有保存的字符。另外,还有五个线程处理在游戏过程中需要即时处理的数据库查询 我们的问题是,由于某种原因,访问包含字符一般信息的表的更新需要很长时间,然后超时

我正在运行一个用Java编写的带有MySQL数据库的MMORPG服务器。几个月来,它运行得很好,但随着我们越来越受欢迎,数据库越来越大,我们开始遇到问题。这些查询都是在同样的线程中运行的,这些线程也处理数据包(是的,它的设计非常糟糕),这导致了严重的延迟-我们通过实现一个save-worker来伪造这一点,它在5个线程中周期性地保存10分钟内没有保存的字符。另外,还有五个线程处理在游戏过程中需要即时处理的数据库查询

我们的问题是,由于某种原因,访问包含字符一般信息的表的更新需要很长时间,然后超时

进程列表:

字符
更新包含大约30多个字段,并以id=

processlist中显示的表的布局:

TABLE `characters` ( -- Contains about 300.000 rows
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `accountid` int(10) unsigned NOT NULL DEFAULT '0',
  `world` int(11) NOT NULL DEFAULT '0',
  `name` varchar(13) NOT NULL DEFAULT '',
  `level` int(11) NOT NULL DEFAULT '0',
  `exp` int(11) NOT NULL DEFAULT '0',
  `str` int(11) NOT NULL DEFAULT '0',
  `dex` int(11) NOT NULL DEFAULT '0',
  `luk` int(11) NOT NULL DEFAULT '0',
  `int` int(11) NOT NULL DEFAULT '0',
...
  `job` int(11) NOT NULL DEFAULT '0',
...
  PRIMARY KEY (`id`),
  KEY `accountid` (`accountid`),
  KEY `ranking1` (`level`,`exp`),
  KEY `ranking2` (`job`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

TABLE `items` ( -- contains 34 million rows
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `type` tinyint(3) unsigned NOT NULL,
  `inventoryType` tinyint(4) NOT NULL,
  `characterId` int(10) unsigned DEFAULT NULL,
  `accountId` int(10) unsigned DEFAULT NULL,
  `itemId` int(10) unsigned NOT NULL,
...
  PRIMARY KEY (`id`),
  KEY `FK_items_1` (`characterId`),
  KEY `FK_items_2` (`accountId`),
  CONSTRAINT `FK_items_1` FOREIGN KEY (`characterId`) REFERENCES `characters` (`id`) ON DELETE CASCADE,
  CONSTRAINT `FK_items_2` FOREIGN KEY (`accountId`) REFERENCES `accounts` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

TABLE `wishlists` ( -- contains ~75.000 rows
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `characterId` int(10) unsigned NOT NULL,
  `serialNumber` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_wishlists_1` (`characterId`),
  CONSTRAINT `FK_wishlists_1` FOREIGN KEY (`characterId`) REFERENCES `characters` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
它是一个运行WS2008R2、MySQL 5.5.22和Java 7的专用服务器。Java通过JDBC(MySQL连接器5.1.18)连接到数据库,对于这些查询,autoCommit设置为false,isloation为事务读取未提交。服务器有32GB内存,其中24个用于Java,其余用于MySQL。 一些设置:

innodb_buffer_pool_size=8G
innodb_log_file_size=1024M
innodb_thread_concurrency=10

导致这种行为的原因是什么?

访问表时是否正确使用了锁?我不知道您的访问设置,但听起来您可能正处于读/写饥饿状态。

访问表时是否正确使用了锁?我不知道您的访问设置,但听起来您可能正处于读/写饥饿状态。

不,我们没有在任何地方使用锁。你能解释一下我们将如何添加它们吗?保存字符的方法首先更新
characters
表,然后更新所有其他表(这需要一些时间,具体取决于数据库负载),最后提交数据。不,我们没有在任何地方使用锁。你能解释一下我们将如何添加它们吗?保存字符的方法首先更新
characters
表,然后更新所有其他表(这需要一些时间,具体取决于数据库负载),最后提交数据。