我正在运行一个用Java编写的带有MySQL数据库的MMORPG服务器。几个月它运行得很好,但随着我们越来越受欢迎,数据库越来越大,我们开始遇到问题。这些查询都在同样的线程中运行,这些线程也处理了数据包(是的,它的设计非常糟糕),这导致了很大的滞后 - 我们通过实现一个save-worker来伪造这个,它会定期保存未保存10分钟的字符5个主题。此外,其他五个线程处理需要在游戏过程中进行即时处理的数据库查询。
我们的问题是访问包含有关字符的一般信息的表的更新由于某种原因需要很长时间,然后超时。
处理列表:http://i.imgur.com/Fr0kD.png
characters
更新包含大约30个字段,以WHERE id = ?结束。
进程列表中显示的表格的布局:
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;
这是一个运行WS2008 R2,MySQL 5.5.22和Java 7的专用服务器.Java通过JDBC(MySQL连接器5.1.18)连接到数据库,并且对于这些查询,autoCommit设置为false,isloation为TRANSACTION_READ_UNCOMMITTED。服务器有32 GB RAM,其中24个用于Java,其余用于MySQL。 一些设置:
innodb_buffer_pool_size=8G
innodb_log_file_size=1024M
innodb_thread_concurrency=10
这种行为可能是什么原因?
答案 0 :(得分:0)
访问桌子时是否正确使用锁?我不知道你的访问设置,但听起来你可能会读/写饥饿。