discuz源码里边使用的都是MyISAM,流量大的时候表经常crash。然后众人都不淡定了,决定把引擎改为innoDB。
只需一行代码 alter table 表明 engine = innoDB
以为比较简单,直接上线,结果果然出了问题,需要回滚。。。
下来研究发现时innoDB的auto increment字段使用上出了问题。
原来表是这样子的
CREATE TABLE `xm_forum_post` (
`pid` bigint(20) NOT NULL,
`fid` bigint(20) NOT NULL DEFAULT '0',
`tid` bigint(20) NOT NULL DEFAULT '0',
`first` tinyint(1) NOT NULL DEFAULT '0',
`author` varchar(64) NOT NULL DEFAULT '',
`authorid` bigint(20) NOT NULL DEFAULT '0',
`subject` varchar(80) NOT NULL DEFAULT '',
`dateline` int(10) unsigned NOT NULL DEFAULT '0',
`message` mediumtext NOT NULL,
`useip` varchar(15) NOT NULL DEFAULT '',
`port` smallint(6) unsigned NOT NULL DEFAULT '0',
`invisible` tinyint(1) NOT NULL DEFAULT '0',
`anonymous` tinyint(1) NOT NULL DEFAULT '0',
`usesig` tinyint(1) NOT NULL DEFAULT '0',
`htmlon` tinyint(1) NOT NULL DEFAULT '0',
`bbcodeoff` tinyint(1) NOT NULL DEFAULT '0',
`smileyoff` tinyint(1) NOT NULL DEFAULT '0',
`parseurloff` tinyint(1) NOT NULL DEFAULT '0',
`attachment` tinyint(1) NOT NULL DEFAULT '0',
`rate` smallint(6) NOT NULL DEFAULT '0',
`ratetimes` tinyint(3) unsigned NOT NULL DEFAULT '0',
`status` int(10) NOT NULL DEFAULT '0',
`tags` varchar(255) NOT NULL DEFAULT '0',
`comment` tinyint(1) NOT NULL DEFAULT '0',
`replycredit` int(10) NOT NULL DEFAULT '0',
`position` int(8) unsigned NOT NULL AUTO_INCREMENT,
`appfrom` varchar(255) DEFAULT NULL COMMENT 'app来自机型',
PRIMARY KEY (`tid`,`position`),
UNIQUE KEY `pid` (`pid`),
KEY `fid` (`fid`),
KEY `authorid` (`authorid`,`invisible`),
KEY `dateline` (`dateline`),
KEY `invisible` (`invisible`),
KEY `displayorder` (`tid`,`invisible`,`dateline`),
KEY `first` (`tid`,`first`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
这里position自增的时候,是在tid相同条件下自增。比如首先insert tid =1,position的默认值=1;insert tid=1 ,这时position的默认值=2;然后insert tid=2, position的默认值又=1。
而innoDB的auto increment字段必须单独建索引,需要
ALTER TABLE `xm_forum_post` ADD INDEX position ( `position` );
这时候情况就变了,position独立成索引后自增不再看tid的眼色,自顾自自增了,一口大黑锅从天而降。。。