我正在運行一個用MySQL數據庫編寫的Java編寫的MMORPG服務器。幾個月後它運行得非常好,但隨着我們越來越流行,數據庫變得越來越大,我們開始出現問題。這些查詢全部運行在也處理數據包的相同線程中(是的,它的設計相當糟糕),這造成了嚴重滯後 - 我們通過實施一個保存工作人員來僞造這個問題,該工作人員定期保存未保存10分鐘的字符在5個線程中。另外,其他五個線程處理數據庫查詢,這些查詢需要在遊戲過程中進行即時處理MySQL在同一個表上超時多次更新
我們的問題是,訪問包含有關字符的常規信息的表的更新需要很長時間,出於某種原因然後超時。
PROCESSLIST:http://i.imgur.com/Fr0kD.png
的characters
更新包含大約30多個領域,並與WHERE 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;
它的運行WS2008 R2的專用服務器,MySQL 5.5.22和Java 7.爪哇通過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
該行爲的原因是什麼?
不,我們沒有在任何地方使用鎖。你能解釋一下我們如何去添加它們嗎?保存字符的方法首先更新「字符」表,然後更新所有其他表(這取決於數據庫負載需要一些時間),最後它提交數據。 – Hidden 2012-04-04 13:30:43