我正在使用生产 MySQL 数据库,我想:
- 创建数据库的只读从属副本,从主数据库获取更新。主数据库是唯一可以写入的数据库。
- 对数据库的从属副本拥有“非永久写入”访问权限。所谓“非永久”,是指用户可以写入数据库并更改内容,但某个时候(比如明天),所有更改都将消失,所有内容都将与主副本完全相同。
QUESTION 1:
这可能吗?我知道 (1) 是可能的,因为这里有一些文档http://dev.mysql.com/doc/refman/5.0/en/replication.html。但我不确定我能否同时获得 (1) 和 (2)。我之所以问这个问题,是因为我需要编写访问数据库的代码,而且由于它是每个人都在使用的生产数据库,所以有时我无法使用该数据库。我想编写使用复制从属服务器(具有非永久写访问权限)的测试程序,当我确保一切正常时,我将使用主数据库运行我的程序,以便更改是永久性的。我希望我的写入显示在从属服务器上,这样我就可以确保写入了正确的东西。
QUESTION 2:
是否可以轻松地将数据库分段复制?该数据库有一个非常大的表。我认为数据库的大小约为 4GB。我只能在周末进行复制,以免打扰大家。但我担心一个周末的时间不足以复制整个数据库。那么,有没有办法分段复制呢?或者有没有一些超快的方法来复制数据库?
QUESTION 3:
设置所有东西会有多复杂?我猜想由于缺乏经验,这会花费我很长时间,但是假设我让 DBA 帮我完成这项工作,我会给他/她带来多大的麻烦?
任何帮助都将不胜感激!顺便说一句,我对 MySQL 和数据库都很陌生,所以请多多包涵 :)
答案1
我们在办公室使用类似这样的情况进行测试/备份/生产。
我们的情况是这样的:
- 生产获得所有写入
- 生产从属副本获取所有更新(用于故障转移)
- 本地从属副本获取所有更新(用于 ro/backup)
- 测试服务器每天早上都会从本地从属服务器进行覆盖。
为了便于完成最后一部分,我们首先锁定本地从属服务器(“FLUSH TABLES WITH READ LOCK;”),然后我们只需使用 Linux LVM 对本地从属副本的数据存储进行快照(这样我们就有了一个一致的磁盘快照)。然后我们使用 rsync 从本地从属服务器的快照复制到测试服务器上的 dar 目录。这样做的副作用是保留了尚未推送到生产环境的新表,这样正在进行的具有新功能的项目就不会被打乱。
这对于我们正在使用的 MyISAM 表来说工作得很好,我们还没有切换到 InnoDB。恐怕我不确定 rsync 部分是否能与 InnoDB 一起正常工作。如果您使用 InnoDB,您可能可以在测试服务器上使用 mysqldump >dumpfile.sql 和 mysql < dumpfile.sql。
答案2
问题 1:
在 Linux 上,您可以使用 LVM 可写快照来创建副本的冻结图像,然后您可以根据自己的心意进行更改,而不会影响真正的副本。
这可能是这样的:
在副本上:
stop true-replica mysql instance;
create a writeable snapshot;
start throwaway-replica mysql instance;
restart true-replica and restart replication;
然后,您可以对一次性副本执行任何您想做的事情,然后,一旦完成,停止实例并删除快照。
问题 2:我不清楚你的意思。通常,MySQL 复制会持续运行,使副本保持最新状态,而对主服务器几乎没有影响。
问题 3:MySQL 非常易于管理。LVM 可能需要一点时间来适应,并且可能需要额外的磁盘空间。
Shlomo - 你的一些术语令人困惑。对于数据库,“复制”一词往往意味着一种使数据库的远程副本保持最新的机制。这需要复制主服务器跟踪数据更改 - MySQL 使用包含已应用的任何更新、插入、删除的二进制日志来实现这一点。复制从服务器需要获取这些记录的更改,然后将其应用于自己的数据集。
初始化从属服务器可能比较棘手。您需要一个转储,其中包含主数据库在给定时刻的快照(大多数数据库转储机制都会提供)以及复制日志中记录下一次更新/删除/插入的点(同样,许多数据库转储过程可以在转储中包含此复制点)。然后,您可以使用转储恢复复制从属服务器,并将其配置为从创建转储的复制点进行复制。
创建转储文件可能会造成干扰:对于 MyISAM 表,您需要停止 MySQL 服务器并将 datadir 的内容复制到转储文件中,或者锁定要包含在转储中的所有表,然后从 datadir 或 mysqldump 复制原始表文件,并在整个过程中保持锁定。在保持锁定期间,对锁定表的更新将在转储过程中停滞 - 这可能会造成干扰。
对于 Innodb,mysqldump 可用于生成转储,而不会对常规数据库用户造成太大影响。在内部,它将生成转储数据的快照,从而即使在用户更新相同的表时也能将一致的数据集包含在转储中。这将对性能产生影响,并且还需要空间来维护快照 - 大约相当于生成转储时其他用户更改的行的大小。显然,更改越多,使用的磁盘空间就越大。转储完成后,将返回保存快照所使用的空间。
一旦构建了副本,维护对从属服务器的复制对主服务器的影响就微乎其微了 - 通常只有几个百分点。所有实际工作都是由从属服务器在通过复制日志提取更改时更新其数据集来完成的。使用内置的 MySQL 复制功能,大多数用户能够全天保持复制运行,而不会对其主数据库产生重大影响。
如果您只希望从服务器拉取更改,那么您只需在周期开始和结束时在从服务器上启动和停止复制。只要主服务器不是特别忙,从服务器通常会很快赶上当前状态。
管理开销是维护主服务器上的复制日志。磁盘上必须有足够的空间来保存至少几天的日志,最好是几周的日志。复制日志保存的时间越长,您的转储可用于初始化副本的时间就越长。如果与转储相关的复制日志已被清除,则您的转储不能用于构建副本。可以配置 MySQL 以在日志超过特定年龄阈值后将其删除,因此不需要日志轮换脚本。
正常模式是,一旦您构建了一个好的副本,就可以使用它来转储 - 从而完全避免对主服务器产生任何影响。您从中获取转储的副本应该启用“log-slave-updates” - 这样它反过来会维护直接对其进行的每个更改的复制日志(这是一个坏主意,因为这样您的副本就会偏离主服务器)以及通过复制流进行的每个更改 - 默认情况下它不会将这些更改添加到复制日志中。
我建议您试用一些测试机器并设置复制,看看会发生什么。一旦您掌握了它,就很容易快速地完成。此外,查看可用的复制过滤选项 - 如果您只想复制主数据库的子集,这些选项会很有用。这些在 MySQL 手册中: