MySQL复制和表锁

时间:2011-06-12 18:19:04

标签: mysql replication

我有以下问题。

我有一个基于PHP和MySQL的MMORPG游戏,平均每秒约600次查询。 我碰巧遇到了锁定时间过长并且阻碍其他查询的表格的问题。 (更新查询例如需要等待Se​​lect查询)并且这些查询必须等待很长时间以便内存已满。

需要这些查询,我认为我不再对它们进行优化。

对Master-Slave使用复制是否明智?选择的主要用于写入和从属? 使用write语句(来自log-bin)的slave的性能问题是否比master高?它是否真的有助于减少表锁定问题?

先谢谢,马丁


好的,谢谢回答。 所以,如果我将InnoDB用于那些表。将它们与MyISAM混合是否明智?

因为使用InnoDB,MyISAM的70MB测试表变为200MB。我宁愿有一些桌子遇到桌面锁InnoDB和其他只是MyISAM的问题。

先谢谢,马丁。

2 个答案:

答案 0 :(得分:4)

在考虑复制和内容之前,请尝试以下方法:

我假设你的桌子正在使用MyISAM MyISAM将整个表锁定在select上,并使更新等待,直到select完成。

在考虑复制之前需要考虑一些想法

使用InnoDB
将表格切换到InnoDB InnoDB执行行锁定而不是表锁定。只有那些更新和选择的行才会被锁定。

考虑使用汇总表
如果你做了很多聚合查询,比如:

select sum(score) from score where player_id = 1

考虑制作一个memory表,如下所示:

CREATE TABLE `test`.`totals` (
  `user_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `score` INTEGER UNSIGNED NOT NULL,
  other_fields .....
  PRIMARY KEY  USING HASH(`user_id`)
)
ENGINE = MEMORY;

设置触发器after updateafter insert,如下所示:

DELIMITER $$

CREATE TRIGGER au_score_each AFTER UPDATE ON score FRO EACH ROW
BEGIN
  UPDATE totals SET score = score + (new.score - old.score) 
  WHERE totals.user_id = new.user_id;
END $$

DELIMITER ;

现在,您可以从select表中获取聚合totals查询,而无需再在完整表上删除数据库。

关于主从的一些评论
请注意,MySQL中的主从属是异步的。这意味着如果您从主站进行选择并在主站上进行更新,您的从站数据将落后 这意味着您正在处理锁定问题以解决时滞问题 在有分数的游戏中,这可能是个问题 此外,您使您的设置变得复杂。

我不是复制方面的专家所以我会停在这里,但我认为你在探索替代方案之前会跳进主从。

答案 1 :(得分:0)

从属更新是单线程的,只需重复在主服务器上执行的更新。因此,虽然您可能从单个从站获得一个小的速度提升,但您真的需要有几个从站才能显着提高SELECT速度。这会大大增加游戏的复杂性。

如果您可以升级您的服务器,那么我建议您先查看MySQL的可调参数,确保您充分利用可用内存等。